argentui 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -4
- package/dist/index.cjs +45 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -9
- package/dist/index.d.ts +33 -9
- package/dist/index.js +44 -4
- package/dist/index.js.map +1 -1
- package/dist/styles.css +7 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -56,19 +56,19 @@ A padded liquid-metal panel.
|
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
### `<MetalText>`
|
|
59
|
-
Metal type. By default
|
|
59
|
+
Metal type. By default the liquid-metal shader is poured into the glyphs — flowing bands, liquid edges, chromatic fringe. Set `variant="outline"` to run the metal around the edges of each glyph over a dark or gradient interior — the border treatment, for type. The CSS chrome gradient stands in until the shader loads (and wherever WebGL is unavailable); pass `shader={false}` to use it on its own, free at any scale.
|
|
60
60
|
|
|
61
61
|

|
|
62
62
|
|
|
63
63
|
```tsx
|
|
64
|
-
<MetalText
|
|
64
|
+
<MetalText tone="silver" fontSize={64}>Quicksilver</MetalText>
|
|
65
65
|
|
|
66
66
|
// metal edges, dark gradient interior
|
|
67
|
-
<MetalText
|
|
67
|
+
<MetalText variant="outline" fillGradient={["#23262c", "#0a0b0d"]} fontSize={64}>
|
|
68
68
|
Quicksilver
|
|
69
69
|
</MetalText>
|
|
70
70
|
|
|
71
|
-
<MetalText tone="gold" style={{ fontSize: 64 }}>Solid gold</MetalText> // CSS
|
|
71
|
+
<MetalText shader={false} tone="gold" style={{ fontSize: 64 }}>Solid gold</MetalText> // pure CSS
|
|
72
72
|
```
|
|
73
73
|
|
|
74
74
|
> Shader mode renders the glyphs into an SVG silhouette, which sees system fonts only by default. To use a webfont (e.g. Google Fonts), pass `fontCss` with an `@font-face` whose `src` is a **data: URI** — it gets embedded in the silhouette and renders correctly (the [argentui.com](https://argentui.com) text lab does exactly this). The CSS gradient stands in until the shader loads, and wherever WebGL is unavailable.
|
|
@@ -82,6 +82,32 @@ Pour the metal into any mark — pass an image with a transparent background and
|
|
|
82
82
|
<MetalLogo src="/logo.svg" tone="silver" size={170} />
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
+
### `<MetalIcon>`
|
|
86
|
+
Pour the liquid-metal shader into any SVG icon — a [lucide-react](https://lucide.dev) or [Heroicons](https://heroicons.com) element, raw SVG, or a URL. React icons are serialized from the DOM to a silhouette; each icon is one WebGL canvas, gated to the viewport like every metal surface.
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
import { MetalIcon } from "argentui";
|
|
90
|
+
import { Sparkles } from "lucide-react";
|
|
91
|
+
import { BeakerIcon } from "@heroicons/react/24/solid";
|
|
92
|
+
|
|
93
|
+
<MetalIcon icon={<Sparkles />} tone="silver" size={32} />
|
|
94
|
+
<MetalIcon icon={<BeakerIcon />} tone="gold" size={64} />
|
|
95
|
+
<MetalIcon svg="<svg>…</svg>" /> {/* or raw SVG */}
|
|
96
|
+
<MetalIcon src="/icon.svg" tone="gunmetal" /> {/* or a URL */}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Buttons take an `icon` prop too — it renders before the label in the label colour:
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
<MetalButton tone="silver" icon={<Sparkles />}>Get started</MetalButton>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
| prop | type | default |
|
|
106
|
+
|------|------|---------|
|
|
107
|
+
| `icon` / `svg` / `src` | `ReactNode` / `string` / `string` | — | the icon source (pick one) |
|
|
108
|
+
| `tone` | `MetalTone` | `"silver"` |
|
|
109
|
+
| `size` | `number` | `32` |
|
|
110
|
+
|
|
85
111
|
### `<MetalToggle>` / `<MetalProgress>` / `<MetalBadge>`
|
|
86
112
|
A mercury switch (the thumb squishes as you press it), a molten progress bar, and metal-rimmed badges.
|
|
87
113
|
|
package/dist/index.cjs
CHANGED
|
@@ -27,6 +27,7 @@ __export(index_exports, {
|
|
|
27
27
|
MetalButton: () => MetalButton,
|
|
28
28
|
MetalCard: () => MetalCard,
|
|
29
29
|
MetalFill: () => MetalFill,
|
|
30
|
+
MetalIcon: () => MetalIcon,
|
|
30
31
|
MetalLogo: () => MetalLogo,
|
|
31
32
|
MetalProgress: () => MetalProgress,
|
|
32
33
|
MetalText: () => MetalText,
|
|
@@ -498,7 +499,7 @@ var MetalCard = (0, import_react2.forwardRef)(function MetalCard2({ className, r
|
|
|
498
499
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Metal, { ref, radius, className: cx("argent-card", className), ...rest });
|
|
499
500
|
});
|
|
500
501
|
var SIZE_RADIUS = { sm: 11, md: 13, lg: 15 };
|
|
501
|
-
var MetalButton = (0, import_react2.forwardRef)(function MetalButton2({ tone = "silver", size = "md", variant = "border", radius, borderWidth = 1.5, revealOnHover = true, haptics = true, speed, engine, finish = "button", effect, angle, halo = false, type = "button", className, children, style, onPointerDown, ...rest }, ref) {
|
|
502
|
+
var MetalButton = (0, import_react2.forwardRef)(function MetalButton2({ tone = "silver", size = "md", variant = "border", radius, borderWidth = 1.5, revealOnHover = true, haptics = true, speed, engine, finish = "button", effect, angle, halo = false, icon, type = "button", className, children, style, onPointerDown, ...rest }, ref) {
|
|
502
503
|
const border = variant === "border";
|
|
503
504
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
504
505
|
"button",
|
|
@@ -517,7 +518,10 @@ var MetalButton = (0, import_react2.forwardRef)(function MetalButton2({ tone = "
|
|
|
517
518
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "argent-fill", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MetalFill, { tone, speed, engine, finish, effect, angle }) }),
|
|
518
519
|
border && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "argent-core", "aria-hidden": "true" }),
|
|
519
520
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "argent-sheen", "aria-hidden": "true" }),
|
|
520
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.
|
|
521
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "argent-content argent-btn-label", children: [
|
|
522
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "argent-btn-icon", "aria-hidden": "true", children: icon }),
|
|
523
|
+
children
|
|
524
|
+
] })
|
|
521
525
|
]
|
|
522
526
|
}
|
|
523
527
|
);
|
|
@@ -738,7 +742,7 @@ var MetalText = (0, import_react4.forwardRef)(function MetalText2({
|
|
|
738
742
|
as,
|
|
739
743
|
tone = "silver",
|
|
740
744
|
shimmer = true,
|
|
741
|
-
shader =
|
|
745
|
+
shader = true,
|
|
742
746
|
variant = "fill",
|
|
743
747
|
fill = "#101114",
|
|
744
748
|
fillGradient,
|
|
@@ -752,7 +756,7 @@ var MetalText = (0, import_react4.forwardRef)(function MetalText2({
|
|
|
752
756
|
children,
|
|
753
757
|
...rest
|
|
754
758
|
}, ref) {
|
|
755
|
-
if (shader) {
|
|
759
|
+
if (shader && typeof children === "string") {
|
|
756
760
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
757
761
|
ShaderText,
|
|
758
762
|
{
|
|
@@ -814,6 +818,42 @@ function MetalLogo({ src, tone = "silver", size = 160, width, height, speed = 1,
|
|
|
814
818
|
src
|
|
815
819
|
) });
|
|
816
820
|
}
|
|
821
|
+
|
|
822
|
+
// src/icon.tsx
|
|
823
|
+
var import_react6 = require("react");
|
|
824
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
825
|
+
function svgToUri(markup) {
|
|
826
|
+
return `data:image/svg+xml,${encodeURIComponent(markup)}`;
|
|
827
|
+
}
|
|
828
|
+
function serialize(svg) {
|
|
829
|
+
const clone = svg.cloneNode(true);
|
|
830
|
+
if (!clone.getAttribute("xmlns")) clone.setAttribute("xmlns", "http://www.w3.org/2000/svg");
|
|
831
|
+
return svgToUri(new XMLSerializer().serializeToString(clone));
|
|
832
|
+
}
|
|
833
|
+
function useIconUri({ svg, src }) {
|
|
834
|
+
const ref = (0, import_react6.useRef)(null);
|
|
835
|
+
const direct = src ?? (svg ? svgToUri(svg) : null);
|
|
836
|
+
const [uri, setUri] = (0, import_react6.useState)(direct);
|
|
837
|
+
(0, import_react6.useEffect)(() => {
|
|
838
|
+
if (direct) {
|
|
839
|
+
setUri(direct);
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
842
|
+
const node = ref.current?.querySelector("svg");
|
|
843
|
+
if (!node) return;
|
|
844
|
+
const next = serialize(node);
|
|
845
|
+
setUri((prev) => prev === next ? prev : next);
|
|
846
|
+
});
|
|
847
|
+
return { ref, uri, fromNode: !direct };
|
|
848
|
+
}
|
|
849
|
+
function MetalIcon({ icon, svg, src, tone = "silver", size = 32, speed = 1, className, style, ...rest }) {
|
|
850
|
+
const { ref, uri, fromNode } = useIconUri({ svg, src });
|
|
851
|
+
const cls = ["argent-icon-wrap", className].filter(Boolean).join(" ");
|
|
852
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: cls, style: { display: "inline-flex", width: size, height: size, ...style }, ...rest, children: [
|
|
853
|
+
fromNode && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { ref, "aria-hidden": "true", style: { position: "absolute", width: 0, height: 0, overflow: "hidden", color: "#000" }, children: icon }),
|
|
854
|
+
uri && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MetalLogo, { src: uri, tone, size, speed })
|
|
855
|
+
] });
|
|
856
|
+
}
|
|
817
857
|
// Annotate the CommonJS export names for ESM import in node:
|
|
818
858
|
0 && (module.exports = {
|
|
819
859
|
EFFECTS,
|
|
@@ -823,6 +863,7 @@ function MetalLogo({ src, tone = "silver", size = 160, width, height, speed = 1,
|
|
|
823
863
|
MetalButton,
|
|
824
864
|
MetalCard,
|
|
825
865
|
MetalFill,
|
|
866
|
+
MetalIcon,
|
|
826
867
|
MetalLogo,
|
|
827
868
|
MetalProgress,
|
|
828
869
|
MetalText,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/surfaces.tsx","../src/metal.tsx","../src/engine.ts","../src/haptics.ts","../src/controls.tsx","../src/text.tsx","../src/logo.tsx"],"sourcesContent":["export { Metal, MetalCard, MetalButton } from \"./surfaces\";\nexport type { MetalProps, MetalCardProps, MetalButtonProps, MetalVariant, MetalFrame } from \"./surfaces\";\nexport { MetalToggle, MetalProgress, MetalBadge } from \"./controls\";\nexport type { MetalToggleProps, MetalProgressProps, MetalBadgeProps } from \"./controls\";\nexport { MetalText } from \"./text\";\nexport type { MetalTextProps, MetalTextVariant } from \"./text\";\nexport { MetalLogo } from \"./logo\";\nexport type { MetalLogoProps } from \"./logo\";\nexport { MetalFill, TONE_PARAMS, FINISHES, EFFECTS, useMounted, useInView, useReducedMotion } from \"./metal\";\nexport type { MetalTone, MetalFillProps, MetalFinish, MetalEffect } from \"./metal\";\nexport { mountMetal, NATIVE_TONES } from \"./engine\";\nexport type { MetalEngine, NativeMetalParams, MetalMount } from \"./engine\";\nexport { setHaptics } from \"./haptics\";\n","import { forwardRef } from \"react\";\nimport { MetalFill, type MetalEffect, type MetalFinish, type MetalTone } from \"./metal\";\nimport type { MetalEngine } from \"./engine\";\nimport { PRESS_PATTERN, vibrate } from \"./haptics\";\n\nfunction cx(...parts: (string | false | undefined | null)[]): string {\n return parts.filter(Boolean).join(\" \");\n}\n\nfunction assignRef<T>(ref: React.ForwardedRef<T>, node: T | null) {\n if (typeof ref === \"function\") ref(node);\n else if (ref) ref.current = node;\n}\n\n/** Where the liquid metal shows: just the edge, or the whole surface. */\nexport type MetalVariant = \"border\" | \"fill\";\n\n/** Border framing: a single rim, or a rim plus an inner hairline frame. */\nexport type MetalFrame = \"single\" | \"double\";\n\ntype StyleVars = React.CSSProperties & Record<`--${string}`, string>;\n\nexport interface MetalProps extends React.HTMLAttributes<HTMLElement> {\n /** Element/component to render. Defaults to `div`. */\n as?: React.ElementType;\n /** Metal finish. */\n tone?: MetalTone;\n /** `\"border\"` (metal edge only, default) or `\"fill\"` (metal fills the surface). */\n variant?: MetalVariant;\n /** `\"single\"` rim (default) or `\"double\"` — rim plus an inner hairline frame. */\n frame?: MetalFrame;\n /** Let the metal show faintly through the interior panel (border variant). */\n tint?: boolean;\n /** Border thickness in px (border variant). */\n borderWidth?: number;\n /** Fill the whole surface with metal on hover (border variant). */\n revealOnHover?: boolean;\n /** Corner radius in px. */\n radius?: number;\n /** Shader animation speed (0 pauses the metal). */\n speed?: number;\n /** Pattern scale — higher spreads the reflection bands out. */\n metalScale?: number;\n /** Shader engine: Paper's LiquidMetal (default) or Argent's own. */\n engine?: MetalEngine;\n /** Shape-tuned shader preset. Defaults to `\"surface\"`. */\n finish?: MetalFinish;\n /** Motion character: flow, molten, ripple, chrome, or wave. */\n effect?: MetalEffect;\n /** Band direction in degrees — overrides the tone/finish default. */\n angle?: number;\n /** A specular streak that sweeps across on hover. */\n sheen?: boolean;\n /**\n * A frosted standoff ring outside the metal — a few px of backdrop blur\n * finished with a ~5% hairline. `true` for 8px, or a number for the ring\n * width. Theme the line with `--argent-halo-line`.\n */\n halo?: boolean | number;\n}\n\nfunction buildVars(radius: number, borderWidth: number, halo: boolean | number, style?: React.CSSProperties): StyleVars {\n const vars: StyleVars = {\n borderRadius: radius,\n \"--argent-bw\": `${borderWidth}px`,\n \"--argent-radius\": `${radius}px`,\n ...style,\n } as StyleVars;\n if (halo) vars[\"--argent-halo\"] = `${halo === true ? 8 : halo}px`;\n return vars;\n}\n\n/**\n * A liquid-metal surface powered by Paper's `LiquidMetal` shader. By default the\n * metal is just the edge; pass `variant=\"fill\"` for a full metal surface, or\n * `revealOnHover` to fill in on interaction. The base for every Argent component.\n */\nexport const Metal = forwardRef<HTMLElement, MetalProps>(function Metal(\n {\n as,\n tone = \"silver\",\n variant = \"border\",\n frame = \"single\",\n tint = false,\n borderWidth = 1.5,\n revealOnHover = false,\n radius = 14,\n speed,\n metalScale,\n engine,\n finish,\n effect,\n angle,\n sheen = false,\n halo = false,\n className,\n style,\n children,\n ...rest\n },\n ref,\n) {\n const Tag = (as ?? \"div\") as React.ElementType;\n const border = variant === \"border\";\n return (\n <Tag\n ref={(node: HTMLElement | null) => assignRef(ref, node)}\n className={cx(\n \"argent\",\n border ? \"argent--border\" : \"argent--fill\",\n border && frame === \"double\" && \"argent--double\",\n border && tint && \"argent--tint\",\n revealOnHover && \"argent--reveal\",\n sheen && \"argent--sheen\",\n !!halo && \"argent--halo\",\n className,\n )}\n data-tone={tone}\n style={buildVars(radius, borderWidth, halo, style)}\n {...rest}\n >\n <span className=\"argent-fill\" aria-hidden=\"true\">\n <MetalFill tone={tone} speed={speed} scale={metalScale} engine={engine} finish={finish} effect={effect} angle={angle} />\n </span>\n {border && <span className=\"argent-core\" aria-hidden=\"true\" />}\n {sheen && <span className=\"argent-sheen\" aria-hidden=\"true\" />}\n <span className=\"argent-content\">{children}</span>\n </Tag>\n );\n});\n\nexport interface MetalCardProps extends MetalProps {}\n\n/** A padded liquid-metal container. Metal edge by default. */\nexport const MetalCard = forwardRef<HTMLElement, MetalCardProps>(function MetalCard(\n { className, radius = 18, ...rest },\n ref,\n) {\n return <Metal ref={ref} radius={radius} className={cx(\"argent-card\", className)} {...rest} />;\n});\n\nexport interface MetalButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n tone?: MetalTone;\n size?: \"sm\" | \"md\" | \"lg\";\n /** `\"border\"` (default — readable, fills on hover) or `\"fill\"` (full chrome). */\n variant?: MetalVariant;\n /** Corner radius in px. */\n radius?: number;\n borderWidth?: number;\n /** Fill with metal on hover (border variant). Defaults to `true`. */\n revealOnHover?: boolean;\n /** Vibrate on press where supported. Defaults to `true`. */\n haptics?: boolean;\n speed?: number;\n engine?: MetalEngine;\n finish?: MetalFinish;\n effect?: MetalEffect;\n angle?: number;\n halo?: boolean | number;\n}\n\nconst SIZE_RADIUS = { sm: 11, md: 13, lg: 15 } as const;\n\n/** A liquid-metal button — readable at rest, molten on hover, with a stamped press. */\nexport const MetalButton = forwardRef<HTMLButtonElement, MetalButtonProps>(function MetalButton(\n { tone = \"silver\", size = \"md\", variant = \"border\", radius, borderWidth = 1.5, revealOnHover = true, haptics = true, speed, engine, finish = \"button\", effect, angle, halo = false, type = \"button\", className, children, style, onPointerDown, ...rest },\n ref,\n) {\n const border = variant === \"border\";\n return (\n <button\n ref={ref}\n type={type}\n onPointerDown={(e) => {\n if (haptics) vibrate(PRESS_PATTERN);\n onPointerDown?.(e);\n }}\n className={cx(\"argent\", border ? \"argent--border\" : \"argent--fill\", border && revealOnHover && \"argent--reveal\", \"argent--sheen\", !!halo && \"argent--halo\", \"argent-btn\", `argent-btn--${size}`, className)}\n data-tone={tone}\n style={buildVars(radius ?? SIZE_RADIUS[size], borderWidth, halo, style)}\n {...rest}\n >\n <span className=\"argent-fill\" aria-hidden=\"true\">\n <MetalFill tone={tone} speed={speed} engine={engine} finish={finish} effect={effect} angle={angle} />\n </span>\n {border && <span className=\"argent-core\" aria-hidden=\"true\" />}\n <span className=\"argent-sheen\" aria-hidden=\"true\" />\n <span className=\"argent-content argent-btn-label\">{children}</span>\n </button>\n );\n});\n","import { useEffect, useRef, useState } from \"react\";\nimport { LiquidMetal, type LiquidMetalParams } from \"@paper-design/shaders-react\";\nimport { mountMetal, NATIVE_TONES, type MetalEngine, type MetalMount, type NativeMetalParams } from \"./engine\";\n\n/**\n * The liquid-metal surface is Paper's `LiquidMetal` WebGL shader\n * (@paper-design/shaders) run with `shape=\"none\"` so it fills the whole element\n * instead of painting a blob. Each tone is a tuned set of shader params; the\n * canvas sits behind the content and is clipped to the surface's radius.\n *\n * `@paper-design/shaders-react` is a peer dependency — install it alongside\n * `argentui`. It is licensed under PolyForm Shield by Paper.\n */\n\nexport type MetalTone = \"silver\" | \"gold\" | \"gunmetal\" | \"obsidian\";\n\ntype Tuned = Pick<\n LiquidMetalParams,\n \"colorBack\" | \"colorTint\" | \"repetition\" | \"softness\" | \"shiftRed\" | \"shiftBlue\" | \"distortion\" | \"contour\" | \"angle\"\n>;\n\nexport const TONE_PARAMS: Record<MetalTone, Tuned> = {\n silver: {\n colorBack: \"#a7abb1\", colorTint: \"#ffffff\",\n repetition: 3, softness: 0.18, shiftRed: 0.32, shiftBlue: 0.32, distortion: 0.14, contour: 0.55, angle: 68,\n },\n gold: {\n colorBack: \"#94700e\", colorTint: \"#ffedb0\",\n repetition: 3, softness: 0.2, shiftRed: 0.3, shiftBlue: 0.12, distortion: 0.13, contour: 0.5, angle: 68,\n },\n gunmetal: {\n colorBack: \"#33373d\", colorTint: \"#b2bac4\",\n repetition: 2.6, softness: 0.26, shiftRed: 0.22, shiftBlue: 0.32, distortion: 0.1, contour: 0.45, angle: 80,\n },\n obsidian: {\n colorBack: \"#000000\", colorTint: \"#9498a6\",\n repetition: 2, softness: 0.4, shiftRed: 0.14, shiftBlue: 0.24, distortion: 0.07, contour: 0.32, angle: 92,\n },\n};\n\n// Paper's image pre-processing misbehaves when several image-mask shaders\n// initialise at once (only one survives) — serialise mounts a beat apart.\nlet imageMountQueue: Promise<void> = Promise.resolve();\nexport function useStaggeredMount(): boolean {\n const [go, setGo] = useState(false);\n useEffect(() => {\n let alive = true;\n imageMountQueue = imageMountQueue.then(async () => {\n if (!alive) return; // unmounted while queued — release the queue instantly\n setGo(true);\n await new Promise((r) => setTimeout(r, 300));\n });\n return () => {\n alive = false;\n };\n }, []);\n return go;\n}\n\n/** True once mounted on the client — the WebGL canvas can't render during SSR. */\nexport function useMounted(): boolean {\n const [m, setM] = useState(false);\n useEffect(() => setM(true), []);\n return m;\n}\n\n/** True when the user prefers reduced motion — the metal freezes (speed 0). */\nexport function useReducedMotion(): boolean {\n const [reduced, setReduced] = useState(false);\n useEffect(() => {\n const mq = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n setReduced(mq.matches);\n const onChange = (e: MediaQueryListEvent) => setReduced(e.matches);\n mq.addEventListener(\"change\", onChange);\n return () => mq.removeEventListener(\"change\", onChange);\n }, []);\n return reduced;\n}\n\n/**\n * Reports whether `ref` is on/near screen. Each metal surface is a WebGL\n * canvas, and browsers cap concurrent contexts (~16) — so we only mount the\n * shader while it's visible and release the context when it scrolls away.\n */\nexport function useInView(ref: React.RefObject<Element | null>, margin = \"250px\"): boolean {\n const [inView, setInView] = useState(false);\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n const io = new IntersectionObserver(([entry]) => setInView(entry.isIntersecting), { rootMargin: margin });\n io.observe(el);\n return () => io.disconnect();\n }, [ref, margin]);\n return inView;\n}\n\n/**\n * Finishes — shader presets tuned to the shape and size of the element. One\n * pattern does not fit all: a card wants broad flowing bands, a thin progress\n * bar wants many stripes crossing it, a 22px toggle thumb wants one soft\n * highlight like a ball bearing, and a hairline badge rim wants dense bands so\n * a tiny visible slice always catches some light.\n */\nexport type MetalFinish = \"surface\" | \"button\" | \"bar\" | \"orb\" | \"rim\";\n\ninterface FinishTuning {\n /** Band direction override (deg). */\n angle?: number;\n /** Random per-mount angle variation (±deg) so identical elements don't look cloned. */\n angleJitter?: number;\n repetition?: number;\n softness?: number;\n distortion?: number;\n /** Multiplier on the tone's chromatic shift. */\n shift?: number;\n /** Default pattern scale. */\n scale?: number;\n /** Multiplier on the animation speed. */\n speed?: number;\n}\n\nexport const FINISHES: Record<MetalFinish, FinishTuning> = {\n /** Cards, nav, panels — broad flowing reflection bands (the tone defaults). */\n surface: { scale: 1.1 },\n /** Buttons — slightly spread, calmer warp so labels stay readable. */\n button: { scale: 1.4, distortion: 0.1 },\n /** Thin horizontal strips (progress) — near-vertical stripes crossing the bar. */\n bar: { angle: 14, repetition: 5, softness: 0.3, distortion: 0.06, shift: 0.5, scale: 0.8, speed: 0.75 },\n /** Small round things (toggle thumbs) — one soft highlight, like a polished sphere. */\n orb: { angle: 112, angleJitter: 20, repetition: 1.7, softness: 0.5, distortion: 0.05, shift: 0.4, scale: 1.5 },\n /** Hairline edges (badges, thin borders) — dense bands so any slice sparkles. */\n rim: { angle: 40, repetition: 4.5, softness: 0.3, distortion: 0.08, shift: 0.5, scale: 0.85, speed: 0.85 },\n};\n\n/**\n * Effects — the character of the liquid's motion, independent of tone and\n * finish: how soft the bands are, how hard the noise churns them, how fast\n * everything moves.\n */\nexport type MetalEffect = \"flow\" | \"molten\" | \"ripple\" | \"chrome\" | \"wave\";\n\ninterface EffectTuning {\n angle?: number;\n repetition?: number;\n softness?: number;\n distortion?: number;\n /** Multiplier on chromatic shift. */\n shift?: number;\n /** Multiplier on animation speed. */\n speed?: number;\n}\n\nexport const EFFECTS: Record<MetalEffect, EffectTuning> = {\n /** The default — steady flowing reflection bands. */\n flow: {},\n /** Slow, heavy, half-melted — soft wide bands churning lazily. */\n molten: { softness: 0.5, distortion: 0.3, speed: 0.45, shift: 0.6 },\n /** Agitated surface — tighter bands, hard noise, quick motion. */\n ripple: { repetition: 4, softness: 0.24, distortion: 0.5, speed: 1.4 },\n /** Mirror-polished — crisp hard bands, strong chromatic fringe, calm. */\n chrome: { softness: 0.05, distortion: 0.05, shift: 1.6, speed: 0.8 },\n /** Horizontal swells rolling through the surface. */\n wave: { angle: 0, repetition: 5, softness: 0.36, distortion: 0.18, speed: 0.7 },\n};\n\nexport interface MetalFillProps {\n tone: MetalTone;\n /** Shader animation speed (0 pauses). */\n speed?: number;\n /** Pattern scale — higher spreads the bands out. Defaults per finish. */\n scale?: number;\n /** `\"paper\"` (Paper's LiquidMetal, default) or `\"native\"` (Argent's own shader). */\n engine?: MetalEngine;\n /** Shape-tuned shader preset. Defaults to `\"surface\"`. */\n finish?: MetalFinish;\n /** Motion character preset. Defaults to `\"flow\"`. */\n effect?: MetalEffect;\n /** Band direction in degrees — overrides the tone/finish default. */\n angle?: number;\n}\n\nconst FILL_STYLE: React.CSSProperties = { position: \"absolute\", inset: 0, width: \"100%\", height: \"100%\" };\n\n/** Argent's own clean-room shader on a plain canvas. */\nfunction NativeCanvas({ params }: { params: NativeMetalParams }) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const mountRef = useRef<MetalMount | null>(null);\n const initial = useRef(params);\n initial.current = params;\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n mountRef.current = mountMetal(canvas, initial.current);\n return () => {\n mountRef.current?.destroy();\n mountRef.current = null;\n };\n }, []);\n useEffect(() => {\n mountRef.current?.update(params);\n }, [params]);\n return <canvas ref={canvasRef} style={{ ...FILL_STYLE, display: \"block\" }} />;\n}\n\n/** The shader canvas, absolutely filling its positioned parent (when in view). */\nexport function MetalFill({ tone, speed = 1, scale, engine = \"paper\", finish = \"surface\", effect = \"flow\", angle }: MetalFillProps) {\n const ref = useRef<HTMLSpanElement>(null);\n const mounted = useMounted();\n const inView = useInView(ref);\n const reduced = useReducedMotion();\n const f = FINISHES[finish];\n const e = EFFECTS[effect];\n const [jitter] = useState(() => (f.angleJitter ? (Math.random() * 2 - 1) * f.angleJitter : 0));\n\n const base = TONE_PARAMS[tone];\n // precedence: explicit prop > effect > finish > tone\n const effAngle = (angle ?? e.angle ?? f.angle ?? base.angle ?? 70) + jitter;\n const effScale = scale ?? f.scale ?? 1.1;\n const effSpeed = (reduced ? 0 : speed) * (f.speed ?? 1) * (e.speed ?? 1);\n const shift = (f.shift ?? 1) * (e.shift ?? 1);\n const repetition = e.repetition ?? f.repetition ?? base.repetition;\n const softness = e.softness ?? f.softness ?? base.softness;\n const distortion = e.distortion ?? f.distortion ?? base.distortion;\n\n const native = NATIVE_TONES[tone];\n const nativeParams: NativeMetalParams = {\n ...native,\n angle: effAngle,\n repetition: repetition ?? native.repetition,\n softness: softness ?? native.softness,\n // the native warp amount runs ~3× paper's distortion scale\n distortion: distortion !== undefined ? distortion * 3 : native.distortion,\n dispersion: native.dispersion * shift,\n speed: effSpeed,\n scale: effScale,\n };\n\n return (\n <span ref={ref} aria-hidden=\"true\" style={{ position: \"absolute\", inset: 0 }}>\n {mounted && inView && (\n engine === \"native\" ? (\n <NativeCanvas params={nativeParams} />\n ) : (\n <LiquidMetal\n shape=\"none\"\n fit=\"cover\"\n scale={effScale}\n speed={effSpeed}\n {...base}\n angle={effAngle}\n repetition={repetition}\n softness={softness}\n distortion={distortion}\n shiftRed={(base.shiftRed ?? 0.3) * shift}\n shiftBlue={(base.shiftBlue ?? 0.3) * shift}\n style={FILL_STYLE}\n />\n )\n )}\n </span>\n );\n}\n","/**\n * Argent's own liquid-metal shader — a clean-room WebGL2 implementation of the\n * classic recipe: hard light→dark reflection banding, curvature-warped UVs,\n * time-driven simplex-noise flow, per-channel chromatic dispersion, and a rim\n * lift. No third-party shader code beyond the public-domain-style simplex\n * noise (Ashima Arts / Stefan Gustavson, MIT).\n *\n * Used when a surface sets `engine=\"native\"`; removes the need for\n * @paper-design/shaders-react entirely.\n */\n\nexport interface NativeMetalParams {\n /** Highlight band colour (hex). */\n light: string;\n /** Shadow band colour (hex). */\n dark: string;\n /** Stripe density. */\n repetition: number;\n /** Band direction in degrees. */\n angle: number;\n /** Band edge softness 0–1. */\n softness: number;\n /** Per-channel band offset (chromatic dispersion). */\n dispersion: number;\n /** Noise warp amount. */\n distortion: number;\n /** Animation speed (0 = still). */\n speed: number;\n /** Pattern scale — higher spreads the bands out. */\n scale: number;\n}\n\nexport type MetalEngine = \"paper\" | \"native\";\n\nconst VERT = `#version 300 es\nvoid main() {\n vec2 pos = vec2(float((gl_VertexID << 1) & 2), float(gl_VertexID & 2));\n gl_Position = vec4(pos * 2.0 - 1.0, 0.0, 1.0);\n}`;\n\nconst FRAG = `#version 300 es\nprecision highp float;\nuniform vec2 u_res;\nuniform float u_time;\nuniform vec3 u_light;\nuniform vec3 u_dark;\nuniform float u_rep;\nuniform float u_angle;\nuniform float u_soft;\nuniform float u_disp;\nuniform float u_dist;\nuniform float u_scale;\nout vec4 outColor;\n\n// 2D simplex noise — Ashima Arts / Stefan Gustavson (webgl-noise, MIT).\nvec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\nvec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\nvec3 permute(vec3 x) { return mod289(((x * 34.0) + 1.0) * x); }\nfloat snoise(vec2 v) {\n const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439);\n vec2 i = floor(v + dot(v, C.yy));\n vec2 x0 = v - i + dot(i, C.xx);\n vec2 i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n i = mod289(i);\n vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0)) + i.x + vec3(0.0, i1.x, 1.0));\n vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);\n m = m * m;\n m = m * m;\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n\n// One reflection band: a soft triangle wave over the warped coordinate.\nfloat stripe(float coord) {\n float f = fract(coord);\n float tri = abs(f * 2.0 - 1.0);\n return smoothstep(0.5 - u_soft, 0.5 + u_soft, tri);\n}\n\nvoid main() {\n vec2 uv = (gl_FragCoord.xy / u_res - 0.5);\n uv.x *= u_res.x / u_res.y;\n uv /= max(u_scale, 0.001);\n\n float t = u_time;\n\n // curvature: bands bend as if wrapping a bulged surface\n float d = length(uv);\n float bulge = 1.0 - 0.45 * d * d;\n\n // flowing warp — two noise octaves drifting at different rates\n float n = snoise(uv * 0.9 + vec2(0.0, -t * 0.28));\n n += 0.35 * snoise(uv * 1.8 + vec2(t * 0.1, -t * 0.45));\n\n // rotate so bands run along u_angle\n float c = cos(u_angle), s = sin(u_angle);\n vec2 ruv = mat2(c, -s, s, c) * uv;\n\n float coord = ruv.y * bulge * u_rep + n * u_dist * 2.2 - t * 0.22;\n\n // per-channel dispersion — the chrome fringing\n float r = stripe(coord + u_disp);\n float g = stripe(coord);\n float b = stripe(coord - u_disp);\n\n vec3 col = vec3(\n mix(u_dark.r, u_light.r, r),\n mix(u_dark.g, u_light.g, g),\n mix(u_dark.b, u_light.b, b)\n );\n\n // rim lift toward the edges\n col *= 0.94 + 0.14 * smoothstep(0.25, 0.85, d);\n\n outColor = vec4(col, 1.0);\n}`;\n\nfunction hexToRgb(hex: string): [number, number, number] {\n const h = hex.replace(\"#\", \"\");\n const v = h.length === 3 ? h.split(\"\").map((ch) => ch + ch).join(\"\") : h;\n const n = parseInt(v, 16);\n return [((n >> 16) & 255) / 255, ((n >> 8) & 255) / 255, (n & 255) / 255];\n}\n\nexport const NATIVE_TONES: Record<string, Omit<NativeMetalParams, \"speed\" | \"scale\">> = {\n silver: { light: \"#f8fafc\", dark: \"#23262b\", repetition: 1.8, angle: 68, softness: 0.34, dispersion: 0.03, distortion: 0.38 },\n gold: { light: \"#ffe9a8\", dark: \"#6e5408\", repetition: 1.8, angle: 68, softness: 0.34, dispersion: 0.028, distortion: 0.36 },\n gunmetal: { light: \"#b6bec9\", dark: \"#14161a\", repetition: 1.6, angle: 80, softness: 0.36, dispersion: 0.025, distortion: 0.34 },\n obsidian: { light: \"#787c88\", dark: \"#000000\", repetition: 1.4, angle: 92, softness: 0.42, dispersion: 0.02, distortion: 0.28 },\n};\n\nexport interface MetalMount {\n update(params: Partial<NativeMetalParams>): void;\n destroy(): void;\n}\n\nfunction compile(gl: WebGL2RenderingContext, type: number, src: string): WebGLShader | null {\n const sh = gl.createShader(type);\n if (!sh) return null;\n gl.shaderSource(sh, src);\n gl.compileShader(sh);\n if (!gl.getShaderParameter(sh, gl.COMPILE_STATUS)) {\n console.error(\"argent shader:\", gl.getShaderInfoLog(sh));\n gl.deleteShader(sh);\n return null;\n }\n return sh;\n}\n\n/** Mount the native liquid-metal shader on a canvas. Returns null without WebGL2. */\nexport function mountMetal(canvas: HTMLCanvasElement, params: NativeMetalParams): MetalMount | null {\n const gl = canvas.getContext(\"webgl2\", { antialias: true });\n if (!gl) return null;\n\n const vs = compile(gl, gl.VERTEX_SHADER, VERT);\n const fs = compile(gl, gl.FRAGMENT_SHADER, FRAG);\n if (!vs || !fs) return null;\n const prog = gl.createProgram()!;\n gl.attachShader(prog, vs);\n gl.attachShader(prog, fs);\n gl.linkProgram(prog);\n if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {\n console.error(\"argent shader link:\", gl.getProgramInfoLog(prog));\n return null;\n }\n gl.useProgram(prog);\n\n const U = (name: string) => gl.getUniformLocation(prog, name);\n const uRes = U(\"u_res\"), uTime = U(\"u_time\"), uLight = U(\"u_light\"), uDark = U(\"u_dark\");\n const uRep = U(\"u_rep\"), uAngle = U(\"u_angle\"), uSoft = U(\"u_soft\");\n const uDisp = U(\"u_disp\"), uDist = U(\"u_dist\"), uScale = U(\"u_scale\");\n\n let p = { ...params };\n let raf = 0;\n let tAcc = Math.random() * 40; // desync multiple surfaces\n let last = performance.now();\n let dead = false;\n\n function draw() {\n raf = 0;\n if (dead) return;\n const dpr = Math.min(window.devicePixelRatio || 1, 2);\n const w = Math.max(1, Math.round(canvas.clientWidth * dpr));\n const h = Math.max(1, Math.round(canvas.clientHeight * dpr));\n if (canvas.width !== w || canvas.height !== h) {\n canvas.width = w;\n canvas.height = h;\n gl!.viewport(0, 0, w, h);\n }\n const now = performance.now();\n tAcc += ((now - last) / 1000) * p.speed;\n last = now;\n\n gl!.uniform2f(uRes, w, h);\n gl!.uniform1f(uTime, tAcc);\n gl!.uniform3fv(uLight, hexToRgb(p.light));\n gl!.uniform3fv(uDark, hexToRgb(p.dark));\n gl!.uniform1f(uRep, p.repetition);\n gl!.uniform1f(uAngle, (p.angle * Math.PI) / 180);\n gl!.uniform1f(uSoft, Math.max(0.02, p.softness));\n gl!.uniform1f(uDisp, p.dispersion);\n gl!.uniform1f(uDist, p.distortion);\n gl!.uniform1f(uScale, p.scale);\n gl!.drawArrays(gl!.TRIANGLES, 0, 3);\n\n if (p.speed > 0) raf = requestAnimationFrame(draw);\n }\n draw();\n\n return {\n update(np) {\n p = { ...p, ...np };\n last = performance.now();\n if (!raf) raf = requestAnimationFrame(draw);\n },\n destroy() {\n dead = true;\n if (raf) cancelAnimationFrame(raf);\n gl.getExtension(\"WEBGL_lose_context\")?.loseContext();\n },\n };\n}\n","/**\n * Tiny haptics for metal presses — `navigator.vibrate` where available\n * (Android Chrome; iOS Safari ignores it). On by default, like Glacé.\n */\n\nlet enabled = true;\n\n/** Globally enable/disable Argent haptics. */\nexport function setHaptics(on: boolean) {\n enabled = on;\n}\n\nexport function vibrate(pattern: number | number[]) {\n if (!enabled || typeof navigator === \"undefined\" || !(\"vibrate\" in navigator)) return;\n try {\n navigator.vibrate(pattern);\n } catch {\n // some browsers throw on vibrate without user activation — fine to ignore\n }\n}\n\n/** The stamped-press click. */\nexport const PRESS_PATTERN = 8;\n","import { forwardRef, useState } from \"react\";\nimport { MetalFill, type MetalTone } from \"./metal\";\nimport { Metal, type MetalProps } from \"./surfaces\";\nimport { PRESS_PATTERN, vibrate } from \"./haptics\";\n\nexport interface MetalToggleProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"onChange\"> {\n tone?: MetalTone;\n checked?: boolean;\n defaultChecked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n /** Vibrate on toggle where supported. Defaults to `true`. */\n haptics?: boolean;\n}\n\n/**\n * A mercury switch — the thumb is a drop of liquid metal that slides (and\n * squishes) across a dark channel.\n */\nexport const MetalToggle = forwardRef<HTMLButtonElement, MetalToggleProps>(function MetalToggle(\n { tone = \"silver\", checked, defaultChecked = false, onCheckedChange, haptics = true, className, onClick, ...rest },\n ref,\n) {\n const [internal, setInternal] = useState(defaultChecked);\n const isOn = checked ?? internal;\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"switch\"\n aria-checked={isOn}\n data-tone={tone}\n data-checked={isOn || undefined}\n className={[\"argent-toggle\", className].filter(Boolean).join(\" \")}\n onClick={(e) => {\n if (haptics) vibrate(PRESS_PATTERN);\n if (checked === undefined) setInternal(!isOn);\n onCheckedChange?.(!isOn);\n onClick?.(e);\n }}\n {...rest}\n >\n <span className=\"argent-toggle-thumb\" aria-hidden=\"true\">\n <MetalFill tone={tone} finish=\"orb\" />\n </span>\n </button>\n );\n});\n\nexport interface MetalProgressProps extends React.HTMLAttributes<HTMLDivElement> {\n tone?: MetalTone;\n /** 0–100. Omit for an indeterminate molten sweep. */\n value?: number;\n /** Track height in px. */\n height?: number;\n}\n\n/** A molten progress bar — liquid metal rising in a dark channel. */\nexport const MetalProgress = forwardRef<HTMLDivElement, MetalProgressProps>(function MetalProgress(\n { tone = \"silver\", value, height = 10, className, style, ...rest },\n ref,\n) {\n const indeterminate = value === undefined;\n const clamped = indeterminate ? 0 : Math.max(0, Math.min(100, value));\n return (\n <div\n ref={ref}\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={indeterminate ? undefined : clamped}\n data-tone={tone}\n className={[\"argent-progress\", indeterminate && \"argent-progress--indeterminate\", className].filter(Boolean).join(\" \")}\n style={{ height, ...style }}\n {...rest}\n >\n <span\n className=\"argent-progress-fill\"\n style={indeterminate ? undefined : { width: `${clamped}%` }}\n aria-hidden=\"true\"\n >\n <MetalFill tone={tone} finish=\"bar\" />\n </span>\n </div>\n );\n});\n\nexport interface MetalBadgeProps extends Omit<MetalProps, \"as\" | \"variant\"> {}\n\n/** A small liquid-metal pill — a metal rim around a quiet label. */\nexport const MetalBadge = forwardRef<HTMLElement, MetalBadgeProps>(function MetalBadge(\n { className, radius = 999, borderWidth = 1, finish = \"rim\", ...rest },\n ref,\n) {\n return (\n <Metal\n ref={ref}\n as=\"span\"\n variant=\"border\"\n radius={radius}\n borderWidth={borderWidth}\n finish={finish}\n className={[\"argent-badge\", className].filter(Boolean).join(\" \")}\n {...rest}\n />\n );\n});\n","import { forwardRef, useEffect, useRef, useState } from \"react\";\nimport { LiquidMetal } from \"@paper-design/shaders-react\";\nimport { TONE_PARAMS, useInView, useMounted, useReducedMotion, useStaggeredMount, type MetalTone } from \"./metal\";\n\n/** Where the metal lives in shader text: the whole glyph, or just its edge. */\nexport type MetalTextVariant = \"fill\" | \"outline\";\n\nexport interface MetalTextProps extends React.HTMLAttributes<HTMLElement> {\n /** Element to render. Defaults to `span`. */\n as?: React.ElementType;\n tone?: MetalTone;\n /** Animate the highlight band across the glyphs (CSS mode). Defaults to `true`. */\n shimmer?: boolean;\n /**\n * Pour the real liquid-metal shader into the glyphs — flowing bands, liquid\n * edges, chromatic fringe. Costs a WebGL canvas; the CSS gradient renders as\n * a placeholder until the shader is ready, and stands in wherever WebGL\n * isn't. Children must be a plain string in this mode.\n */\n shader?: boolean;\n /**\n * Shader mode: `\"fill\"` (metal fills the glyphs, default) or `\"outline\"` —\n * the metal runs around the edge of each letterform and the interior takes\n * `fill` / `fillGradient`.\n */\n variant?: MetalTextVariant;\n /** Interior colour for `variant=\"outline\"`. */\n fill?: string;\n /** Interior vertical gradient `[top, bottom]` for `variant=\"outline\"` — wins over `fill`. */\n fillGradient?: [string, string];\n /** Metal edge thickness in px for `variant=\"outline\"`. Defaults to ~5% of the font size. */\n outlineWidth?: number;\n /** Type size in px (shader mode). Defaults to `64`. */\n fontSize?: number;\n /** Weight for the glyph silhouette (shader mode). Defaults to `800`. */\n fontWeight?: number;\n /**\n * Font for the silhouette (shader mode). Rendered inside an SVG image, which\n * sees system fonts only — to use a webfont, pass `fontCss` with a\n * data-URI @font-face for the same family.\n */\n fontFamily?: string;\n /**\n * Raw CSS embedded in the glyph SVG (shader mode) — typically a @font-face\n * whose `src` is a data: URI, which lets webfonts (e.g. Google Fonts) render\n * inside the silhouette. Load the same face into `document.fonts` so the\n * width measurement matches.\n */\n fontCss?: string;\n /** Shader animation speed (0 pauses). */\n speed?: number;\n}\n\nconst DEFAULT_STACK = \"-apple-system, 'Helvetica Neue', Helvetica, Arial, sans-serif\";\n\ninterface GlyphGeom {\n text: string;\n w: number;\n h: number;\n fontSize: number;\n fontWeight: number;\n fontFamily: string;\n fontCss?: string;\n}\n\nfunction svgOpen(g: GlyphGeom): string {\n const style = g.fontCss ? `<style>${g.fontCss}</style>` : \"\";\n return `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 ${g.w} ${g.h}' width='${g.w}' height='${g.h}'>${style}`;\n}\n\nfunction svgText(g: GlyphGeom, attrs: string): string {\n const safe = g.text.replace(/&/g, \"&\").replace(/</g, \"<\");\n return `<text x='50%' y='${Math.round(g.fontSize * 1.0)}' font-size='${g.fontSize}' font-family=\"${g.fontFamily.replace(/\"/g, \"'\")}\" font-weight='${g.fontWeight}' text-anchor='middle' ${attrs}>${safe}</text>`;\n}\n\nfunction encode(svg: string): string {\n return `data:image/svg+xml,${encodeURIComponent(svg)}`;\n}\n\n/** Solid glyphs — the shader fills the whole letterform. */\nfunction fillSilhouette(g: GlyphGeom): string {\n return encode(`${svgOpen(g)}${svgText(g, \"fill='#000'\")}</svg>`);\n}\n\n/** Stroke-only glyphs — the shader flows in a ring around each letterform. */\nfunction outlineSilhouette(g: GlyphGeom, ow: number): string {\n return encode(`${svgOpen(g)}${svgText(g, `fill='none' stroke='#000' stroke-width='${ow}' stroke-linejoin='round'`)}</svg>`);\n}\n\n/** The interior of outline text — flat or gradient fill, geometry-identical to the silhouette. */\nfunction interior(g: GlyphGeom, fill: string, gradient?: [string, string]): string {\n if (!gradient) return encode(`${svgOpen(g)}${svgText(g, `fill='${fill}'`)}</svg>`);\n const defs = `<defs><linearGradient id='g' x1='0' y1='0' x2='0' y2='1'><stop offset='0' stop-color='${gradient[0]}'/><stop offset='1' stop-color='${gradient[1]}'/></linearGradient></defs>`;\n return encode(`${svgOpen(g)}${defs}${svgText(g, \"fill='url(#g)'\")}</svg>`);\n}\n\nconst LAYER: React.CSSProperties = { position: \"absolute\", inset: 0, width: \"100%\", height: \"100%\" };\n\nfunction ShaderText({\n text,\n tone,\n variant,\n fill,\n fillGradient,\n outlineWidth,\n fontSize,\n fontWeight,\n fontFamily,\n fontCss,\n speed,\n shimmer,\n className,\n style,\n ...rest\n}: {\n text: string;\n tone: MetalTone;\n variant: MetalTextVariant;\n fill: string;\n fillGradient?: [string, string];\n outlineWidth?: number;\n fontSize: number;\n fontWeight: number;\n fontFamily: string;\n fontCss?: string;\n speed: number;\n shimmer: boolean;\n} & React.HTMLAttributes<HTMLElement>) {\n const ref = useRef<HTMLSpanElement>(null);\n const mounted = useMounted();\n const inView = useInView(ref);\n const reduced = useReducedMotion();\n const turn = useStaggeredMount();\n const [geom, setGeom] = useState<GlyphGeom | null>(null);\n\n const outlined = variant === \"outline\";\n const ow = outlineWidth ?? Math.max(2, Math.round(fontSize * 0.05));\n\n useEffect(() => {\n let alive = true;\n const fontSpec = `${fontWeight} ${fontSize}px ${fontFamily}`;\n const measure = () => {\n if (!alive) return;\n const ctx = document.createElement(\"canvas\").getContext(\"2d\");\n if (!ctx) return;\n ctx.font = fontSpec;\n const m = ctx.measureText(text);\n setGeom({\n text,\n w: Math.ceil(m.width + fontSize * 0.24 + ow * 2),\n h: Math.ceil(fontSize * 1.3 + ow),\n fontSize,\n fontWeight,\n fontFamily,\n fontCss,\n });\n };\n // wait for webfonts so the measured width matches the silhouette\n if (document.fonts?.load) document.fonts.load(fontSpec, text).then(measure, measure);\n else measure();\n return () => {\n alive = false;\n };\n }, [text, fontSize, fontWeight, fontFamily, fontCss, ow]);\n\n const ready = mounted && inView && turn && geom;\n const { colorBack: _drop, ...params } = TONE_PARAMS[tone];\n // a thin ring can't survive heavy edge distortion — calm it down for outlines\n const shaderParams = outlined ? { ...params, contour: 0.2, distortion: Math.min(params.distortion ?? 0.1, 0.08) } : params;\n\n return (\n <span\n ref={ref}\n role=\"img\"\n aria-label={text}\n className={className}\n style={{\n position: \"relative\",\n display: \"inline-block\",\n verticalAlign: \"middle\",\n width: geom?.w,\n height: geom?.h,\n ...style,\n }}\n {...rest}\n >\n {ready ? (\n <>\n {outlined && <img src={interior(geom, fill, fillGradient)} alt=\"\" aria-hidden=\"true\" style={LAYER} />}\n <LiquidMetal\n // keyed by silhouette: rapid prop changes can finish processing\n // out of order and leave stale glyphs — a clean re-init can't\n key={`${geom.text}|${geom.fontFamily}|${geom.w}|${outlined ? \"o\" : \"f\"}`}\n image={outlined ? outlineSilhouette(geom, ow) : fillSilhouette(geom)}\n suspendWhenProcessingImage={false}\n colorBack=\"#00000000\"\n fit=\"contain\"\n scale={0.97}\n speed={reduced ? 0 : speed}\n {...shaderParams}\n style={LAYER}\n />\n </>\n ) : (\n // CSS chrome stands in until the shader is ready (and during SSR)\n <span\n aria-hidden=\"true\"\n className={[\"argent-text\", shimmer && !outlined && \"argent-text--shimmer\"].filter(Boolean).join(\" \")}\n data-tone={tone}\n style={{\n fontSize,\n fontWeight,\n fontFamily,\n lineHeight: 1.3,\n whiteSpace: \"nowrap\",\n ...(outlined && {\n background: \"none\",\n WebkitTextFillColor: fillGradient?.[0] ?? fill,\n color: fillGradient?.[0] ?? fill,\n WebkitTextStroke: \"1px rgba(220, 224, 230, 0.55)\",\n }),\n }}\n >\n {text}\n </span>\n )}\n </span>\n );\n}\n\n/**\n * Metal type. By default a chrome gradient clipped to the glyphs with a flowing\n * shimmer — pure CSS, use it freely at any scale. Pass `shader` to pour the\n * real liquid-metal shader into the letterforms — `variant=\"fill\"` floods the\n * glyphs; `variant=\"outline\"` runs the metal around their edges over a dark or\n * gradient interior.\n */\nexport const MetalText = forwardRef<HTMLElement, MetalTextProps>(function MetalText(\n {\n as,\n tone = \"silver\",\n shimmer = true,\n shader = false,\n variant = \"fill\",\n fill = \"#101114\",\n fillGradient,\n outlineWidth,\n fontSize = 64,\n fontWeight = 800,\n fontFamily = DEFAULT_STACK,\n fontCss,\n speed = 1,\n className,\n children,\n ...rest\n },\n ref,\n) {\n if (shader) {\n return (\n <ShaderText\n text={String(children)}\n tone={tone}\n variant={variant}\n fill={fill}\n fillGradient={fillGradient}\n outlineWidth={outlineWidth}\n fontSize={fontSize}\n fontWeight={fontWeight}\n fontFamily={fontFamily}\n fontCss={fontCss}\n speed={speed}\n shimmer={shimmer}\n className={className}\n {...rest}\n />\n );\n }\n const Tag = (as ?? \"span\") as React.ElementType;\n return (\n <Tag\n ref={ref}\n className={[\"argent-text\", shimmer && \"argent-text--shimmer\", className].filter(Boolean).join(\" \")}\n data-tone={tone}\n {...rest}\n >\n {children}\n </Tag>\n );\n});\n","import { useRef } from \"react\";\nimport { LiquidMetal } from \"@paper-design/shaders-react\";\nimport { TONE_PARAMS, useInView, useMounted, useReducedMotion, useStaggeredMount, type MetalTone } from \"./metal\";\n\nexport interface MetalLogoProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Image URL (or data URI) with a transparent background — the metal flows inside its silhouette. */\n src: string;\n tone?: MetalTone;\n /** Rendered size in px (square by default). */\n size?: number;\n width?: number;\n height?: number;\n /** Shader animation speed (0 pauses). */\n speed?: number;\n}\n\n/**\n * Liquid metal poured into a logo — pass any image with a transparent\n * background and the metal flows inside its silhouette. The classic\n * liquid-metal treatment for marks, monograms, and icons.\n */\nexport function MetalLogo({ src, tone = \"silver\", size = 160, width, height, speed = 1, style, ...rest }: MetalLogoProps) {\n const ref = useRef<HTMLDivElement>(null);\n const mounted = useMounted();\n const inView = useInView(ref);\n const reduced = useReducedMotion();\n const turn = useStaggeredMount();\n const w = width ?? size;\n const h = height ?? size;\n const { colorBack: _drop, ...params } = TONE_PARAMS[tone];\n return (\n <div ref={ref} style={{ position: \"relative\", width: w, height: h, ...style }} {...rest}>\n {mounted && inView && turn && (\n <LiquidMetal\n key={src}\n image={src}\n suspendWhenProcessingImage={false}\n colorBack=\"#00000000\"\n fit=\"contain\"\n scale={0.92}\n speed={reduced ? 0 : speed}\n {...params}\n style={{ position: \"absolute\", inset: 0, width: \"100%\", height: \"100%\" }}\n />\n )}\n </div>\n );\n}\n"],"mappings":"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","names":["import_react","import_jsx_runtime","Metal","MetalCard","MetalButton","import_react","import_jsx_runtime","MetalToggle","MetalProgress","MetalBadge","import_react","import_shaders_react","import_jsx_runtime","MetalText","import_react","import_shaders_react","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/surfaces.tsx","../src/metal.tsx","../src/engine.ts","../src/haptics.ts","../src/controls.tsx","../src/text.tsx","../src/logo.tsx","../src/icon.tsx"],"sourcesContent":["export { Metal, MetalCard, MetalButton } from \"./surfaces\";\nexport type { MetalProps, MetalCardProps, MetalButtonProps, MetalVariant, MetalFrame } from \"./surfaces\";\nexport { MetalToggle, MetalProgress, MetalBadge } from \"./controls\";\nexport type { MetalToggleProps, MetalProgressProps, MetalBadgeProps } from \"./controls\";\nexport { MetalText } from \"./text\";\nexport type { MetalTextProps, MetalTextVariant } from \"./text\";\nexport { MetalLogo } from \"./logo\";\nexport type { MetalLogoProps } from \"./logo\";\nexport { MetalIcon } from \"./icon\";\nexport type { MetalIconProps } from \"./icon\";\nexport { MetalFill, TONE_PARAMS, FINISHES, EFFECTS, useMounted, useInView, useReducedMotion } from \"./metal\";\nexport type { MetalTone, MetalFillProps, MetalFinish, MetalEffect } from \"./metal\";\nexport { mountMetal, NATIVE_TONES } from \"./engine\";\nexport type { MetalEngine, NativeMetalParams, MetalMount } from \"./engine\";\nexport { setHaptics } from \"./haptics\";\n","import { forwardRef } from \"react\";\nimport { MetalFill, type MetalEffect, type MetalFinish, type MetalTone } from \"./metal\";\nimport type { MetalEngine } from \"./engine\";\nimport { PRESS_PATTERN, vibrate } from \"./haptics\";\n\nfunction cx(...parts: (string | false | undefined | null)[]): string {\n return parts.filter(Boolean).join(\" \");\n}\n\nfunction assignRef<T>(ref: React.ForwardedRef<T>, node: T | null) {\n if (typeof ref === \"function\") ref(node);\n else if (ref) ref.current = node;\n}\n\n/** Where the liquid metal shows: just the edge, or the whole surface. */\nexport type MetalVariant = \"border\" | \"fill\";\n\n/** Border framing: a single rim, or a rim plus an inner hairline frame. */\nexport type MetalFrame = \"single\" | \"double\";\n\ntype StyleVars = React.CSSProperties & Record<`--${string}`, string>;\n\nexport interface MetalProps extends React.HTMLAttributes<HTMLElement> {\n /** Element/component to render. Defaults to `div`. */\n as?: React.ElementType;\n /** Metal finish. */\n tone?: MetalTone;\n /** `\"border\"` (metal edge only, default) or `\"fill\"` (metal fills the surface). */\n variant?: MetalVariant;\n /** `\"single\"` rim (default) or `\"double\"` — rim plus an inner hairline frame. */\n frame?: MetalFrame;\n /** Let the metal show faintly through the interior panel (border variant). */\n tint?: boolean;\n /** Border thickness in px (border variant). */\n borderWidth?: number;\n /** Fill the whole surface with metal on hover (border variant). */\n revealOnHover?: boolean;\n /** Corner radius in px. */\n radius?: number;\n /** Shader animation speed (0 pauses the metal). */\n speed?: number;\n /** Pattern scale — higher spreads the reflection bands out. */\n metalScale?: number;\n /** Shader engine: Paper's LiquidMetal (default) or Argent's own. */\n engine?: MetalEngine;\n /** Shape-tuned shader preset. Defaults to `\"surface\"`. */\n finish?: MetalFinish;\n /** Motion character: flow, molten, ripple, chrome, or wave. */\n effect?: MetalEffect;\n /** Band direction in degrees — overrides the tone/finish default. */\n angle?: number;\n /** A specular streak that sweeps across on hover. */\n sheen?: boolean;\n /**\n * A frosted standoff ring outside the metal — a few px of backdrop blur\n * finished with a ~5% hairline. `true` for 8px, or a number for the ring\n * width. Theme the line with `--argent-halo-line`.\n */\n halo?: boolean | number;\n}\n\nfunction buildVars(radius: number, borderWidth: number, halo: boolean | number, style?: React.CSSProperties): StyleVars {\n const vars: StyleVars = {\n borderRadius: radius,\n \"--argent-bw\": `${borderWidth}px`,\n \"--argent-radius\": `${radius}px`,\n ...style,\n } as StyleVars;\n if (halo) vars[\"--argent-halo\"] = `${halo === true ? 8 : halo}px`;\n return vars;\n}\n\n/**\n * A liquid-metal surface powered by Paper's `LiquidMetal` shader. By default the\n * metal is just the edge; pass `variant=\"fill\"` for a full metal surface, or\n * `revealOnHover` to fill in on interaction. The base for every Argent component.\n */\nexport const Metal = forwardRef<HTMLElement, MetalProps>(function Metal(\n {\n as,\n tone = \"silver\",\n variant = \"border\",\n frame = \"single\",\n tint = false,\n borderWidth = 1.5,\n revealOnHover = false,\n radius = 14,\n speed,\n metalScale,\n engine,\n finish,\n effect,\n angle,\n sheen = false,\n halo = false,\n className,\n style,\n children,\n ...rest\n },\n ref,\n) {\n const Tag = (as ?? \"div\") as React.ElementType;\n const border = variant === \"border\";\n return (\n <Tag\n ref={(node: HTMLElement | null) => assignRef(ref, node)}\n className={cx(\n \"argent\",\n border ? \"argent--border\" : \"argent--fill\",\n border && frame === \"double\" && \"argent--double\",\n border && tint && \"argent--tint\",\n revealOnHover && \"argent--reveal\",\n sheen && \"argent--sheen\",\n !!halo && \"argent--halo\",\n className,\n )}\n data-tone={tone}\n style={buildVars(radius, borderWidth, halo, style)}\n {...rest}\n >\n <span className=\"argent-fill\" aria-hidden=\"true\">\n <MetalFill tone={tone} speed={speed} scale={metalScale} engine={engine} finish={finish} effect={effect} angle={angle} />\n </span>\n {border && <span className=\"argent-core\" aria-hidden=\"true\" />}\n {sheen && <span className=\"argent-sheen\" aria-hidden=\"true\" />}\n <span className=\"argent-content\">{children}</span>\n </Tag>\n );\n});\n\nexport interface MetalCardProps extends MetalProps {}\n\n/** A padded liquid-metal container. Metal edge by default. */\nexport const MetalCard = forwardRef<HTMLElement, MetalCardProps>(function MetalCard(\n { className, radius = 18, ...rest },\n ref,\n) {\n return <Metal ref={ref} radius={radius} className={cx(\"argent-card\", className)} {...rest} />;\n});\n\nexport interface MetalButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n tone?: MetalTone;\n size?: \"sm\" | \"md\" | \"lg\";\n /** `\"border\"` (default — readable, fills on hover) or `\"fill\"` (full chrome). */\n variant?: MetalVariant;\n /** Corner radius in px. */\n radius?: number;\n borderWidth?: number;\n /** Fill with metal on hover (border variant). Defaults to `true`. */\n revealOnHover?: boolean;\n /** Vibrate on press where supported. Defaults to `true`. */\n haptics?: boolean;\n speed?: number;\n engine?: MetalEngine;\n finish?: MetalFinish;\n effect?: MetalEffect;\n angle?: number;\n halo?: boolean | number;\n /** An icon (any SVG element) rendered before the label, in the label colour. */\n icon?: React.ReactNode;\n}\n\nconst SIZE_RADIUS = { sm: 11, md: 13, lg: 15 } as const;\n\n/** A liquid-metal button — readable at rest, molten on hover, with a stamped press. */\nexport const MetalButton = forwardRef<HTMLButtonElement, MetalButtonProps>(function MetalButton(\n { tone = \"silver\", size = \"md\", variant = \"border\", radius, borderWidth = 1.5, revealOnHover = true, haptics = true, speed, engine, finish = \"button\", effect, angle, halo = false, icon, type = \"button\", className, children, style, onPointerDown, ...rest },\n ref,\n) {\n const border = variant === \"border\";\n return (\n <button\n ref={ref}\n type={type}\n onPointerDown={(e) => {\n if (haptics) vibrate(PRESS_PATTERN);\n onPointerDown?.(e);\n }}\n className={cx(\"argent\", border ? \"argent--border\" : \"argent--fill\", border && revealOnHover && \"argent--reveal\", \"argent--sheen\", !!halo && \"argent--halo\", \"argent-btn\", `argent-btn--${size}`, className)}\n data-tone={tone}\n style={buildVars(radius ?? SIZE_RADIUS[size], borderWidth, halo, style)}\n {...rest}\n >\n <span className=\"argent-fill\" aria-hidden=\"true\">\n <MetalFill tone={tone} speed={speed} engine={engine} finish={finish} effect={effect} angle={angle} />\n </span>\n {border && <span className=\"argent-core\" aria-hidden=\"true\" />}\n <span className=\"argent-sheen\" aria-hidden=\"true\" />\n <span className=\"argent-content argent-btn-label\">\n {icon && <span className=\"argent-btn-icon\" aria-hidden=\"true\">{icon}</span>}\n {children}\n </span>\n </button>\n );\n});\n","import { useEffect, useRef, useState } from \"react\";\nimport { LiquidMetal, type LiquidMetalParams } from \"@paper-design/shaders-react\";\nimport { mountMetal, NATIVE_TONES, type MetalEngine, type MetalMount, type NativeMetalParams } from \"./engine\";\n\n/**\n * The liquid-metal surface is Paper's `LiquidMetal` WebGL shader\n * (@paper-design/shaders) run with `shape=\"none\"` so it fills the whole element\n * instead of painting a blob. Each tone is a tuned set of shader params; the\n * canvas sits behind the content and is clipped to the surface's radius.\n *\n * `@paper-design/shaders-react` is a peer dependency — install it alongside\n * `argentui`. It is licensed under PolyForm Shield by Paper.\n */\n\nexport type MetalTone = \"silver\" | \"gold\" | \"gunmetal\" | \"obsidian\";\n\ntype Tuned = Pick<\n LiquidMetalParams,\n \"colorBack\" | \"colorTint\" | \"repetition\" | \"softness\" | \"shiftRed\" | \"shiftBlue\" | \"distortion\" | \"contour\" | \"angle\"\n>;\n\nexport const TONE_PARAMS: Record<MetalTone, Tuned> = {\n silver: {\n colorBack: \"#a7abb1\", colorTint: \"#ffffff\",\n repetition: 3, softness: 0.18, shiftRed: 0.32, shiftBlue: 0.32, distortion: 0.14, contour: 0.55, angle: 68,\n },\n gold: {\n colorBack: \"#94700e\", colorTint: \"#ffedb0\",\n repetition: 3, softness: 0.2, shiftRed: 0.3, shiftBlue: 0.12, distortion: 0.13, contour: 0.5, angle: 68,\n },\n gunmetal: {\n colorBack: \"#33373d\", colorTint: \"#b2bac4\",\n repetition: 2.6, softness: 0.26, shiftRed: 0.22, shiftBlue: 0.32, distortion: 0.1, contour: 0.45, angle: 80,\n },\n obsidian: {\n colorBack: \"#000000\", colorTint: \"#9498a6\",\n repetition: 2, softness: 0.4, shiftRed: 0.14, shiftBlue: 0.24, distortion: 0.07, contour: 0.32, angle: 92,\n },\n};\n\n// Paper's image pre-processing misbehaves when several image-mask shaders\n// initialise at once (only one survives) — serialise mounts a beat apart.\nlet imageMountQueue: Promise<void> = Promise.resolve();\nexport function useStaggeredMount(): boolean {\n const [go, setGo] = useState(false);\n useEffect(() => {\n let alive = true;\n imageMountQueue = imageMountQueue.then(async () => {\n if (!alive) return; // unmounted while queued — release the queue instantly\n setGo(true);\n await new Promise((r) => setTimeout(r, 300));\n });\n return () => {\n alive = false;\n };\n }, []);\n return go;\n}\n\n/** True once mounted on the client — the WebGL canvas can't render during SSR. */\nexport function useMounted(): boolean {\n const [m, setM] = useState(false);\n useEffect(() => setM(true), []);\n return m;\n}\n\n/** True when the user prefers reduced motion — the metal freezes (speed 0). */\nexport function useReducedMotion(): boolean {\n const [reduced, setReduced] = useState(false);\n useEffect(() => {\n const mq = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n setReduced(mq.matches);\n const onChange = (e: MediaQueryListEvent) => setReduced(e.matches);\n mq.addEventListener(\"change\", onChange);\n return () => mq.removeEventListener(\"change\", onChange);\n }, []);\n return reduced;\n}\n\n/**\n * Reports whether `ref` is on/near screen. Each metal surface is a WebGL\n * canvas, and browsers cap concurrent contexts (~16) — so we only mount the\n * shader while it's visible and release the context when it scrolls away.\n */\nexport function useInView(ref: React.RefObject<Element | null>, margin = \"250px\"): boolean {\n const [inView, setInView] = useState(false);\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n const io = new IntersectionObserver(([entry]) => setInView(entry.isIntersecting), { rootMargin: margin });\n io.observe(el);\n return () => io.disconnect();\n }, [ref, margin]);\n return inView;\n}\n\n/**\n * Finishes — shader presets tuned to the shape and size of the element. One\n * pattern does not fit all: a card wants broad flowing bands, a thin progress\n * bar wants many stripes crossing it, a 22px toggle thumb wants one soft\n * highlight like a ball bearing, and a hairline badge rim wants dense bands so\n * a tiny visible slice always catches some light.\n */\nexport type MetalFinish = \"surface\" | \"button\" | \"bar\" | \"orb\" | \"rim\";\n\ninterface FinishTuning {\n /** Band direction override (deg). */\n angle?: number;\n /** Random per-mount angle variation (±deg) so identical elements don't look cloned. */\n angleJitter?: number;\n repetition?: number;\n softness?: number;\n distortion?: number;\n /** Multiplier on the tone's chromatic shift. */\n shift?: number;\n /** Default pattern scale. */\n scale?: number;\n /** Multiplier on the animation speed. */\n speed?: number;\n}\n\nexport const FINISHES: Record<MetalFinish, FinishTuning> = {\n /** Cards, nav, panels — broad flowing reflection bands (the tone defaults). */\n surface: { scale: 1.1 },\n /** Buttons — slightly spread, calmer warp so labels stay readable. */\n button: { scale: 1.4, distortion: 0.1 },\n /** Thin horizontal strips (progress) — near-vertical stripes crossing the bar. */\n bar: { angle: 14, repetition: 5, softness: 0.3, distortion: 0.06, shift: 0.5, scale: 0.8, speed: 0.75 },\n /** Small round things (toggle thumbs) — one soft highlight, like a polished sphere. */\n orb: { angle: 112, angleJitter: 20, repetition: 1.7, softness: 0.5, distortion: 0.05, shift: 0.4, scale: 1.5 },\n /** Hairline edges (badges, thin borders) — dense bands so any slice sparkles. */\n rim: { angle: 40, repetition: 4.5, softness: 0.3, distortion: 0.08, shift: 0.5, scale: 0.85, speed: 0.85 },\n};\n\n/**\n * Effects — the character of the liquid's motion, independent of tone and\n * finish: how soft the bands are, how hard the noise churns them, how fast\n * everything moves.\n */\nexport type MetalEffect = \"flow\" | \"molten\" | \"ripple\" | \"chrome\" | \"wave\";\n\ninterface EffectTuning {\n angle?: number;\n repetition?: number;\n softness?: number;\n distortion?: number;\n /** Multiplier on chromatic shift. */\n shift?: number;\n /** Multiplier on animation speed. */\n speed?: number;\n}\n\nexport const EFFECTS: Record<MetalEffect, EffectTuning> = {\n /** The default — steady flowing reflection bands. */\n flow: {},\n /** Slow, heavy, half-melted — soft wide bands churning lazily. */\n molten: { softness: 0.5, distortion: 0.3, speed: 0.45, shift: 0.6 },\n /** Agitated surface — tighter bands, hard noise, quick motion. */\n ripple: { repetition: 4, softness: 0.24, distortion: 0.5, speed: 1.4 },\n /** Mirror-polished — crisp hard bands, strong chromatic fringe, calm. */\n chrome: { softness: 0.05, distortion: 0.05, shift: 1.6, speed: 0.8 },\n /** Horizontal swells rolling through the surface. */\n wave: { angle: 0, repetition: 5, softness: 0.36, distortion: 0.18, speed: 0.7 },\n};\n\nexport interface MetalFillProps {\n tone: MetalTone;\n /** Shader animation speed (0 pauses). */\n speed?: number;\n /** Pattern scale — higher spreads the bands out. Defaults per finish. */\n scale?: number;\n /** `\"paper\"` (Paper's LiquidMetal, default) or `\"native\"` (Argent's own shader). */\n engine?: MetalEngine;\n /** Shape-tuned shader preset. Defaults to `\"surface\"`. */\n finish?: MetalFinish;\n /** Motion character preset. Defaults to `\"flow\"`. */\n effect?: MetalEffect;\n /** Band direction in degrees — overrides the tone/finish default. */\n angle?: number;\n}\n\nconst FILL_STYLE: React.CSSProperties = { position: \"absolute\", inset: 0, width: \"100%\", height: \"100%\" };\n\n/** Argent's own clean-room shader on a plain canvas. */\nfunction NativeCanvas({ params }: { params: NativeMetalParams }) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const mountRef = useRef<MetalMount | null>(null);\n const initial = useRef(params);\n initial.current = params;\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n mountRef.current = mountMetal(canvas, initial.current);\n return () => {\n mountRef.current?.destroy();\n mountRef.current = null;\n };\n }, []);\n useEffect(() => {\n mountRef.current?.update(params);\n }, [params]);\n return <canvas ref={canvasRef} style={{ ...FILL_STYLE, display: \"block\" }} />;\n}\n\n/** The shader canvas, absolutely filling its positioned parent (when in view). */\nexport function MetalFill({ tone, speed = 1, scale, engine = \"paper\", finish = \"surface\", effect = \"flow\", angle }: MetalFillProps) {\n const ref = useRef<HTMLSpanElement>(null);\n const mounted = useMounted();\n const inView = useInView(ref);\n const reduced = useReducedMotion();\n const f = FINISHES[finish];\n const e = EFFECTS[effect];\n const [jitter] = useState(() => (f.angleJitter ? (Math.random() * 2 - 1) * f.angleJitter : 0));\n\n const base = TONE_PARAMS[tone];\n // precedence: explicit prop > effect > finish > tone\n const effAngle = (angle ?? e.angle ?? f.angle ?? base.angle ?? 70) + jitter;\n const effScale = scale ?? f.scale ?? 1.1;\n const effSpeed = (reduced ? 0 : speed) * (f.speed ?? 1) * (e.speed ?? 1);\n const shift = (f.shift ?? 1) * (e.shift ?? 1);\n const repetition = e.repetition ?? f.repetition ?? base.repetition;\n const softness = e.softness ?? f.softness ?? base.softness;\n const distortion = e.distortion ?? f.distortion ?? base.distortion;\n\n const native = NATIVE_TONES[tone];\n const nativeParams: NativeMetalParams = {\n ...native,\n angle: effAngle,\n repetition: repetition ?? native.repetition,\n softness: softness ?? native.softness,\n // the native warp amount runs ~3× paper's distortion scale\n distortion: distortion !== undefined ? distortion * 3 : native.distortion,\n dispersion: native.dispersion * shift,\n speed: effSpeed,\n scale: effScale,\n };\n\n return (\n <span ref={ref} aria-hidden=\"true\" style={{ position: \"absolute\", inset: 0 }}>\n {mounted && inView && (\n engine === \"native\" ? (\n <NativeCanvas params={nativeParams} />\n ) : (\n <LiquidMetal\n shape=\"none\"\n fit=\"cover\"\n scale={effScale}\n speed={effSpeed}\n {...base}\n angle={effAngle}\n repetition={repetition}\n softness={softness}\n distortion={distortion}\n shiftRed={(base.shiftRed ?? 0.3) * shift}\n shiftBlue={(base.shiftBlue ?? 0.3) * shift}\n style={FILL_STYLE}\n />\n )\n )}\n </span>\n );\n}\n","/**\n * Argent's own liquid-metal shader — a clean-room WebGL2 implementation of the\n * classic recipe: hard light→dark reflection banding, curvature-warped UVs,\n * time-driven simplex-noise flow, per-channel chromatic dispersion, and a rim\n * lift. No third-party shader code beyond the public-domain-style simplex\n * noise (Ashima Arts / Stefan Gustavson, MIT).\n *\n * Used when a surface sets `engine=\"native\"`; removes the need for\n * @paper-design/shaders-react entirely.\n */\n\nexport interface NativeMetalParams {\n /** Highlight band colour (hex). */\n light: string;\n /** Shadow band colour (hex). */\n dark: string;\n /** Stripe density. */\n repetition: number;\n /** Band direction in degrees. */\n angle: number;\n /** Band edge softness 0–1. */\n softness: number;\n /** Per-channel band offset (chromatic dispersion). */\n dispersion: number;\n /** Noise warp amount. */\n distortion: number;\n /** Animation speed (0 = still). */\n speed: number;\n /** Pattern scale — higher spreads the bands out. */\n scale: number;\n}\n\nexport type MetalEngine = \"paper\" | \"native\";\n\nconst VERT = `#version 300 es\nvoid main() {\n vec2 pos = vec2(float((gl_VertexID << 1) & 2), float(gl_VertexID & 2));\n gl_Position = vec4(pos * 2.0 - 1.0, 0.0, 1.0);\n}`;\n\nconst FRAG = `#version 300 es\nprecision highp float;\nuniform vec2 u_res;\nuniform float u_time;\nuniform vec3 u_light;\nuniform vec3 u_dark;\nuniform float u_rep;\nuniform float u_angle;\nuniform float u_soft;\nuniform float u_disp;\nuniform float u_dist;\nuniform float u_scale;\nout vec4 outColor;\n\n// 2D simplex noise — Ashima Arts / Stefan Gustavson (webgl-noise, MIT).\nvec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\nvec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\nvec3 permute(vec3 x) { return mod289(((x * 34.0) + 1.0) * x); }\nfloat snoise(vec2 v) {\n const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439);\n vec2 i = floor(v + dot(v, C.yy));\n vec2 x0 = v - i + dot(i, C.xx);\n vec2 i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n i = mod289(i);\n vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0)) + i.x + vec3(0.0, i1.x, 1.0));\n vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);\n m = m * m;\n m = m * m;\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n\n// One reflection band: a soft triangle wave over the warped coordinate.\nfloat stripe(float coord) {\n float f = fract(coord);\n float tri = abs(f * 2.0 - 1.0);\n return smoothstep(0.5 - u_soft, 0.5 + u_soft, tri);\n}\n\nvoid main() {\n vec2 uv = (gl_FragCoord.xy / u_res - 0.5);\n uv.x *= u_res.x / u_res.y;\n uv /= max(u_scale, 0.001);\n\n float t = u_time;\n\n // curvature: bands bend as if wrapping a bulged surface\n float d = length(uv);\n float bulge = 1.0 - 0.45 * d * d;\n\n // flowing warp — two noise octaves drifting at different rates\n float n = snoise(uv * 0.9 + vec2(0.0, -t * 0.28));\n n += 0.35 * snoise(uv * 1.8 + vec2(t * 0.1, -t * 0.45));\n\n // rotate so bands run along u_angle\n float c = cos(u_angle), s = sin(u_angle);\n vec2 ruv = mat2(c, -s, s, c) * uv;\n\n float coord = ruv.y * bulge * u_rep + n * u_dist * 2.2 - t * 0.22;\n\n // per-channel dispersion — the chrome fringing\n float r = stripe(coord + u_disp);\n float g = stripe(coord);\n float b = stripe(coord - u_disp);\n\n vec3 col = vec3(\n mix(u_dark.r, u_light.r, r),\n mix(u_dark.g, u_light.g, g),\n mix(u_dark.b, u_light.b, b)\n );\n\n // rim lift toward the edges\n col *= 0.94 + 0.14 * smoothstep(0.25, 0.85, d);\n\n outColor = vec4(col, 1.0);\n}`;\n\nfunction hexToRgb(hex: string): [number, number, number] {\n const h = hex.replace(\"#\", \"\");\n const v = h.length === 3 ? h.split(\"\").map((ch) => ch + ch).join(\"\") : h;\n const n = parseInt(v, 16);\n return [((n >> 16) & 255) / 255, ((n >> 8) & 255) / 255, (n & 255) / 255];\n}\n\nexport const NATIVE_TONES: Record<string, Omit<NativeMetalParams, \"speed\" | \"scale\">> = {\n silver: { light: \"#f8fafc\", dark: \"#23262b\", repetition: 1.8, angle: 68, softness: 0.34, dispersion: 0.03, distortion: 0.38 },\n gold: { light: \"#ffe9a8\", dark: \"#6e5408\", repetition: 1.8, angle: 68, softness: 0.34, dispersion: 0.028, distortion: 0.36 },\n gunmetal: { light: \"#b6bec9\", dark: \"#14161a\", repetition: 1.6, angle: 80, softness: 0.36, dispersion: 0.025, distortion: 0.34 },\n obsidian: { light: \"#787c88\", dark: \"#000000\", repetition: 1.4, angle: 92, softness: 0.42, dispersion: 0.02, distortion: 0.28 },\n};\n\nexport interface MetalMount {\n update(params: Partial<NativeMetalParams>): void;\n destroy(): void;\n}\n\nfunction compile(gl: WebGL2RenderingContext, type: number, src: string): WebGLShader | null {\n const sh = gl.createShader(type);\n if (!sh) return null;\n gl.shaderSource(sh, src);\n gl.compileShader(sh);\n if (!gl.getShaderParameter(sh, gl.COMPILE_STATUS)) {\n console.error(\"argent shader:\", gl.getShaderInfoLog(sh));\n gl.deleteShader(sh);\n return null;\n }\n return sh;\n}\n\n/** Mount the native liquid-metal shader on a canvas. Returns null without WebGL2. */\nexport function mountMetal(canvas: HTMLCanvasElement, params: NativeMetalParams): MetalMount | null {\n const gl = canvas.getContext(\"webgl2\", { antialias: true });\n if (!gl) return null;\n\n const vs = compile(gl, gl.VERTEX_SHADER, VERT);\n const fs = compile(gl, gl.FRAGMENT_SHADER, FRAG);\n if (!vs || !fs) return null;\n const prog = gl.createProgram()!;\n gl.attachShader(prog, vs);\n gl.attachShader(prog, fs);\n gl.linkProgram(prog);\n if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {\n console.error(\"argent shader link:\", gl.getProgramInfoLog(prog));\n return null;\n }\n gl.useProgram(prog);\n\n const U = (name: string) => gl.getUniformLocation(prog, name);\n const uRes = U(\"u_res\"), uTime = U(\"u_time\"), uLight = U(\"u_light\"), uDark = U(\"u_dark\");\n const uRep = U(\"u_rep\"), uAngle = U(\"u_angle\"), uSoft = U(\"u_soft\");\n const uDisp = U(\"u_disp\"), uDist = U(\"u_dist\"), uScale = U(\"u_scale\");\n\n let p = { ...params };\n let raf = 0;\n let tAcc = Math.random() * 40; // desync multiple surfaces\n let last = performance.now();\n let dead = false;\n\n function draw() {\n raf = 0;\n if (dead) return;\n const dpr = Math.min(window.devicePixelRatio || 1, 2);\n const w = Math.max(1, Math.round(canvas.clientWidth * dpr));\n const h = Math.max(1, Math.round(canvas.clientHeight * dpr));\n if (canvas.width !== w || canvas.height !== h) {\n canvas.width = w;\n canvas.height = h;\n gl!.viewport(0, 0, w, h);\n }\n const now = performance.now();\n tAcc += ((now - last) / 1000) * p.speed;\n last = now;\n\n gl!.uniform2f(uRes, w, h);\n gl!.uniform1f(uTime, tAcc);\n gl!.uniform3fv(uLight, hexToRgb(p.light));\n gl!.uniform3fv(uDark, hexToRgb(p.dark));\n gl!.uniform1f(uRep, p.repetition);\n gl!.uniform1f(uAngle, (p.angle * Math.PI) / 180);\n gl!.uniform1f(uSoft, Math.max(0.02, p.softness));\n gl!.uniform1f(uDisp, p.dispersion);\n gl!.uniform1f(uDist, p.distortion);\n gl!.uniform1f(uScale, p.scale);\n gl!.drawArrays(gl!.TRIANGLES, 0, 3);\n\n if (p.speed > 0) raf = requestAnimationFrame(draw);\n }\n draw();\n\n return {\n update(np) {\n p = { ...p, ...np };\n last = performance.now();\n if (!raf) raf = requestAnimationFrame(draw);\n },\n destroy() {\n dead = true;\n if (raf) cancelAnimationFrame(raf);\n gl.getExtension(\"WEBGL_lose_context\")?.loseContext();\n },\n };\n}\n","/**\n * Tiny haptics for metal presses — `navigator.vibrate` where available\n * (Android Chrome; iOS Safari ignores it). On by default, like Glacé.\n */\n\nlet enabled = true;\n\n/** Globally enable/disable Argent haptics. */\nexport function setHaptics(on: boolean) {\n enabled = on;\n}\n\nexport function vibrate(pattern: number | number[]) {\n if (!enabled || typeof navigator === \"undefined\" || !(\"vibrate\" in navigator)) return;\n try {\n navigator.vibrate(pattern);\n } catch {\n // some browsers throw on vibrate without user activation — fine to ignore\n }\n}\n\n/** The stamped-press click. */\nexport const PRESS_PATTERN = 8;\n","import { forwardRef, useState } from \"react\";\nimport { MetalFill, type MetalTone } from \"./metal\";\nimport { Metal, type MetalProps } from \"./surfaces\";\nimport { PRESS_PATTERN, vibrate } from \"./haptics\";\n\nexport interface MetalToggleProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"onChange\"> {\n tone?: MetalTone;\n checked?: boolean;\n defaultChecked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n /** Vibrate on toggle where supported. Defaults to `true`. */\n haptics?: boolean;\n}\n\n/**\n * A mercury switch — the thumb is a drop of liquid metal that slides (and\n * squishes) across a dark channel.\n */\nexport const MetalToggle = forwardRef<HTMLButtonElement, MetalToggleProps>(function MetalToggle(\n { tone = \"silver\", checked, defaultChecked = false, onCheckedChange, haptics = true, className, onClick, ...rest },\n ref,\n) {\n const [internal, setInternal] = useState(defaultChecked);\n const isOn = checked ?? internal;\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"switch\"\n aria-checked={isOn}\n data-tone={tone}\n data-checked={isOn || undefined}\n className={[\"argent-toggle\", className].filter(Boolean).join(\" \")}\n onClick={(e) => {\n if (haptics) vibrate(PRESS_PATTERN);\n if (checked === undefined) setInternal(!isOn);\n onCheckedChange?.(!isOn);\n onClick?.(e);\n }}\n {...rest}\n >\n <span className=\"argent-toggle-thumb\" aria-hidden=\"true\">\n <MetalFill tone={tone} finish=\"orb\" />\n </span>\n </button>\n );\n});\n\nexport interface MetalProgressProps extends React.HTMLAttributes<HTMLDivElement> {\n tone?: MetalTone;\n /** 0–100. Omit for an indeterminate molten sweep. */\n value?: number;\n /** Track height in px. */\n height?: number;\n}\n\n/** A molten progress bar — liquid metal rising in a dark channel. */\nexport const MetalProgress = forwardRef<HTMLDivElement, MetalProgressProps>(function MetalProgress(\n { tone = \"silver\", value, height = 10, className, style, ...rest },\n ref,\n) {\n const indeterminate = value === undefined;\n const clamped = indeterminate ? 0 : Math.max(0, Math.min(100, value));\n return (\n <div\n ref={ref}\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={indeterminate ? undefined : clamped}\n data-tone={tone}\n className={[\"argent-progress\", indeterminate && \"argent-progress--indeterminate\", className].filter(Boolean).join(\" \")}\n style={{ height, ...style }}\n {...rest}\n >\n <span\n className=\"argent-progress-fill\"\n style={indeterminate ? undefined : { width: `${clamped}%` }}\n aria-hidden=\"true\"\n >\n <MetalFill tone={tone} finish=\"bar\" />\n </span>\n </div>\n );\n});\n\nexport interface MetalBadgeProps extends Omit<MetalProps, \"as\" | \"variant\"> {}\n\n/** A small liquid-metal pill — a metal rim around a quiet label. */\nexport const MetalBadge = forwardRef<HTMLElement, MetalBadgeProps>(function MetalBadge(\n { className, radius = 999, borderWidth = 1, finish = \"rim\", ...rest },\n ref,\n) {\n return (\n <Metal\n ref={ref}\n as=\"span\"\n variant=\"border\"\n radius={radius}\n borderWidth={borderWidth}\n finish={finish}\n className={[\"argent-badge\", className].filter(Boolean).join(\" \")}\n {...rest}\n />\n );\n});\n","import { forwardRef, useEffect, useRef, useState } from \"react\";\nimport { LiquidMetal } from \"@paper-design/shaders-react\";\nimport { TONE_PARAMS, useInView, useMounted, useReducedMotion, useStaggeredMount, type MetalTone } from \"./metal\";\n\n/** Where the metal lives in shader text: the whole glyph, or just its edge. */\nexport type MetalTextVariant = \"fill\" | \"outline\";\n\nexport interface MetalTextProps extends React.HTMLAttributes<HTMLElement> {\n /** Element to render. Defaults to `span`. */\n as?: React.ElementType;\n tone?: MetalTone;\n /** Animate the highlight band across the glyphs (CSS mode). Defaults to `true`. */\n shimmer?: boolean;\n /**\n * Pour the real liquid-metal shader into the glyphs — flowing bands, liquid\n * edges, chromatic fringe. On by default (one WebGL canvas; the CSS chrome\n * gradient renders as a placeholder until the shader is ready, and stands in\n * wherever WebGL isn't). Set `shader={false}` for the pure-CSS gradient.\n * Shader mode requires a plain string child; element children fall back to CSS.\n */\n shader?: boolean;\n /**\n * Shader mode: `\"fill\"` (metal fills the glyphs, default) or `\"outline\"` —\n * the metal runs around the edge of each letterform and the interior takes\n * `fill` / `fillGradient`.\n */\n variant?: MetalTextVariant;\n /** Interior colour for `variant=\"outline\"`. */\n fill?: string;\n /** Interior vertical gradient `[top, bottom]` for `variant=\"outline\"` — wins over `fill`. */\n fillGradient?: [string, string];\n /** Metal edge thickness in px for `variant=\"outline\"`. Defaults to ~5% of the font size. */\n outlineWidth?: number;\n /** Type size in px (shader mode). Defaults to `64`. */\n fontSize?: number;\n /** Weight for the glyph silhouette (shader mode). Defaults to `800`. */\n fontWeight?: number;\n /**\n * Font for the silhouette (shader mode). Rendered inside an SVG image, which\n * sees system fonts only — to use a webfont, pass `fontCss` with a\n * data-URI @font-face for the same family.\n */\n fontFamily?: string;\n /**\n * Raw CSS embedded in the glyph SVG (shader mode) — typically a @font-face\n * whose `src` is a data: URI, which lets webfonts (e.g. Google Fonts) render\n * inside the silhouette. Load the same face into `document.fonts` so the\n * width measurement matches.\n */\n fontCss?: string;\n /** Shader animation speed (0 pauses). */\n speed?: number;\n}\n\nconst DEFAULT_STACK = \"-apple-system, 'Helvetica Neue', Helvetica, Arial, sans-serif\";\n\ninterface GlyphGeom {\n text: string;\n w: number;\n h: number;\n fontSize: number;\n fontWeight: number;\n fontFamily: string;\n fontCss?: string;\n}\n\nfunction svgOpen(g: GlyphGeom): string {\n const style = g.fontCss ? `<style>${g.fontCss}</style>` : \"\";\n return `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 ${g.w} ${g.h}' width='${g.w}' height='${g.h}'>${style}`;\n}\n\nfunction svgText(g: GlyphGeom, attrs: string): string {\n const safe = g.text.replace(/&/g, \"&\").replace(/</g, \"<\");\n return `<text x='50%' y='${Math.round(g.fontSize * 1.0)}' font-size='${g.fontSize}' font-family=\"${g.fontFamily.replace(/\"/g, \"'\")}\" font-weight='${g.fontWeight}' text-anchor='middle' ${attrs}>${safe}</text>`;\n}\n\nfunction encode(svg: string): string {\n return `data:image/svg+xml,${encodeURIComponent(svg)}`;\n}\n\n/** Solid glyphs — the shader fills the whole letterform. */\nfunction fillSilhouette(g: GlyphGeom): string {\n return encode(`${svgOpen(g)}${svgText(g, \"fill='#000'\")}</svg>`);\n}\n\n/** Stroke-only glyphs — the shader flows in a ring around each letterform. */\nfunction outlineSilhouette(g: GlyphGeom, ow: number): string {\n return encode(`${svgOpen(g)}${svgText(g, `fill='none' stroke='#000' stroke-width='${ow}' stroke-linejoin='round'`)}</svg>`);\n}\n\n/** The interior of outline text — flat or gradient fill, geometry-identical to the silhouette. */\nfunction interior(g: GlyphGeom, fill: string, gradient?: [string, string]): string {\n if (!gradient) return encode(`${svgOpen(g)}${svgText(g, `fill='${fill}'`)}</svg>`);\n const defs = `<defs><linearGradient id='g' x1='0' y1='0' x2='0' y2='1'><stop offset='0' stop-color='${gradient[0]}'/><stop offset='1' stop-color='${gradient[1]}'/></linearGradient></defs>`;\n return encode(`${svgOpen(g)}${defs}${svgText(g, \"fill='url(#g)'\")}</svg>`);\n}\n\nconst LAYER: React.CSSProperties = { position: \"absolute\", inset: 0, width: \"100%\", height: \"100%\" };\n\nfunction ShaderText({\n text,\n tone,\n variant,\n fill,\n fillGradient,\n outlineWidth,\n fontSize,\n fontWeight,\n fontFamily,\n fontCss,\n speed,\n shimmer,\n className,\n style,\n ...rest\n}: {\n text: string;\n tone: MetalTone;\n variant: MetalTextVariant;\n fill: string;\n fillGradient?: [string, string];\n outlineWidth?: number;\n fontSize: number;\n fontWeight: number;\n fontFamily: string;\n fontCss?: string;\n speed: number;\n shimmer: boolean;\n} & React.HTMLAttributes<HTMLElement>) {\n const ref = useRef<HTMLSpanElement>(null);\n const mounted = useMounted();\n const inView = useInView(ref);\n const reduced = useReducedMotion();\n const turn = useStaggeredMount();\n const [geom, setGeom] = useState<GlyphGeom | null>(null);\n\n const outlined = variant === \"outline\";\n const ow = outlineWidth ?? Math.max(2, Math.round(fontSize * 0.05));\n\n useEffect(() => {\n let alive = true;\n const fontSpec = `${fontWeight} ${fontSize}px ${fontFamily}`;\n const measure = () => {\n if (!alive) return;\n const ctx = document.createElement(\"canvas\").getContext(\"2d\");\n if (!ctx) return;\n ctx.font = fontSpec;\n const m = ctx.measureText(text);\n setGeom({\n text,\n w: Math.ceil(m.width + fontSize * 0.24 + ow * 2),\n h: Math.ceil(fontSize * 1.3 + ow),\n fontSize,\n fontWeight,\n fontFamily,\n fontCss,\n });\n };\n // wait for webfonts so the measured width matches the silhouette\n if (document.fonts?.load) document.fonts.load(fontSpec, text).then(measure, measure);\n else measure();\n return () => {\n alive = false;\n };\n }, [text, fontSize, fontWeight, fontFamily, fontCss, ow]);\n\n const ready = mounted && inView && turn && geom;\n const { colorBack: _drop, ...params } = TONE_PARAMS[tone];\n // a thin ring can't survive heavy edge distortion — calm it down for outlines\n const shaderParams = outlined ? { ...params, contour: 0.2, distortion: Math.min(params.distortion ?? 0.1, 0.08) } : params;\n\n return (\n <span\n ref={ref}\n role=\"img\"\n aria-label={text}\n className={className}\n style={{\n position: \"relative\",\n display: \"inline-block\",\n verticalAlign: \"middle\",\n width: geom?.w,\n height: geom?.h,\n ...style,\n }}\n {...rest}\n >\n {ready ? (\n <>\n {outlined && <img src={interior(geom, fill, fillGradient)} alt=\"\" aria-hidden=\"true\" style={LAYER} />}\n <LiquidMetal\n // keyed by silhouette: rapid prop changes can finish processing\n // out of order and leave stale glyphs — a clean re-init can't\n key={`${geom.text}|${geom.fontFamily}|${geom.w}|${outlined ? \"o\" : \"f\"}`}\n image={outlined ? outlineSilhouette(geom, ow) : fillSilhouette(geom)}\n suspendWhenProcessingImage={false}\n colorBack=\"#00000000\"\n fit=\"contain\"\n scale={0.97}\n speed={reduced ? 0 : speed}\n {...shaderParams}\n style={LAYER}\n />\n </>\n ) : (\n // CSS chrome stands in until the shader is ready (and during SSR)\n <span\n aria-hidden=\"true\"\n className={[\"argent-text\", shimmer && !outlined && \"argent-text--shimmer\"].filter(Boolean).join(\" \")}\n data-tone={tone}\n style={{\n fontSize,\n fontWeight,\n fontFamily,\n lineHeight: 1.3,\n whiteSpace: \"nowrap\",\n ...(outlined && {\n background: \"none\",\n WebkitTextFillColor: fillGradient?.[0] ?? fill,\n color: fillGradient?.[0] ?? fill,\n WebkitTextStroke: \"1px rgba(220, 224, 230, 0.55)\",\n }),\n }}\n >\n {text}\n </span>\n )}\n </span>\n );\n}\n\n/**\n * Metal type. By default the real liquid-metal shader is poured into the glyphs\n * — `variant=\"fill\"` floods them, `variant=\"outline\"` runs the metal around\n * their edges over a dark or gradient interior. The CSS chrome gradient stands\n * in until the shader loads. Set `shader={false}` for the pure-CSS gradient\n * (free at any scale); element children also fall back to it.\n */\nexport const MetalText = forwardRef<HTMLElement, MetalTextProps>(function MetalText(\n {\n as,\n tone = \"silver\",\n shimmer = true,\n shader = true,\n variant = \"fill\",\n fill = \"#101114\",\n fillGradient,\n outlineWidth,\n fontSize = 64,\n fontWeight = 800,\n fontFamily = DEFAULT_STACK,\n fontCss,\n speed = 1,\n className,\n children,\n ...rest\n },\n ref,\n) {\n if (shader && typeof children === \"string\") {\n return (\n <ShaderText\n text={String(children)}\n tone={tone}\n variant={variant}\n fill={fill}\n fillGradient={fillGradient}\n outlineWidth={outlineWidth}\n fontSize={fontSize}\n fontWeight={fontWeight}\n fontFamily={fontFamily}\n fontCss={fontCss}\n speed={speed}\n shimmer={shimmer}\n className={className}\n {...rest}\n />\n );\n }\n const Tag = (as ?? \"span\") as React.ElementType;\n return (\n <Tag\n ref={ref}\n className={[\"argent-text\", shimmer && \"argent-text--shimmer\", className].filter(Boolean).join(\" \")}\n data-tone={tone}\n {...rest}\n >\n {children}\n </Tag>\n );\n});\n","import { useRef } from \"react\";\nimport { LiquidMetal } from \"@paper-design/shaders-react\";\nimport { TONE_PARAMS, useInView, useMounted, useReducedMotion, useStaggeredMount, type MetalTone } from \"./metal\";\n\nexport interface MetalLogoProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Image URL (or data URI) with a transparent background — the metal flows inside its silhouette. */\n src: string;\n tone?: MetalTone;\n /** Rendered size in px (square by default). */\n size?: number;\n width?: number;\n height?: number;\n /** Shader animation speed (0 pauses). */\n speed?: number;\n}\n\n/**\n * Liquid metal poured into a logo — pass any image with a transparent\n * background and the metal flows inside its silhouette. The classic\n * liquid-metal treatment for marks, monograms, and icons.\n */\nexport function MetalLogo({ src, tone = \"silver\", size = 160, width, height, speed = 1, style, ...rest }: MetalLogoProps) {\n const ref = useRef<HTMLDivElement>(null);\n const mounted = useMounted();\n const inView = useInView(ref);\n const reduced = useReducedMotion();\n const turn = useStaggeredMount();\n const w = width ?? size;\n const h = height ?? size;\n const { colorBack: _drop, ...params } = TONE_PARAMS[tone];\n return (\n <div ref={ref} style={{ position: \"relative\", width: w, height: h, ...style }} {...rest}>\n {mounted && inView && turn && (\n <LiquidMetal\n key={src}\n image={src}\n suspendWhenProcessingImage={false}\n colorBack=\"#00000000\"\n fit=\"contain\"\n scale={0.92}\n speed={reduced ? 0 : speed}\n {...params}\n style={{ position: \"absolute\", inset: 0, width: \"100%\", height: \"100%\" }}\n />\n )}\n </div>\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { MetalLogo } from \"./logo\";\nimport type { MetalTone } from \"./metal\";\n\n/**\n * Liquid metal poured into an icon. Pass any SVG icon — a React element from\n * lucide-react / heroicons, a raw SVG string, or a URL — and it renders filled\n * with the liquid-metal shader (one WebGL canvas, gated to the viewport like\n * every metal surface). React icons are serialized from the DOM to a silhouette.\n */\nexport interface MetalIconProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, \"children\"> {\n /** A React SVG element, e.g. `<Beaker />` (lucide) or `<BeakerIcon />` (heroicons). */\n icon?: React.ReactNode;\n /** Raw SVG markup (alternative to `icon`). */\n svg?: string;\n /** SVG URL or data URI (alternative to `icon`). */\n src?: string;\n tone?: MetalTone;\n /** Rendered size in px (square). Defaults to `32`. */\n size?: number;\n /** Shader animation speed. */\n speed?: number;\n}\n\nfunction svgToUri(markup: string): string {\n return `data:image/svg+xml,${encodeURIComponent(markup)}`;\n}\n\nfunction serialize(svg: SVGElement): string {\n const clone = svg.cloneNode(true) as SVGElement;\n if (!clone.getAttribute(\"xmlns\")) clone.setAttribute(\"xmlns\", \"http://www.w3.org/2000/svg\");\n return svgToUri(new XMLSerializer().serializeToString(clone));\n}\n\n/** Resolve `svg`/`src`, or serialize the icon rendered into `ref`, to a data URI. */\nfunction useIconUri({ svg, src }: Pick<MetalIconProps, \"svg\" | \"src\">) {\n const ref = useRef<HTMLSpanElement>(null);\n const direct = src ?? (svg ? svgToUri(svg) : null);\n const [uri, setUri] = useState<string | null>(direct);\n useEffect(() => {\n if (direct) {\n setUri(direct);\n return;\n }\n const node = ref.current?.querySelector(\"svg\");\n if (!node) return;\n const next = serialize(node as unknown as SVGElement);\n // most icons are static — only re-set when the markup actually changes\n setUri((prev) => (prev === next ? prev : next));\n });\n return { ref, uri, fromNode: !direct };\n}\n\nexport function MetalIcon({ icon, svg, src, tone = \"silver\", size = 32, speed = 1, className, style, ...rest }: MetalIconProps) {\n const { ref, uri, fromNode } = useIconUri({ svg, src });\n const cls = [\"argent-icon-wrap\", className].filter(Boolean).join(\" \");\n return (\n <span className={cls} style={{ display: \"inline-flex\", width: size, height: size, ...style }} {...rest}>\n {fromNode && (\n <span ref={ref} aria-hidden=\"true\" style={{ position: \"absolute\", width: 0, height: 0, overflow: \"hidden\", color: \"#000\" }}>\n {icon}\n </span>\n )}\n {uri && <MetalLogo src={uri} tone={tone} size={size} speed={speed} />}\n </span>\n );\n}\n"],"mappings":"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","names":["import_react","import_jsx_runtime","Metal","MetalCard","MetalButton","import_react","import_jsx_runtime","MetalToggle","MetalProgress","MetalBadge","import_react","import_shaders_react","import_jsx_runtime","MetalText","import_react","import_shaders_react","import_jsx_runtime","import_react","import_jsx_runtime"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -191,6 +191,8 @@ interface MetalButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>
|
|
|
191
191
|
effect?: MetalEffect;
|
|
192
192
|
angle?: number;
|
|
193
193
|
halo?: boolean | number;
|
|
194
|
+
/** An icon (any SVG element) rendered before the label, in the label colour. */
|
|
195
|
+
icon?: React.ReactNode;
|
|
194
196
|
}
|
|
195
197
|
/** A liquid-metal button — readable at rest, molten on hover, with a stamped press. */
|
|
196
198
|
declare const MetalButton: react.ForwardRefExoticComponent<MetalButtonProps & react.RefAttributes<HTMLButtonElement>>;
|
|
@@ -232,9 +234,10 @@ interface MetalTextProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
232
234
|
shimmer?: boolean;
|
|
233
235
|
/**
|
|
234
236
|
* Pour the real liquid-metal shader into the glyphs — flowing bands, liquid
|
|
235
|
-
* edges, chromatic fringe.
|
|
236
|
-
* a placeholder until the shader is ready, and stands in
|
|
237
|
-
* isn't.
|
|
237
|
+
* edges, chromatic fringe. On by default (one WebGL canvas; the CSS chrome
|
|
238
|
+
* gradient renders as a placeholder until the shader is ready, and stands in
|
|
239
|
+
* wherever WebGL isn't). Set `shader={false}` for the pure-CSS gradient.
|
|
240
|
+
* Shader mode requires a plain string child; element children fall back to CSS.
|
|
238
241
|
*/
|
|
239
242
|
shader?: boolean;
|
|
240
243
|
/**
|
|
@@ -270,11 +273,11 @@ interface MetalTextProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
270
273
|
speed?: number;
|
|
271
274
|
}
|
|
272
275
|
/**
|
|
273
|
-
* Metal type. By default
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
276
|
+
* Metal type. By default the real liquid-metal shader is poured into the glyphs
|
|
277
|
+
* — `variant="fill"` floods them, `variant="outline"` runs the metal around
|
|
278
|
+
* their edges over a dark or gradient interior. The CSS chrome gradient stands
|
|
279
|
+
* in until the shader loads. Set `shader={false}` for the pure-CSS gradient
|
|
280
|
+
* (free at any scale); element children also fall back to it.
|
|
278
281
|
*/
|
|
279
282
|
declare const MetalText: react.ForwardRefExoticComponent<MetalTextProps & react.RefAttributes<HTMLElement>>;
|
|
280
283
|
|
|
@@ -296,6 +299,27 @@ interface MetalLogoProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
296
299
|
*/
|
|
297
300
|
declare function MetalLogo({ src, tone, size, width, height, speed, style, ...rest }: MetalLogoProps): react.JSX.Element;
|
|
298
301
|
|
|
302
|
+
/**
|
|
303
|
+
* Liquid metal poured into an icon. Pass any SVG icon — a React element from
|
|
304
|
+
* lucide-react / heroicons, a raw SVG string, or a URL — and it renders filled
|
|
305
|
+
* with the liquid-metal shader (one WebGL canvas, gated to the viewport like
|
|
306
|
+
* every metal surface). React icons are serialized from the DOM to a silhouette.
|
|
307
|
+
*/
|
|
308
|
+
interface MetalIconProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, "children"> {
|
|
309
|
+
/** A React SVG element, e.g. `<Beaker />` (lucide) or `<BeakerIcon />` (heroicons). */
|
|
310
|
+
icon?: React.ReactNode;
|
|
311
|
+
/** Raw SVG markup (alternative to `icon`). */
|
|
312
|
+
svg?: string;
|
|
313
|
+
/** SVG URL or data URI (alternative to `icon`). */
|
|
314
|
+
src?: string;
|
|
315
|
+
tone?: MetalTone;
|
|
316
|
+
/** Rendered size in px (square). Defaults to `32`. */
|
|
317
|
+
size?: number;
|
|
318
|
+
/** Shader animation speed. */
|
|
319
|
+
speed?: number;
|
|
320
|
+
}
|
|
321
|
+
declare function MetalIcon({ icon, svg, src, tone, size, speed, className, style, ...rest }: MetalIconProps): react.JSX.Element;
|
|
322
|
+
|
|
299
323
|
/**
|
|
300
324
|
* Tiny haptics for metal presses — `navigator.vibrate` where available
|
|
301
325
|
* (Android Chrome; iOS Safari ignores it). On by default, like Glacé.
|
|
@@ -303,4 +327,4 @@ declare function MetalLogo({ src, tone, size, width, height, speed, style, ...re
|
|
|
303
327
|
/** Globally enable/disable Argent haptics. */
|
|
304
328
|
declare function setHaptics(on: boolean): void;
|
|
305
329
|
|
|
306
|
-
export { EFFECTS, FINISHES, Metal, MetalBadge, type MetalBadgeProps, MetalButton, type MetalButtonProps, MetalCard, type MetalCardProps, type MetalEffect, type MetalEngine, MetalFill, type MetalFillProps, type MetalFinish, type MetalFrame, MetalLogo, type MetalLogoProps, type MetalMount, MetalProgress, type MetalProgressProps, type MetalProps, MetalText, type MetalTextProps, type MetalTextVariant, MetalToggle, type MetalToggleProps, type MetalTone, type MetalVariant, NATIVE_TONES, type NativeMetalParams, TONE_PARAMS, mountMetal, setHaptics, useInView, useMounted, useReducedMotion };
|
|
330
|
+
export { EFFECTS, FINISHES, Metal, MetalBadge, type MetalBadgeProps, MetalButton, type MetalButtonProps, MetalCard, type MetalCardProps, type MetalEffect, type MetalEngine, MetalFill, type MetalFillProps, type MetalFinish, type MetalFrame, MetalIcon, type MetalIconProps, MetalLogo, type MetalLogoProps, type MetalMount, MetalProgress, type MetalProgressProps, type MetalProps, MetalText, type MetalTextProps, type MetalTextVariant, MetalToggle, type MetalToggleProps, type MetalTone, type MetalVariant, NATIVE_TONES, type NativeMetalParams, TONE_PARAMS, mountMetal, setHaptics, useInView, useMounted, useReducedMotion };
|
package/dist/index.d.ts
CHANGED
|
@@ -191,6 +191,8 @@ interface MetalButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>
|
|
|
191
191
|
effect?: MetalEffect;
|
|
192
192
|
angle?: number;
|
|
193
193
|
halo?: boolean | number;
|
|
194
|
+
/** An icon (any SVG element) rendered before the label, in the label colour. */
|
|
195
|
+
icon?: React.ReactNode;
|
|
194
196
|
}
|
|
195
197
|
/** A liquid-metal button — readable at rest, molten on hover, with a stamped press. */
|
|
196
198
|
declare const MetalButton: react.ForwardRefExoticComponent<MetalButtonProps & react.RefAttributes<HTMLButtonElement>>;
|
|
@@ -232,9 +234,10 @@ interface MetalTextProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
232
234
|
shimmer?: boolean;
|
|
233
235
|
/**
|
|
234
236
|
* Pour the real liquid-metal shader into the glyphs — flowing bands, liquid
|
|
235
|
-
* edges, chromatic fringe.
|
|
236
|
-
* a placeholder until the shader is ready, and stands in
|
|
237
|
-
* isn't.
|
|
237
|
+
* edges, chromatic fringe. On by default (one WebGL canvas; the CSS chrome
|
|
238
|
+
* gradient renders as a placeholder until the shader is ready, and stands in
|
|
239
|
+
* wherever WebGL isn't). Set `shader={false}` for the pure-CSS gradient.
|
|
240
|
+
* Shader mode requires a plain string child; element children fall back to CSS.
|
|
238
241
|
*/
|
|
239
242
|
shader?: boolean;
|
|
240
243
|
/**
|
|
@@ -270,11 +273,11 @@ interface MetalTextProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
270
273
|
speed?: number;
|
|
271
274
|
}
|
|
272
275
|
/**
|
|
273
|
-
* Metal type. By default
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
276
|
+
* Metal type. By default the real liquid-metal shader is poured into the glyphs
|
|
277
|
+
* — `variant="fill"` floods them, `variant="outline"` runs the metal around
|
|
278
|
+
* their edges over a dark or gradient interior. The CSS chrome gradient stands
|
|
279
|
+
* in until the shader loads. Set `shader={false}` for the pure-CSS gradient
|
|
280
|
+
* (free at any scale); element children also fall back to it.
|
|
278
281
|
*/
|
|
279
282
|
declare const MetalText: react.ForwardRefExoticComponent<MetalTextProps & react.RefAttributes<HTMLElement>>;
|
|
280
283
|
|
|
@@ -296,6 +299,27 @@ interface MetalLogoProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
296
299
|
*/
|
|
297
300
|
declare function MetalLogo({ src, tone, size, width, height, speed, style, ...rest }: MetalLogoProps): react.JSX.Element;
|
|
298
301
|
|
|
302
|
+
/**
|
|
303
|
+
* Liquid metal poured into an icon. Pass any SVG icon — a React element from
|
|
304
|
+
* lucide-react / heroicons, a raw SVG string, or a URL — and it renders filled
|
|
305
|
+
* with the liquid-metal shader (one WebGL canvas, gated to the viewport like
|
|
306
|
+
* every metal surface). React icons are serialized from the DOM to a silhouette.
|
|
307
|
+
*/
|
|
308
|
+
interface MetalIconProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, "children"> {
|
|
309
|
+
/** A React SVG element, e.g. `<Beaker />` (lucide) or `<BeakerIcon />` (heroicons). */
|
|
310
|
+
icon?: React.ReactNode;
|
|
311
|
+
/** Raw SVG markup (alternative to `icon`). */
|
|
312
|
+
svg?: string;
|
|
313
|
+
/** SVG URL or data URI (alternative to `icon`). */
|
|
314
|
+
src?: string;
|
|
315
|
+
tone?: MetalTone;
|
|
316
|
+
/** Rendered size in px (square). Defaults to `32`. */
|
|
317
|
+
size?: number;
|
|
318
|
+
/** Shader animation speed. */
|
|
319
|
+
speed?: number;
|
|
320
|
+
}
|
|
321
|
+
declare function MetalIcon({ icon, svg, src, tone, size, speed, className, style, ...rest }: MetalIconProps): react.JSX.Element;
|
|
322
|
+
|
|
299
323
|
/**
|
|
300
324
|
* Tiny haptics for metal presses — `navigator.vibrate` where available
|
|
301
325
|
* (Android Chrome; iOS Safari ignores it). On by default, like Glacé.
|
|
@@ -303,4 +327,4 @@ declare function MetalLogo({ src, tone, size, width, height, speed, style, ...re
|
|
|
303
327
|
/** Globally enable/disable Argent haptics. */
|
|
304
328
|
declare function setHaptics(on: boolean): void;
|
|
305
329
|
|
|
306
|
-
export { EFFECTS, FINISHES, Metal, MetalBadge, type MetalBadgeProps, MetalButton, type MetalButtonProps, MetalCard, type MetalCardProps, type MetalEffect, type MetalEngine, MetalFill, type MetalFillProps, type MetalFinish, type MetalFrame, MetalLogo, type MetalLogoProps, type MetalMount, MetalProgress, type MetalProgressProps, type MetalProps, MetalText, type MetalTextProps, type MetalTextVariant, MetalToggle, type MetalToggleProps, type MetalTone, type MetalVariant, NATIVE_TONES, type NativeMetalParams, TONE_PARAMS, mountMetal, setHaptics, useInView, useMounted, useReducedMotion };
|
|
330
|
+
export { EFFECTS, FINISHES, Metal, MetalBadge, type MetalBadgeProps, MetalButton, type MetalButtonProps, MetalCard, type MetalCardProps, type MetalEffect, type MetalEngine, MetalFill, type MetalFillProps, type MetalFinish, type MetalFrame, MetalIcon, type MetalIconProps, MetalLogo, type MetalLogoProps, type MetalMount, MetalProgress, type MetalProgressProps, type MetalProps, MetalText, type MetalTextProps, type MetalTextVariant, MetalToggle, type MetalToggleProps, type MetalTone, type MetalVariant, NATIVE_TONES, type NativeMetalParams, TONE_PARAMS, mountMetal, setHaptics, useInView, useMounted, useReducedMotion };
|
package/dist/index.js
CHANGED
|
@@ -455,7 +455,7 @@ var MetalCard = forwardRef(function MetalCard2({ className, radius = 18, ...rest
|
|
|
455
455
|
return /* @__PURE__ */ jsx2(Metal, { ref, radius, className: cx("argent-card", className), ...rest });
|
|
456
456
|
});
|
|
457
457
|
var SIZE_RADIUS = { sm: 11, md: 13, lg: 15 };
|
|
458
|
-
var MetalButton = forwardRef(function MetalButton2({ tone = "silver", size = "md", variant = "border", radius, borderWidth = 1.5, revealOnHover = true, haptics = true, speed, engine, finish = "button", effect, angle, halo = false, type = "button", className, children, style, onPointerDown, ...rest }, ref) {
|
|
458
|
+
var MetalButton = forwardRef(function MetalButton2({ tone = "silver", size = "md", variant = "border", radius, borderWidth = 1.5, revealOnHover = true, haptics = true, speed, engine, finish = "button", effect, angle, halo = false, icon, type = "button", className, children, style, onPointerDown, ...rest }, ref) {
|
|
459
459
|
const border = variant === "border";
|
|
460
460
|
return /* @__PURE__ */ jsxs(
|
|
461
461
|
"button",
|
|
@@ -474,7 +474,10 @@ var MetalButton = forwardRef(function MetalButton2({ tone = "silver", size = "md
|
|
|
474
474
|
/* @__PURE__ */ jsx2("span", { className: "argent-fill", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(MetalFill, { tone, speed, engine, finish, effect, angle }) }),
|
|
475
475
|
border && /* @__PURE__ */ jsx2("span", { className: "argent-core", "aria-hidden": "true" }),
|
|
476
476
|
/* @__PURE__ */ jsx2("span", { className: "argent-sheen", "aria-hidden": "true" }),
|
|
477
|
-
/* @__PURE__ */
|
|
477
|
+
/* @__PURE__ */ jsxs("span", { className: "argent-content argent-btn-label", children: [
|
|
478
|
+
icon && /* @__PURE__ */ jsx2("span", { className: "argent-btn-icon", "aria-hidden": "true", children: icon }),
|
|
479
|
+
children
|
|
480
|
+
] })
|
|
478
481
|
]
|
|
479
482
|
}
|
|
480
483
|
);
|
|
@@ -695,7 +698,7 @@ var MetalText = forwardRef3(function MetalText2({
|
|
|
695
698
|
as,
|
|
696
699
|
tone = "silver",
|
|
697
700
|
shimmer = true,
|
|
698
|
-
shader =
|
|
701
|
+
shader = true,
|
|
699
702
|
variant = "fill",
|
|
700
703
|
fill = "#101114",
|
|
701
704
|
fillGradient,
|
|
@@ -709,7 +712,7 @@ var MetalText = forwardRef3(function MetalText2({
|
|
|
709
712
|
children,
|
|
710
713
|
...rest
|
|
711
714
|
}, ref) {
|
|
712
|
-
if (shader) {
|
|
715
|
+
if (shader && typeof children === "string") {
|
|
713
716
|
return /* @__PURE__ */ jsx4(
|
|
714
717
|
ShaderText,
|
|
715
718
|
{
|
|
@@ -771,6 +774,42 @@ function MetalLogo({ src, tone = "silver", size = 160, width, height, speed = 1,
|
|
|
771
774
|
src
|
|
772
775
|
) });
|
|
773
776
|
}
|
|
777
|
+
|
|
778
|
+
// src/icon.tsx
|
|
779
|
+
import { useEffect as useEffect3, useRef as useRef4, useState as useState4 } from "react";
|
|
780
|
+
import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
781
|
+
function svgToUri(markup) {
|
|
782
|
+
return `data:image/svg+xml,${encodeURIComponent(markup)}`;
|
|
783
|
+
}
|
|
784
|
+
function serialize(svg) {
|
|
785
|
+
const clone = svg.cloneNode(true);
|
|
786
|
+
if (!clone.getAttribute("xmlns")) clone.setAttribute("xmlns", "http://www.w3.org/2000/svg");
|
|
787
|
+
return svgToUri(new XMLSerializer().serializeToString(clone));
|
|
788
|
+
}
|
|
789
|
+
function useIconUri({ svg, src }) {
|
|
790
|
+
const ref = useRef4(null);
|
|
791
|
+
const direct = src ?? (svg ? svgToUri(svg) : null);
|
|
792
|
+
const [uri, setUri] = useState4(direct);
|
|
793
|
+
useEffect3(() => {
|
|
794
|
+
if (direct) {
|
|
795
|
+
setUri(direct);
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
798
|
+
const node = ref.current?.querySelector("svg");
|
|
799
|
+
if (!node) return;
|
|
800
|
+
const next = serialize(node);
|
|
801
|
+
setUri((prev) => prev === next ? prev : next);
|
|
802
|
+
});
|
|
803
|
+
return { ref, uri, fromNode: !direct };
|
|
804
|
+
}
|
|
805
|
+
function MetalIcon({ icon, svg, src, tone = "silver", size = 32, speed = 1, className, style, ...rest }) {
|
|
806
|
+
const { ref, uri, fromNode } = useIconUri({ svg, src });
|
|
807
|
+
const cls = ["argent-icon-wrap", className].filter(Boolean).join(" ");
|
|
808
|
+
return /* @__PURE__ */ jsxs3("span", { className: cls, style: { display: "inline-flex", width: size, height: size, ...style }, ...rest, children: [
|
|
809
|
+
fromNode && /* @__PURE__ */ jsx6("span", { ref, "aria-hidden": "true", style: { position: "absolute", width: 0, height: 0, overflow: "hidden", color: "#000" }, children: icon }),
|
|
810
|
+
uri && /* @__PURE__ */ jsx6(MetalLogo, { src: uri, tone, size, speed })
|
|
811
|
+
] });
|
|
812
|
+
}
|
|
774
813
|
export {
|
|
775
814
|
EFFECTS,
|
|
776
815
|
FINISHES,
|
|
@@ -779,6 +818,7 @@ export {
|
|
|
779
818
|
MetalButton,
|
|
780
819
|
MetalCard,
|
|
781
820
|
MetalFill,
|
|
821
|
+
MetalIcon,
|
|
782
822
|
MetalLogo,
|
|
783
823
|
MetalProgress,
|
|
784
824
|
MetalText,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/surfaces.tsx","../src/metal.tsx","../src/engine.ts","../src/haptics.ts","../src/controls.tsx","../src/text.tsx","../src/logo.tsx"],"sourcesContent":["import { forwardRef } from \"react\";\nimport { MetalFill, type MetalEffect, type MetalFinish, type MetalTone } from \"./metal\";\nimport type { MetalEngine } from \"./engine\";\nimport { PRESS_PATTERN, vibrate } from \"./haptics\";\n\nfunction cx(...parts: (string | false | undefined | null)[]): string {\n return parts.filter(Boolean).join(\" \");\n}\n\nfunction assignRef<T>(ref: React.ForwardedRef<T>, node: T | null) {\n if (typeof ref === \"function\") ref(node);\n else if (ref) ref.current = node;\n}\n\n/** Where the liquid metal shows: just the edge, or the whole surface. */\nexport type MetalVariant = \"border\" | \"fill\";\n\n/** Border framing: a single rim, or a rim plus an inner hairline frame. */\nexport type MetalFrame = \"single\" | \"double\";\n\ntype StyleVars = React.CSSProperties & Record<`--${string}`, string>;\n\nexport interface MetalProps extends React.HTMLAttributes<HTMLElement> {\n /** Element/component to render. Defaults to `div`. */\n as?: React.ElementType;\n /** Metal finish. */\n tone?: MetalTone;\n /** `\"border\"` (metal edge only, default) or `\"fill\"` (metal fills the surface). */\n variant?: MetalVariant;\n /** `\"single\"` rim (default) or `\"double\"` — rim plus an inner hairline frame. */\n frame?: MetalFrame;\n /** Let the metal show faintly through the interior panel (border variant). */\n tint?: boolean;\n /** Border thickness in px (border variant). */\n borderWidth?: number;\n /** Fill the whole surface with metal on hover (border variant). */\n revealOnHover?: boolean;\n /** Corner radius in px. */\n radius?: number;\n /** Shader animation speed (0 pauses the metal). */\n speed?: number;\n /** Pattern scale — higher spreads the reflection bands out. */\n metalScale?: number;\n /** Shader engine: Paper's LiquidMetal (default) or Argent's own. */\n engine?: MetalEngine;\n /** Shape-tuned shader preset. Defaults to `\"surface\"`. */\n finish?: MetalFinish;\n /** Motion character: flow, molten, ripple, chrome, or wave. */\n effect?: MetalEffect;\n /** Band direction in degrees — overrides the tone/finish default. */\n angle?: number;\n /** A specular streak that sweeps across on hover. */\n sheen?: boolean;\n /**\n * A frosted standoff ring outside the metal — a few px of backdrop blur\n * finished with a ~5% hairline. `true` for 8px, or a number for the ring\n * width. Theme the line with `--argent-halo-line`.\n */\n halo?: boolean | number;\n}\n\nfunction buildVars(radius: number, borderWidth: number, halo: boolean | number, style?: React.CSSProperties): StyleVars {\n const vars: StyleVars = {\n borderRadius: radius,\n \"--argent-bw\": `${borderWidth}px`,\n \"--argent-radius\": `${radius}px`,\n ...style,\n } as StyleVars;\n if (halo) vars[\"--argent-halo\"] = `${halo === true ? 8 : halo}px`;\n return vars;\n}\n\n/**\n * A liquid-metal surface powered by Paper's `LiquidMetal` shader. By default the\n * metal is just the edge; pass `variant=\"fill\"` for a full metal surface, or\n * `revealOnHover` to fill in on interaction. The base for every Argent component.\n */\nexport const Metal = forwardRef<HTMLElement, MetalProps>(function Metal(\n {\n as,\n tone = \"silver\",\n variant = \"border\",\n frame = \"single\",\n tint = false,\n borderWidth = 1.5,\n revealOnHover = false,\n radius = 14,\n speed,\n metalScale,\n engine,\n finish,\n effect,\n angle,\n sheen = false,\n halo = false,\n className,\n style,\n children,\n ...rest\n },\n ref,\n) {\n const Tag = (as ?? \"div\") as React.ElementType;\n const border = variant === \"border\";\n return (\n <Tag\n ref={(node: HTMLElement | null) => assignRef(ref, node)}\n className={cx(\n \"argent\",\n border ? \"argent--border\" : \"argent--fill\",\n border && frame === \"double\" && \"argent--double\",\n border && tint && \"argent--tint\",\n revealOnHover && \"argent--reveal\",\n sheen && \"argent--sheen\",\n !!halo && \"argent--halo\",\n className,\n )}\n data-tone={tone}\n style={buildVars(radius, borderWidth, halo, style)}\n {...rest}\n >\n <span className=\"argent-fill\" aria-hidden=\"true\">\n <MetalFill tone={tone} speed={speed} scale={metalScale} engine={engine} finish={finish} effect={effect} angle={angle} />\n </span>\n {border && <span className=\"argent-core\" aria-hidden=\"true\" />}\n {sheen && <span className=\"argent-sheen\" aria-hidden=\"true\" />}\n <span className=\"argent-content\">{children}</span>\n </Tag>\n );\n});\n\nexport interface MetalCardProps extends MetalProps {}\n\n/** A padded liquid-metal container. Metal edge by default. */\nexport const MetalCard = forwardRef<HTMLElement, MetalCardProps>(function MetalCard(\n { className, radius = 18, ...rest },\n ref,\n) {\n return <Metal ref={ref} radius={radius} className={cx(\"argent-card\", className)} {...rest} />;\n});\n\nexport interface MetalButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n tone?: MetalTone;\n size?: \"sm\" | \"md\" | \"lg\";\n /** `\"border\"` (default — readable, fills on hover) or `\"fill\"` (full chrome). */\n variant?: MetalVariant;\n /** Corner radius in px. */\n radius?: number;\n borderWidth?: number;\n /** Fill with metal on hover (border variant). Defaults to `true`. */\n revealOnHover?: boolean;\n /** Vibrate on press where supported. Defaults to `true`. */\n haptics?: boolean;\n speed?: number;\n engine?: MetalEngine;\n finish?: MetalFinish;\n effect?: MetalEffect;\n angle?: number;\n halo?: boolean | number;\n}\n\nconst SIZE_RADIUS = { sm: 11, md: 13, lg: 15 } as const;\n\n/** A liquid-metal button — readable at rest, molten on hover, with a stamped press. */\nexport const MetalButton = forwardRef<HTMLButtonElement, MetalButtonProps>(function MetalButton(\n { tone = \"silver\", size = \"md\", variant = \"border\", radius, borderWidth = 1.5, revealOnHover = true, haptics = true, speed, engine, finish = \"button\", effect, angle, halo = false, type = \"button\", className, children, style, onPointerDown, ...rest },\n ref,\n) {\n const border = variant === \"border\";\n return (\n <button\n ref={ref}\n type={type}\n onPointerDown={(e) => {\n if (haptics) vibrate(PRESS_PATTERN);\n onPointerDown?.(e);\n }}\n className={cx(\"argent\", border ? \"argent--border\" : \"argent--fill\", border && revealOnHover && \"argent--reveal\", \"argent--sheen\", !!halo && \"argent--halo\", \"argent-btn\", `argent-btn--${size}`, className)}\n data-tone={tone}\n style={buildVars(radius ?? SIZE_RADIUS[size], borderWidth, halo, style)}\n {...rest}\n >\n <span className=\"argent-fill\" aria-hidden=\"true\">\n <MetalFill tone={tone} speed={speed} engine={engine} finish={finish} effect={effect} angle={angle} />\n </span>\n {border && <span className=\"argent-core\" aria-hidden=\"true\" />}\n <span className=\"argent-sheen\" aria-hidden=\"true\" />\n <span className=\"argent-content argent-btn-label\">{children}</span>\n </button>\n );\n});\n","import { useEffect, useRef, useState } from \"react\";\nimport { LiquidMetal, type LiquidMetalParams } from \"@paper-design/shaders-react\";\nimport { mountMetal, NATIVE_TONES, type MetalEngine, type MetalMount, type NativeMetalParams } from \"./engine\";\n\n/**\n * The liquid-metal surface is Paper's `LiquidMetal` WebGL shader\n * (@paper-design/shaders) run with `shape=\"none\"` so it fills the whole element\n * instead of painting a blob. Each tone is a tuned set of shader params; the\n * canvas sits behind the content and is clipped to the surface's radius.\n *\n * `@paper-design/shaders-react` is a peer dependency — install it alongside\n * `argentui`. It is licensed under PolyForm Shield by Paper.\n */\n\nexport type MetalTone = \"silver\" | \"gold\" | \"gunmetal\" | \"obsidian\";\n\ntype Tuned = Pick<\n LiquidMetalParams,\n \"colorBack\" | \"colorTint\" | \"repetition\" | \"softness\" | \"shiftRed\" | \"shiftBlue\" | \"distortion\" | \"contour\" | \"angle\"\n>;\n\nexport const TONE_PARAMS: Record<MetalTone, Tuned> = {\n silver: {\n colorBack: \"#a7abb1\", colorTint: \"#ffffff\",\n repetition: 3, softness: 0.18, shiftRed: 0.32, shiftBlue: 0.32, distortion: 0.14, contour: 0.55, angle: 68,\n },\n gold: {\n colorBack: \"#94700e\", colorTint: \"#ffedb0\",\n repetition: 3, softness: 0.2, shiftRed: 0.3, shiftBlue: 0.12, distortion: 0.13, contour: 0.5, angle: 68,\n },\n gunmetal: {\n colorBack: \"#33373d\", colorTint: \"#b2bac4\",\n repetition: 2.6, softness: 0.26, shiftRed: 0.22, shiftBlue: 0.32, distortion: 0.1, contour: 0.45, angle: 80,\n },\n obsidian: {\n colorBack: \"#000000\", colorTint: \"#9498a6\",\n repetition: 2, softness: 0.4, shiftRed: 0.14, shiftBlue: 0.24, distortion: 0.07, contour: 0.32, angle: 92,\n },\n};\n\n// Paper's image pre-processing misbehaves when several image-mask shaders\n// initialise at once (only one survives) — serialise mounts a beat apart.\nlet imageMountQueue: Promise<void> = Promise.resolve();\nexport function useStaggeredMount(): boolean {\n const [go, setGo] = useState(false);\n useEffect(() => {\n let alive = true;\n imageMountQueue = imageMountQueue.then(async () => {\n if (!alive) return; // unmounted while queued — release the queue instantly\n setGo(true);\n await new Promise((r) => setTimeout(r, 300));\n });\n return () => {\n alive = false;\n };\n }, []);\n return go;\n}\n\n/** True once mounted on the client — the WebGL canvas can't render during SSR. */\nexport function useMounted(): boolean {\n const [m, setM] = useState(false);\n useEffect(() => setM(true), []);\n return m;\n}\n\n/** True when the user prefers reduced motion — the metal freezes (speed 0). */\nexport function useReducedMotion(): boolean {\n const [reduced, setReduced] = useState(false);\n useEffect(() => {\n const mq = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n setReduced(mq.matches);\n const onChange = (e: MediaQueryListEvent) => setReduced(e.matches);\n mq.addEventListener(\"change\", onChange);\n return () => mq.removeEventListener(\"change\", onChange);\n }, []);\n return reduced;\n}\n\n/**\n * Reports whether `ref` is on/near screen. Each metal surface is a WebGL\n * canvas, and browsers cap concurrent contexts (~16) — so we only mount the\n * shader while it's visible and release the context when it scrolls away.\n */\nexport function useInView(ref: React.RefObject<Element | null>, margin = \"250px\"): boolean {\n const [inView, setInView] = useState(false);\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n const io = new IntersectionObserver(([entry]) => setInView(entry.isIntersecting), { rootMargin: margin });\n io.observe(el);\n return () => io.disconnect();\n }, [ref, margin]);\n return inView;\n}\n\n/**\n * Finishes — shader presets tuned to the shape and size of the element. One\n * pattern does not fit all: a card wants broad flowing bands, a thin progress\n * bar wants many stripes crossing it, a 22px toggle thumb wants one soft\n * highlight like a ball bearing, and a hairline badge rim wants dense bands so\n * a tiny visible slice always catches some light.\n */\nexport type MetalFinish = \"surface\" | \"button\" | \"bar\" | \"orb\" | \"rim\";\n\ninterface FinishTuning {\n /** Band direction override (deg). */\n angle?: number;\n /** Random per-mount angle variation (±deg) so identical elements don't look cloned. */\n angleJitter?: number;\n repetition?: number;\n softness?: number;\n distortion?: number;\n /** Multiplier on the tone's chromatic shift. */\n shift?: number;\n /** Default pattern scale. */\n scale?: number;\n /** Multiplier on the animation speed. */\n speed?: number;\n}\n\nexport const FINISHES: Record<MetalFinish, FinishTuning> = {\n /** Cards, nav, panels — broad flowing reflection bands (the tone defaults). */\n surface: { scale: 1.1 },\n /** Buttons — slightly spread, calmer warp so labels stay readable. */\n button: { scale: 1.4, distortion: 0.1 },\n /** Thin horizontal strips (progress) — near-vertical stripes crossing the bar. */\n bar: { angle: 14, repetition: 5, softness: 0.3, distortion: 0.06, shift: 0.5, scale: 0.8, speed: 0.75 },\n /** Small round things (toggle thumbs) — one soft highlight, like a polished sphere. */\n orb: { angle: 112, angleJitter: 20, repetition: 1.7, softness: 0.5, distortion: 0.05, shift: 0.4, scale: 1.5 },\n /** Hairline edges (badges, thin borders) — dense bands so any slice sparkles. */\n rim: { angle: 40, repetition: 4.5, softness: 0.3, distortion: 0.08, shift: 0.5, scale: 0.85, speed: 0.85 },\n};\n\n/**\n * Effects — the character of the liquid's motion, independent of tone and\n * finish: how soft the bands are, how hard the noise churns them, how fast\n * everything moves.\n */\nexport type MetalEffect = \"flow\" | \"molten\" | \"ripple\" | \"chrome\" | \"wave\";\n\ninterface EffectTuning {\n angle?: number;\n repetition?: number;\n softness?: number;\n distortion?: number;\n /** Multiplier on chromatic shift. */\n shift?: number;\n /** Multiplier on animation speed. */\n speed?: number;\n}\n\nexport const EFFECTS: Record<MetalEffect, EffectTuning> = {\n /** The default — steady flowing reflection bands. */\n flow: {},\n /** Slow, heavy, half-melted — soft wide bands churning lazily. */\n molten: { softness: 0.5, distortion: 0.3, speed: 0.45, shift: 0.6 },\n /** Agitated surface — tighter bands, hard noise, quick motion. */\n ripple: { repetition: 4, softness: 0.24, distortion: 0.5, speed: 1.4 },\n /** Mirror-polished — crisp hard bands, strong chromatic fringe, calm. */\n chrome: { softness: 0.05, distortion: 0.05, shift: 1.6, speed: 0.8 },\n /** Horizontal swells rolling through the surface. */\n wave: { angle: 0, repetition: 5, softness: 0.36, distortion: 0.18, speed: 0.7 },\n};\n\nexport interface MetalFillProps {\n tone: MetalTone;\n /** Shader animation speed (0 pauses). */\n speed?: number;\n /** Pattern scale — higher spreads the bands out. Defaults per finish. */\n scale?: number;\n /** `\"paper\"` (Paper's LiquidMetal, default) or `\"native\"` (Argent's own shader). */\n engine?: MetalEngine;\n /** Shape-tuned shader preset. Defaults to `\"surface\"`. */\n finish?: MetalFinish;\n /** Motion character preset. Defaults to `\"flow\"`. */\n effect?: MetalEffect;\n /** Band direction in degrees — overrides the tone/finish default. */\n angle?: number;\n}\n\nconst FILL_STYLE: React.CSSProperties = { position: \"absolute\", inset: 0, width: \"100%\", height: \"100%\" };\n\n/** Argent's own clean-room shader on a plain canvas. */\nfunction NativeCanvas({ params }: { params: NativeMetalParams }) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const mountRef = useRef<MetalMount | null>(null);\n const initial = useRef(params);\n initial.current = params;\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n mountRef.current = mountMetal(canvas, initial.current);\n return () => {\n mountRef.current?.destroy();\n mountRef.current = null;\n };\n }, []);\n useEffect(() => {\n mountRef.current?.update(params);\n }, [params]);\n return <canvas ref={canvasRef} style={{ ...FILL_STYLE, display: \"block\" }} />;\n}\n\n/** The shader canvas, absolutely filling its positioned parent (when in view). */\nexport function MetalFill({ tone, speed = 1, scale, engine = \"paper\", finish = \"surface\", effect = \"flow\", angle }: MetalFillProps) {\n const ref = useRef<HTMLSpanElement>(null);\n const mounted = useMounted();\n const inView = useInView(ref);\n const reduced = useReducedMotion();\n const f = FINISHES[finish];\n const e = EFFECTS[effect];\n const [jitter] = useState(() => (f.angleJitter ? (Math.random() * 2 - 1) * f.angleJitter : 0));\n\n const base = TONE_PARAMS[tone];\n // precedence: explicit prop > effect > finish > tone\n const effAngle = (angle ?? e.angle ?? f.angle ?? base.angle ?? 70) + jitter;\n const effScale = scale ?? f.scale ?? 1.1;\n const effSpeed = (reduced ? 0 : speed) * (f.speed ?? 1) * (e.speed ?? 1);\n const shift = (f.shift ?? 1) * (e.shift ?? 1);\n const repetition = e.repetition ?? f.repetition ?? base.repetition;\n const softness = e.softness ?? f.softness ?? base.softness;\n const distortion = e.distortion ?? f.distortion ?? base.distortion;\n\n const native = NATIVE_TONES[tone];\n const nativeParams: NativeMetalParams = {\n ...native,\n angle: effAngle,\n repetition: repetition ?? native.repetition,\n softness: softness ?? native.softness,\n // the native warp amount runs ~3× paper's distortion scale\n distortion: distortion !== undefined ? distortion * 3 : native.distortion,\n dispersion: native.dispersion * shift,\n speed: effSpeed,\n scale: effScale,\n };\n\n return (\n <span ref={ref} aria-hidden=\"true\" style={{ position: \"absolute\", inset: 0 }}>\n {mounted && inView && (\n engine === \"native\" ? (\n <NativeCanvas params={nativeParams} />\n ) : (\n <LiquidMetal\n shape=\"none\"\n fit=\"cover\"\n scale={effScale}\n speed={effSpeed}\n {...base}\n angle={effAngle}\n repetition={repetition}\n softness={softness}\n distortion={distortion}\n shiftRed={(base.shiftRed ?? 0.3) * shift}\n shiftBlue={(base.shiftBlue ?? 0.3) * shift}\n style={FILL_STYLE}\n />\n )\n )}\n </span>\n );\n}\n","/**\n * Argent's own liquid-metal shader — a clean-room WebGL2 implementation of the\n * classic recipe: hard light→dark reflection banding, curvature-warped UVs,\n * time-driven simplex-noise flow, per-channel chromatic dispersion, and a rim\n * lift. No third-party shader code beyond the public-domain-style simplex\n * noise (Ashima Arts / Stefan Gustavson, MIT).\n *\n * Used when a surface sets `engine=\"native\"`; removes the need for\n * @paper-design/shaders-react entirely.\n */\n\nexport interface NativeMetalParams {\n /** Highlight band colour (hex). */\n light: string;\n /** Shadow band colour (hex). */\n dark: string;\n /** Stripe density. */\n repetition: number;\n /** Band direction in degrees. */\n angle: number;\n /** Band edge softness 0–1. */\n softness: number;\n /** Per-channel band offset (chromatic dispersion). */\n dispersion: number;\n /** Noise warp amount. */\n distortion: number;\n /** Animation speed (0 = still). */\n speed: number;\n /** Pattern scale — higher spreads the bands out. */\n scale: number;\n}\n\nexport type MetalEngine = \"paper\" | \"native\";\n\nconst VERT = `#version 300 es\nvoid main() {\n vec2 pos = vec2(float((gl_VertexID << 1) & 2), float(gl_VertexID & 2));\n gl_Position = vec4(pos * 2.0 - 1.0, 0.0, 1.0);\n}`;\n\nconst FRAG = `#version 300 es\nprecision highp float;\nuniform vec2 u_res;\nuniform float u_time;\nuniform vec3 u_light;\nuniform vec3 u_dark;\nuniform float u_rep;\nuniform float u_angle;\nuniform float u_soft;\nuniform float u_disp;\nuniform float u_dist;\nuniform float u_scale;\nout vec4 outColor;\n\n// 2D simplex noise — Ashima Arts / Stefan Gustavson (webgl-noise, MIT).\nvec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\nvec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\nvec3 permute(vec3 x) { return mod289(((x * 34.0) + 1.0) * x); }\nfloat snoise(vec2 v) {\n const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439);\n vec2 i = floor(v + dot(v, C.yy));\n vec2 x0 = v - i + dot(i, C.xx);\n vec2 i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n i = mod289(i);\n vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0)) + i.x + vec3(0.0, i1.x, 1.0));\n vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);\n m = m * m;\n m = m * m;\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n\n// One reflection band: a soft triangle wave over the warped coordinate.\nfloat stripe(float coord) {\n float f = fract(coord);\n float tri = abs(f * 2.0 - 1.0);\n return smoothstep(0.5 - u_soft, 0.5 + u_soft, tri);\n}\n\nvoid main() {\n vec2 uv = (gl_FragCoord.xy / u_res - 0.5);\n uv.x *= u_res.x / u_res.y;\n uv /= max(u_scale, 0.001);\n\n float t = u_time;\n\n // curvature: bands bend as if wrapping a bulged surface\n float d = length(uv);\n float bulge = 1.0 - 0.45 * d * d;\n\n // flowing warp — two noise octaves drifting at different rates\n float n = snoise(uv * 0.9 + vec2(0.0, -t * 0.28));\n n += 0.35 * snoise(uv * 1.8 + vec2(t * 0.1, -t * 0.45));\n\n // rotate so bands run along u_angle\n float c = cos(u_angle), s = sin(u_angle);\n vec2 ruv = mat2(c, -s, s, c) * uv;\n\n float coord = ruv.y * bulge * u_rep + n * u_dist * 2.2 - t * 0.22;\n\n // per-channel dispersion — the chrome fringing\n float r = stripe(coord + u_disp);\n float g = stripe(coord);\n float b = stripe(coord - u_disp);\n\n vec3 col = vec3(\n mix(u_dark.r, u_light.r, r),\n mix(u_dark.g, u_light.g, g),\n mix(u_dark.b, u_light.b, b)\n );\n\n // rim lift toward the edges\n col *= 0.94 + 0.14 * smoothstep(0.25, 0.85, d);\n\n outColor = vec4(col, 1.0);\n}`;\n\nfunction hexToRgb(hex: string): [number, number, number] {\n const h = hex.replace(\"#\", \"\");\n const v = h.length === 3 ? h.split(\"\").map((ch) => ch + ch).join(\"\") : h;\n const n = parseInt(v, 16);\n return [((n >> 16) & 255) / 255, ((n >> 8) & 255) / 255, (n & 255) / 255];\n}\n\nexport const NATIVE_TONES: Record<string, Omit<NativeMetalParams, \"speed\" | \"scale\">> = {\n silver: { light: \"#f8fafc\", dark: \"#23262b\", repetition: 1.8, angle: 68, softness: 0.34, dispersion: 0.03, distortion: 0.38 },\n gold: { light: \"#ffe9a8\", dark: \"#6e5408\", repetition: 1.8, angle: 68, softness: 0.34, dispersion: 0.028, distortion: 0.36 },\n gunmetal: { light: \"#b6bec9\", dark: \"#14161a\", repetition: 1.6, angle: 80, softness: 0.36, dispersion: 0.025, distortion: 0.34 },\n obsidian: { light: \"#787c88\", dark: \"#000000\", repetition: 1.4, angle: 92, softness: 0.42, dispersion: 0.02, distortion: 0.28 },\n};\n\nexport interface MetalMount {\n update(params: Partial<NativeMetalParams>): void;\n destroy(): void;\n}\n\nfunction compile(gl: WebGL2RenderingContext, type: number, src: string): WebGLShader | null {\n const sh = gl.createShader(type);\n if (!sh) return null;\n gl.shaderSource(sh, src);\n gl.compileShader(sh);\n if (!gl.getShaderParameter(sh, gl.COMPILE_STATUS)) {\n console.error(\"argent shader:\", gl.getShaderInfoLog(sh));\n gl.deleteShader(sh);\n return null;\n }\n return sh;\n}\n\n/** Mount the native liquid-metal shader on a canvas. Returns null without WebGL2. */\nexport function mountMetal(canvas: HTMLCanvasElement, params: NativeMetalParams): MetalMount | null {\n const gl = canvas.getContext(\"webgl2\", { antialias: true });\n if (!gl) return null;\n\n const vs = compile(gl, gl.VERTEX_SHADER, VERT);\n const fs = compile(gl, gl.FRAGMENT_SHADER, FRAG);\n if (!vs || !fs) return null;\n const prog = gl.createProgram()!;\n gl.attachShader(prog, vs);\n gl.attachShader(prog, fs);\n gl.linkProgram(prog);\n if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {\n console.error(\"argent shader link:\", gl.getProgramInfoLog(prog));\n return null;\n }\n gl.useProgram(prog);\n\n const U = (name: string) => gl.getUniformLocation(prog, name);\n const uRes = U(\"u_res\"), uTime = U(\"u_time\"), uLight = U(\"u_light\"), uDark = U(\"u_dark\");\n const uRep = U(\"u_rep\"), uAngle = U(\"u_angle\"), uSoft = U(\"u_soft\");\n const uDisp = U(\"u_disp\"), uDist = U(\"u_dist\"), uScale = U(\"u_scale\");\n\n let p = { ...params };\n let raf = 0;\n let tAcc = Math.random() * 40; // desync multiple surfaces\n let last = performance.now();\n let dead = false;\n\n function draw() {\n raf = 0;\n if (dead) return;\n const dpr = Math.min(window.devicePixelRatio || 1, 2);\n const w = Math.max(1, Math.round(canvas.clientWidth * dpr));\n const h = Math.max(1, Math.round(canvas.clientHeight * dpr));\n if (canvas.width !== w || canvas.height !== h) {\n canvas.width = w;\n canvas.height = h;\n gl!.viewport(0, 0, w, h);\n }\n const now = performance.now();\n tAcc += ((now - last) / 1000) * p.speed;\n last = now;\n\n gl!.uniform2f(uRes, w, h);\n gl!.uniform1f(uTime, tAcc);\n gl!.uniform3fv(uLight, hexToRgb(p.light));\n gl!.uniform3fv(uDark, hexToRgb(p.dark));\n gl!.uniform1f(uRep, p.repetition);\n gl!.uniform1f(uAngle, (p.angle * Math.PI) / 180);\n gl!.uniform1f(uSoft, Math.max(0.02, p.softness));\n gl!.uniform1f(uDisp, p.dispersion);\n gl!.uniform1f(uDist, p.distortion);\n gl!.uniform1f(uScale, p.scale);\n gl!.drawArrays(gl!.TRIANGLES, 0, 3);\n\n if (p.speed > 0) raf = requestAnimationFrame(draw);\n }\n draw();\n\n return {\n update(np) {\n p = { ...p, ...np };\n last = performance.now();\n if (!raf) raf = requestAnimationFrame(draw);\n },\n destroy() {\n dead = true;\n if (raf) cancelAnimationFrame(raf);\n gl.getExtension(\"WEBGL_lose_context\")?.loseContext();\n },\n };\n}\n","/**\n * Tiny haptics for metal presses — `navigator.vibrate` where available\n * (Android Chrome; iOS Safari ignores it). On by default, like Glacé.\n */\n\nlet enabled = true;\n\n/** Globally enable/disable Argent haptics. */\nexport function setHaptics(on: boolean) {\n enabled = on;\n}\n\nexport function vibrate(pattern: number | number[]) {\n if (!enabled || typeof navigator === \"undefined\" || !(\"vibrate\" in navigator)) return;\n try {\n navigator.vibrate(pattern);\n } catch {\n // some browsers throw on vibrate without user activation — fine to ignore\n }\n}\n\n/** The stamped-press click. */\nexport const PRESS_PATTERN = 8;\n","import { forwardRef, useState } from \"react\";\nimport { MetalFill, type MetalTone } from \"./metal\";\nimport { Metal, type MetalProps } from \"./surfaces\";\nimport { PRESS_PATTERN, vibrate } from \"./haptics\";\n\nexport interface MetalToggleProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"onChange\"> {\n tone?: MetalTone;\n checked?: boolean;\n defaultChecked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n /** Vibrate on toggle where supported. Defaults to `true`. */\n haptics?: boolean;\n}\n\n/**\n * A mercury switch — the thumb is a drop of liquid metal that slides (and\n * squishes) across a dark channel.\n */\nexport const MetalToggle = forwardRef<HTMLButtonElement, MetalToggleProps>(function MetalToggle(\n { tone = \"silver\", checked, defaultChecked = false, onCheckedChange, haptics = true, className, onClick, ...rest },\n ref,\n) {\n const [internal, setInternal] = useState(defaultChecked);\n const isOn = checked ?? internal;\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"switch\"\n aria-checked={isOn}\n data-tone={tone}\n data-checked={isOn || undefined}\n className={[\"argent-toggle\", className].filter(Boolean).join(\" \")}\n onClick={(e) => {\n if (haptics) vibrate(PRESS_PATTERN);\n if (checked === undefined) setInternal(!isOn);\n onCheckedChange?.(!isOn);\n onClick?.(e);\n }}\n {...rest}\n >\n <span className=\"argent-toggle-thumb\" aria-hidden=\"true\">\n <MetalFill tone={tone} finish=\"orb\" />\n </span>\n </button>\n );\n});\n\nexport interface MetalProgressProps extends React.HTMLAttributes<HTMLDivElement> {\n tone?: MetalTone;\n /** 0–100. Omit for an indeterminate molten sweep. */\n value?: number;\n /** Track height in px. */\n height?: number;\n}\n\n/** A molten progress bar — liquid metal rising in a dark channel. */\nexport const MetalProgress = forwardRef<HTMLDivElement, MetalProgressProps>(function MetalProgress(\n { tone = \"silver\", value, height = 10, className, style, ...rest },\n ref,\n) {\n const indeterminate = value === undefined;\n const clamped = indeterminate ? 0 : Math.max(0, Math.min(100, value));\n return (\n <div\n ref={ref}\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={indeterminate ? undefined : clamped}\n data-tone={tone}\n className={[\"argent-progress\", indeterminate && \"argent-progress--indeterminate\", className].filter(Boolean).join(\" \")}\n style={{ height, ...style }}\n {...rest}\n >\n <span\n className=\"argent-progress-fill\"\n style={indeterminate ? undefined : { width: `${clamped}%` }}\n aria-hidden=\"true\"\n >\n <MetalFill tone={tone} finish=\"bar\" />\n </span>\n </div>\n );\n});\n\nexport interface MetalBadgeProps extends Omit<MetalProps, \"as\" | \"variant\"> {}\n\n/** A small liquid-metal pill — a metal rim around a quiet label. */\nexport const MetalBadge = forwardRef<HTMLElement, MetalBadgeProps>(function MetalBadge(\n { className, radius = 999, borderWidth = 1, finish = \"rim\", ...rest },\n ref,\n) {\n return (\n <Metal\n ref={ref}\n as=\"span\"\n variant=\"border\"\n radius={radius}\n borderWidth={borderWidth}\n finish={finish}\n className={[\"argent-badge\", className].filter(Boolean).join(\" \")}\n {...rest}\n />\n );\n});\n","import { forwardRef, useEffect, useRef, useState } from \"react\";\nimport { LiquidMetal } from \"@paper-design/shaders-react\";\nimport { TONE_PARAMS, useInView, useMounted, useReducedMotion, useStaggeredMount, type MetalTone } from \"./metal\";\n\n/** Where the metal lives in shader text: the whole glyph, or just its edge. */\nexport type MetalTextVariant = \"fill\" | \"outline\";\n\nexport interface MetalTextProps extends React.HTMLAttributes<HTMLElement> {\n /** Element to render. Defaults to `span`. */\n as?: React.ElementType;\n tone?: MetalTone;\n /** Animate the highlight band across the glyphs (CSS mode). Defaults to `true`. */\n shimmer?: boolean;\n /**\n * Pour the real liquid-metal shader into the glyphs — flowing bands, liquid\n * edges, chromatic fringe. Costs a WebGL canvas; the CSS gradient renders as\n * a placeholder until the shader is ready, and stands in wherever WebGL\n * isn't. Children must be a plain string in this mode.\n */\n shader?: boolean;\n /**\n * Shader mode: `\"fill\"` (metal fills the glyphs, default) or `\"outline\"` —\n * the metal runs around the edge of each letterform and the interior takes\n * `fill` / `fillGradient`.\n */\n variant?: MetalTextVariant;\n /** Interior colour for `variant=\"outline\"`. */\n fill?: string;\n /** Interior vertical gradient `[top, bottom]` for `variant=\"outline\"` — wins over `fill`. */\n fillGradient?: [string, string];\n /** Metal edge thickness in px for `variant=\"outline\"`. Defaults to ~5% of the font size. */\n outlineWidth?: number;\n /** Type size in px (shader mode). Defaults to `64`. */\n fontSize?: number;\n /** Weight for the glyph silhouette (shader mode). Defaults to `800`. */\n fontWeight?: number;\n /**\n * Font for the silhouette (shader mode). Rendered inside an SVG image, which\n * sees system fonts only — to use a webfont, pass `fontCss` with a\n * data-URI @font-face for the same family.\n */\n fontFamily?: string;\n /**\n * Raw CSS embedded in the glyph SVG (shader mode) — typically a @font-face\n * whose `src` is a data: URI, which lets webfonts (e.g. Google Fonts) render\n * inside the silhouette. Load the same face into `document.fonts` so the\n * width measurement matches.\n */\n fontCss?: string;\n /** Shader animation speed (0 pauses). */\n speed?: number;\n}\n\nconst DEFAULT_STACK = \"-apple-system, 'Helvetica Neue', Helvetica, Arial, sans-serif\";\n\ninterface GlyphGeom {\n text: string;\n w: number;\n h: number;\n fontSize: number;\n fontWeight: number;\n fontFamily: string;\n fontCss?: string;\n}\n\nfunction svgOpen(g: GlyphGeom): string {\n const style = g.fontCss ? `<style>${g.fontCss}</style>` : \"\";\n return `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 ${g.w} ${g.h}' width='${g.w}' height='${g.h}'>${style}`;\n}\n\nfunction svgText(g: GlyphGeom, attrs: string): string {\n const safe = g.text.replace(/&/g, \"&\").replace(/</g, \"<\");\n return `<text x='50%' y='${Math.round(g.fontSize * 1.0)}' font-size='${g.fontSize}' font-family=\"${g.fontFamily.replace(/\"/g, \"'\")}\" font-weight='${g.fontWeight}' text-anchor='middle' ${attrs}>${safe}</text>`;\n}\n\nfunction encode(svg: string): string {\n return `data:image/svg+xml,${encodeURIComponent(svg)}`;\n}\n\n/** Solid glyphs — the shader fills the whole letterform. */\nfunction fillSilhouette(g: GlyphGeom): string {\n return encode(`${svgOpen(g)}${svgText(g, \"fill='#000'\")}</svg>`);\n}\n\n/** Stroke-only glyphs — the shader flows in a ring around each letterform. */\nfunction outlineSilhouette(g: GlyphGeom, ow: number): string {\n return encode(`${svgOpen(g)}${svgText(g, `fill='none' stroke='#000' stroke-width='${ow}' stroke-linejoin='round'`)}</svg>`);\n}\n\n/** The interior of outline text — flat or gradient fill, geometry-identical to the silhouette. */\nfunction interior(g: GlyphGeom, fill: string, gradient?: [string, string]): string {\n if (!gradient) return encode(`${svgOpen(g)}${svgText(g, `fill='${fill}'`)}</svg>`);\n const defs = `<defs><linearGradient id='g' x1='0' y1='0' x2='0' y2='1'><stop offset='0' stop-color='${gradient[0]}'/><stop offset='1' stop-color='${gradient[1]}'/></linearGradient></defs>`;\n return encode(`${svgOpen(g)}${defs}${svgText(g, \"fill='url(#g)'\")}</svg>`);\n}\n\nconst LAYER: React.CSSProperties = { position: \"absolute\", inset: 0, width: \"100%\", height: \"100%\" };\n\nfunction ShaderText({\n text,\n tone,\n variant,\n fill,\n fillGradient,\n outlineWidth,\n fontSize,\n fontWeight,\n fontFamily,\n fontCss,\n speed,\n shimmer,\n className,\n style,\n ...rest\n}: {\n text: string;\n tone: MetalTone;\n variant: MetalTextVariant;\n fill: string;\n fillGradient?: [string, string];\n outlineWidth?: number;\n fontSize: number;\n fontWeight: number;\n fontFamily: string;\n fontCss?: string;\n speed: number;\n shimmer: boolean;\n} & React.HTMLAttributes<HTMLElement>) {\n const ref = useRef<HTMLSpanElement>(null);\n const mounted = useMounted();\n const inView = useInView(ref);\n const reduced = useReducedMotion();\n const turn = useStaggeredMount();\n const [geom, setGeom] = useState<GlyphGeom | null>(null);\n\n const outlined = variant === \"outline\";\n const ow = outlineWidth ?? Math.max(2, Math.round(fontSize * 0.05));\n\n useEffect(() => {\n let alive = true;\n const fontSpec = `${fontWeight} ${fontSize}px ${fontFamily}`;\n const measure = () => {\n if (!alive) return;\n const ctx = document.createElement(\"canvas\").getContext(\"2d\");\n if (!ctx) return;\n ctx.font = fontSpec;\n const m = ctx.measureText(text);\n setGeom({\n text,\n w: Math.ceil(m.width + fontSize * 0.24 + ow * 2),\n h: Math.ceil(fontSize * 1.3 + ow),\n fontSize,\n fontWeight,\n fontFamily,\n fontCss,\n });\n };\n // wait for webfonts so the measured width matches the silhouette\n if (document.fonts?.load) document.fonts.load(fontSpec, text).then(measure, measure);\n else measure();\n return () => {\n alive = false;\n };\n }, [text, fontSize, fontWeight, fontFamily, fontCss, ow]);\n\n const ready = mounted && inView && turn && geom;\n const { colorBack: _drop, ...params } = TONE_PARAMS[tone];\n // a thin ring can't survive heavy edge distortion — calm it down for outlines\n const shaderParams = outlined ? { ...params, contour: 0.2, distortion: Math.min(params.distortion ?? 0.1, 0.08) } : params;\n\n return (\n <span\n ref={ref}\n role=\"img\"\n aria-label={text}\n className={className}\n style={{\n position: \"relative\",\n display: \"inline-block\",\n verticalAlign: \"middle\",\n width: geom?.w,\n height: geom?.h,\n ...style,\n }}\n {...rest}\n >\n {ready ? (\n <>\n {outlined && <img src={interior(geom, fill, fillGradient)} alt=\"\" aria-hidden=\"true\" style={LAYER} />}\n <LiquidMetal\n // keyed by silhouette: rapid prop changes can finish processing\n // out of order and leave stale glyphs — a clean re-init can't\n key={`${geom.text}|${geom.fontFamily}|${geom.w}|${outlined ? \"o\" : \"f\"}`}\n image={outlined ? outlineSilhouette(geom, ow) : fillSilhouette(geom)}\n suspendWhenProcessingImage={false}\n colorBack=\"#00000000\"\n fit=\"contain\"\n scale={0.97}\n speed={reduced ? 0 : speed}\n {...shaderParams}\n style={LAYER}\n />\n </>\n ) : (\n // CSS chrome stands in until the shader is ready (and during SSR)\n <span\n aria-hidden=\"true\"\n className={[\"argent-text\", shimmer && !outlined && \"argent-text--shimmer\"].filter(Boolean).join(\" \")}\n data-tone={tone}\n style={{\n fontSize,\n fontWeight,\n fontFamily,\n lineHeight: 1.3,\n whiteSpace: \"nowrap\",\n ...(outlined && {\n background: \"none\",\n WebkitTextFillColor: fillGradient?.[0] ?? fill,\n color: fillGradient?.[0] ?? fill,\n WebkitTextStroke: \"1px rgba(220, 224, 230, 0.55)\",\n }),\n }}\n >\n {text}\n </span>\n )}\n </span>\n );\n}\n\n/**\n * Metal type. By default a chrome gradient clipped to the glyphs with a flowing\n * shimmer — pure CSS, use it freely at any scale. Pass `shader` to pour the\n * real liquid-metal shader into the letterforms — `variant=\"fill\"` floods the\n * glyphs; `variant=\"outline\"` runs the metal around their edges over a dark or\n * gradient interior.\n */\nexport const MetalText = forwardRef<HTMLElement, MetalTextProps>(function MetalText(\n {\n as,\n tone = \"silver\",\n shimmer = true,\n shader = false,\n variant = \"fill\",\n fill = \"#101114\",\n fillGradient,\n outlineWidth,\n fontSize = 64,\n fontWeight = 800,\n fontFamily = DEFAULT_STACK,\n fontCss,\n speed = 1,\n className,\n children,\n ...rest\n },\n ref,\n) {\n if (shader) {\n return (\n <ShaderText\n text={String(children)}\n tone={tone}\n variant={variant}\n fill={fill}\n fillGradient={fillGradient}\n outlineWidth={outlineWidth}\n fontSize={fontSize}\n fontWeight={fontWeight}\n fontFamily={fontFamily}\n fontCss={fontCss}\n speed={speed}\n shimmer={shimmer}\n className={className}\n {...rest}\n />\n );\n }\n const Tag = (as ?? \"span\") as React.ElementType;\n return (\n <Tag\n ref={ref}\n className={[\"argent-text\", shimmer && \"argent-text--shimmer\", className].filter(Boolean).join(\" \")}\n data-tone={tone}\n {...rest}\n >\n {children}\n </Tag>\n );\n});\n","import { useRef } from \"react\";\nimport { LiquidMetal } from \"@paper-design/shaders-react\";\nimport { TONE_PARAMS, useInView, useMounted, useReducedMotion, useStaggeredMount, type MetalTone } from \"./metal\";\n\nexport interface MetalLogoProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Image URL (or data URI) with a transparent background — the metal flows inside its silhouette. */\n src: string;\n tone?: MetalTone;\n /** Rendered size in px (square by default). */\n size?: number;\n width?: number;\n height?: number;\n /** Shader animation speed (0 pauses). */\n speed?: number;\n}\n\n/**\n * Liquid metal poured into a logo — pass any image with a transparent\n * background and the metal flows inside its silhouette. The classic\n * liquid-metal treatment for marks, monograms, and icons.\n */\nexport function MetalLogo({ src, tone = \"silver\", size = 160, width, height, speed = 1, style, ...rest }: MetalLogoProps) {\n const ref = useRef<HTMLDivElement>(null);\n const mounted = useMounted();\n const inView = useInView(ref);\n const reduced = useReducedMotion();\n const turn = useStaggeredMount();\n const w = width ?? size;\n const h = height ?? size;\n const { colorBack: _drop, ...params } = TONE_PARAMS[tone];\n return (\n <div ref={ref} style={{ position: \"relative\", width: w, height: h, ...style }} {...rest}>\n {mounted && inView && turn && (\n <LiquidMetal\n key={src}\n image={src}\n suspendWhenProcessingImage={false}\n colorBack=\"#00000000\"\n fit=\"contain\"\n scale={0.92}\n speed={reduced ? 0 : speed}\n {...params}\n style={{ position: \"absolute\", inset: 0, width: \"100%\", height: \"100%\" }}\n />\n )}\n </div>\n );\n}\n"],"mappings":"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","names":["jsx","Metal","MetalCard","MetalButton","forwardRef","useState","jsx","forwardRef","MetalToggle","useState","MetalProgress","MetalBadge","forwardRef","useEffect","useRef","useState","LiquidMetal","jsx","jsxs","useRef","useState","useEffect","LiquidMetal","forwardRef","MetalText","useRef","LiquidMetal","jsx","useRef","LiquidMetal"]}
|
|
1
|
+
{"version":3,"sources":["../src/surfaces.tsx","../src/metal.tsx","../src/engine.ts","../src/haptics.ts","../src/controls.tsx","../src/text.tsx","../src/logo.tsx","../src/icon.tsx"],"sourcesContent":["import { forwardRef } from \"react\";\nimport { MetalFill, type MetalEffect, type MetalFinish, type MetalTone } from \"./metal\";\nimport type { MetalEngine } from \"./engine\";\nimport { PRESS_PATTERN, vibrate } from \"./haptics\";\n\nfunction cx(...parts: (string | false | undefined | null)[]): string {\n return parts.filter(Boolean).join(\" \");\n}\n\nfunction assignRef<T>(ref: React.ForwardedRef<T>, node: T | null) {\n if (typeof ref === \"function\") ref(node);\n else if (ref) ref.current = node;\n}\n\n/** Where the liquid metal shows: just the edge, or the whole surface. */\nexport type MetalVariant = \"border\" | \"fill\";\n\n/** Border framing: a single rim, or a rim plus an inner hairline frame. */\nexport type MetalFrame = \"single\" | \"double\";\n\ntype StyleVars = React.CSSProperties & Record<`--${string}`, string>;\n\nexport interface MetalProps extends React.HTMLAttributes<HTMLElement> {\n /** Element/component to render. Defaults to `div`. */\n as?: React.ElementType;\n /** Metal finish. */\n tone?: MetalTone;\n /** `\"border\"` (metal edge only, default) or `\"fill\"` (metal fills the surface). */\n variant?: MetalVariant;\n /** `\"single\"` rim (default) or `\"double\"` — rim plus an inner hairline frame. */\n frame?: MetalFrame;\n /** Let the metal show faintly through the interior panel (border variant). */\n tint?: boolean;\n /** Border thickness in px (border variant). */\n borderWidth?: number;\n /** Fill the whole surface with metal on hover (border variant). */\n revealOnHover?: boolean;\n /** Corner radius in px. */\n radius?: number;\n /** Shader animation speed (0 pauses the metal). */\n speed?: number;\n /** Pattern scale — higher spreads the reflection bands out. */\n metalScale?: number;\n /** Shader engine: Paper's LiquidMetal (default) or Argent's own. */\n engine?: MetalEngine;\n /** Shape-tuned shader preset. Defaults to `\"surface\"`. */\n finish?: MetalFinish;\n /** Motion character: flow, molten, ripple, chrome, or wave. */\n effect?: MetalEffect;\n /** Band direction in degrees — overrides the tone/finish default. */\n angle?: number;\n /** A specular streak that sweeps across on hover. */\n sheen?: boolean;\n /**\n * A frosted standoff ring outside the metal — a few px of backdrop blur\n * finished with a ~5% hairline. `true` for 8px, or a number for the ring\n * width. Theme the line with `--argent-halo-line`.\n */\n halo?: boolean | number;\n}\n\nfunction buildVars(radius: number, borderWidth: number, halo: boolean | number, style?: React.CSSProperties): StyleVars {\n const vars: StyleVars = {\n borderRadius: radius,\n \"--argent-bw\": `${borderWidth}px`,\n \"--argent-radius\": `${radius}px`,\n ...style,\n } as StyleVars;\n if (halo) vars[\"--argent-halo\"] = `${halo === true ? 8 : halo}px`;\n return vars;\n}\n\n/**\n * A liquid-metal surface powered by Paper's `LiquidMetal` shader. By default the\n * metal is just the edge; pass `variant=\"fill\"` for a full metal surface, or\n * `revealOnHover` to fill in on interaction. The base for every Argent component.\n */\nexport const Metal = forwardRef<HTMLElement, MetalProps>(function Metal(\n {\n as,\n tone = \"silver\",\n variant = \"border\",\n frame = \"single\",\n tint = false,\n borderWidth = 1.5,\n revealOnHover = false,\n radius = 14,\n speed,\n metalScale,\n engine,\n finish,\n effect,\n angle,\n sheen = false,\n halo = false,\n className,\n style,\n children,\n ...rest\n },\n ref,\n) {\n const Tag = (as ?? \"div\") as React.ElementType;\n const border = variant === \"border\";\n return (\n <Tag\n ref={(node: HTMLElement | null) => assignRef(ref, node)}\n className={cx(\n \"argent\",\n border ? \"argent--border\" : \"argent--fill\",\n border && frame === \"double\" && \"argent--double\",\n border && tint && \"argent--tint\",\n revealOnHover && \"argent--reveal\",\n sheen && \"argent--sheen\",\n !!halo && \"argent--halo\",\n className,\n )}\n data-tone={tone}\n style={buildVars(radius, borderWidth, halo, style)}\n {...rest}\n >\n <span className=\"argent-fill\" aria-hidden=\"true\">\n <MetalFill tone={tone} speed={speed} scale={metalScale} engine={engine} finish={finish} effect={effect} angle={angle} />\n </span>\n {border && <span className=\"argent-core\" aria-hidden=\"true\" />}\n {sheen && <span className=\"argent-sheen\" aria-hidden=\"true\" />}\n <span className=\"argent-content\">{children}</span>\n </Tag>\n );\n});\n\nexport interface MetalCardProps extends MetalProps {}\n\n/** A padded liquid-metal container. Metal edge by default. */\nexport const MetalCard = forwardRef<HTMLElement, MetalCardProps>(function MetalCard(\n { className, radius = 18, ...rest },\n ref,\n) {\n return <Metal ref={ref} radius={radius} className={cx(\"argent-card\", className)} {...rest} />;\n});\n\nexport interface MetalButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n tone?: MetalTone;\n size?: \"sm\" | \"md\" | \"lg\";\n /** `\"border\"` (default — readable, fills on hover) or `\"fill\"` (full chrome). */\n variant?: MetalVariant;\n /** Corner radius in px. */\n radius?: number;\n borderWidth?: number;\n /** Fill with metal on hover (border variant). Defaults to `true`. */\n revealOnHover?: boolean;\n /** Vibrate on press where supported. Defaults to `true`. */\n haptics?: boolean;\n speed?: number;\n engine?: MetalEngine;\n finish?: MetalFinish;\n effect?: MetalEffect;\n angle?: number;\n halo?: boolean | number;\n /** An icon (any SVG element) rendered before the label, in the label colour. */\n icon?: React.ReactNode;\n}\n\nconst SIZE_RADIUS = { sm: 11, md: 13, lg: 15 } as const;\n\n/** A liquid-metal button — readable at rest, molten on hover, with a stamped press. */\nexport const MetalButton = forwardRef<HTMLButtonElement, MetalButtonProps>(function MetalButton(\n { tone = \"silver\", size = \"md\", variant = \"border\", radius, borderWidth = 1.5, revealOnHover = true, haptics = true, speed, engine, finish = \"button\", effect, angle, halo = false, icon, type = \"button\", className, children, style, onPointerDown, ...rest },\n ref,\n) {\n const border = variant === \"border\";\n return (\n <button\n ref={ref}\n type={type}\n onPointerDown={(e) => {\n if (haptics) vibrate(PRESS_PATTERN);\n onPointerDown?.(e);\n }}\n className={cx(\"argent\", border ? \"argent--border\" : \"argent--fill\", border && revealOnHover && \"argent--reveal\", \"argent--sheen\", !!halo && \"argent--halo\", \"argent-btn\", `argent-btn--${size}`, className)}\n data-tone={tone}\n style={buildVars(radius ?? SIZE_RADIUS[size], borderWidth, halo, style)}\n {...rest}\n >\n <span className=\"argent-fill\" aria-hidden=\"true\">\n <MetalFill tone={tone} speed={speed} engine={engine} finish={finish} effect={effect} angle={angle} />\n </span>\n {border && <span className=\"argent-core\" aria-hidden=\"true\" />}\n <span className=\"argent-sheen\" aria-hidden=\"true\" />\n <span className=\"argent-content argent-btn-label\">\n {icon && <span className=\"argent-btn-icon\" aria-hidden=\"true\">{icon}</span>}\n {children}\n </span>\n </button>\n );\n});\n","import { useEffect, useRef, useState } from \"react\";\nimport { LiquidMetal, type LiquidMetalParams } from \"@paper-design/shaders-react\";\nimport { mountMetal, NATIVE_TONES, type MetalEngine, type MetalMount, type NativeMetalParams } from \"./engine\";\n\n/**\n * The liquid-metal surface is Paper's `LiquidMetal` WebGL shader\n * (@paper-design/shaders) run with `shape=\"none\"` so it fills the whole element\n * instead of painting a blob. Each tone is a tuned set of shader params; the\n * canvas sits behind the content and is clipped to the surface's radius.\n *\n * `@paper-design/shaders-react` is a peer dependency — install it alongside\n * `argentui`. It is licensed under PolyForm Shield by Paper.\n */\n\nexport type MetalTone = \"silver\" | \"gold\" | \"gunmetal\" | \"obsidian\";\n\ntype Tuned = Pick<\n LiquidMetalParams,\n \"colorBack\" | \"colorTint\" | \"repetition\" | \"softness\" | \"shiftRed\" | \"shiftBlue\" | \"distortion\" | \"contour\" | \"angle\"\n>;\n\nexport const TONE_PARAMS: Record<MetalTone, Tuned> = {\n silver: {\n colorBack: \"#a7abb1\", colorTint: \"#ffffff\",\n repetition: 3, softness: 0.18, shiftRed: 0.32, shiftBlue: 0.32, distortion: 0.14, contour: 0.55, angle: 68,\n },\n gold: {\n colorBack: \"#94700e\", colorTint: \"#ffedb0\",\n repetition: 3, softness: 0.2, shiftRed: 0.3, shiftBlue: 0.12, distortion: 0.13, contour: 0.5, angle: 68,\n },\n gunmetal: {\n colorBack: \"#33373d\", colorTint: \"#b2bac4\",\n repetition: 2.6, softness: 0.26, shiftRed: 0.22, shiftBlue: 0.32, distortion: 0.1, contour: 0.45, angle: 80,\n },\n obsidian: {\n colorBack: \"#000000\", colorTint: \"#9498a6\",\n repetition: 2, softness: 0.4, shiftRed: 0.14, shiftBlue: 0.24, distortion: 0.07, contour: 0.32, angle: 92,\n },\n};\n\n// Paper's image pre-processing misbehaves when several image-mask shaders\n// initialise at once (only one survives) — serialise mounts a beat apart.\nlet imageMountQueue: Promise<void> = Promise.resolve();\nexport function useStaggeredMount(): boolean {\n const [go, setGo] = useState(false);\n useEffect(() => {\n let alive = true;\n imageMountQueue = imageMountQueue.then(async () => {\n if (!alive) return; // unmounted while queued — release the queue instantly\n setGo(true);\n await new Promise((r) => setTimeout(r, 300));\n });\n return () => {\n alive = false;\n };\n }, []);\n return go;\n}\n\n/** True once mounted on the client — the WebGL canvas can't render during SSR. */\nexport function useMounted(): boolean {\n const [m, setM] = useState(false);\n useEffect(() => setM(true), []);\n return m;\n}\n\n/** True when the user prefers reduced motion — the metal freezes (speed 0). */\nexport function useReducedMotion(): boolean {\n const [reduced, setReduced] = useState(false);\n useEffect(() => {\n const mq = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n setReduced(mq.matches);\n const onChange = (e: MediaQueryListEvent) => setReduced(e.matches);\n mq.addEventListener(\"change\", onChange);\n return () => mq.removeEventListener(\"change\", onChange);\n }, []);\n return reduced;\n}\n\n/**\n * Reports whether `ref` is on/near screen. Each metal surface is a WebGL\n * canvas, and browsers cap concurrent contexts (~16) — so we only mount the\n * shader while it's visible and release the context when it scrolls away.\n */\nexport function useInView(ref: React.RefObject<Element | null>, margin = \"250px\"): boolean {\n const [inView, setInView] = useState(false);\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n const io = new IntersectionObserver(([entry]) => setInView(entry.isIntersecting), { rootMargin: margin });\n io.observe(el);\n return () => io.disconnect();\n }, [ref, margin]);\n return inView;\n}\n\n/**\n * Finishes — shader presets tuned to the shape and size of the element. One\n * pattern does not fit all: a card wants broad flowing bands, a thin progress\n * bar wants many stripes crossing it, a 22px toggle thumb wants one soft\n * highlight like a ball bearing, and a hairline badge rim wants dense bands so\n * a tiny visible slice always catches some light.\n */\nexport type MetalFinish = \"surface\" | \"button\" | \"bar\" | \"orb\" | \"rim\";\n\ninterface FinishTuning {\n /** Band direction override (deg). */\n angle?: number;\n /** Random per-mount angle variation (±deg) so identical elements don't look cloned. */\n angleJitter?: number;\n repetition?: number;\n softness?: number;\n distortion?: number;\n /** Multiplier on the tone's chromatic shift. */\n shift?: number;\n /** Default pattern scale. */\n scale?: number;\n /** Multiplier on the animation speed. */\n speed?: number;\n}\n\nexport const FINISHES: Record<MetalFinish, FinishTuning> = {\n /** Cards, nav, panels — broad flowing reflection bands (the tone defaults). */\n surface: { scale: 1.1 },\n /** Buttons — slightly spread, calmer warp so labels stay readable. */\n button: { scale: 1.4, distortion: 0.1 },\n /** Thin horizontal strips (progress) — near-vertical stripes crossing the bar. */\n bar: { angle: 14, repetition: 5, softness: 0.3, distortion: 0.06, shift: 0.5, scale: 0.8, speed: 0.75 },\n /** Small round things (toggle thumbs) — one soft highlight, like a polished sphere. */\n orb: { angle: 112, angleJitter: 20, repetition: 1.7, softness: 0.5, distortion: 0.05, shift: 0.4, scale: 1.5 },\n /** Hairline edges (badges, thin borders) — dense bands so any slice sparkles. */\n rim: { angle: 40, repetition: 4.5, softness: 0.3, distortion: 0.08, shift: 0.5, scale: 0.85, speed: 0.85 },\n};\n\n/**\n * Effects — the character of the liquid's motion, independent of tone and\n * finish: how soft the bands are, how hard the noise churns them, how fast\n * everything moves.\n */\nexport type MetalEffect = \"flow\" | \"molten\" | \"ripple\" | \"chrome\" | \"wave\";\n\ninterface EffectTuning {\n angle?: number;\n repetition?: number;\n softness?: number;\n distortion?: number;\n /** Multiplier on chromatic shift. */\n shift?: number;\n /** Multiplier on animation speed. */\n speed?: number;\n}\n\nexport const EFFECTS: Record<MetalEffect, EffectTuning> = {\n /** The default — steady flowing reflection bands. */\n flow: {},\n /** Slow, heavy, half-melted — soft wide bands churning lazily. */\n molten: { softness: 0.5, distortion: 0.3, speed: 0.45, shift: 0.6 },\n /** Agitated surface — tighter bands, hard noise, quick motion. */\n ripple: { repetition: 4, softness: 0.24, distortion: 0.5, speed: 1.4 },\n /** Mirror-polished — crisp hard bands, strong chromatic fringe, calm. */\n chrome: { softness: 0.05, distortion: 0.05, shift: 1.6, speed: 0.8 },\n /** Horizontal swells rolling through the surface. */\n wave: { angle: 0, repetition: 5, softness: 0.36, distortion: 0.18, speed: 0.7 },\n};\n\nexport interface MetalFillProps {\n tone: MetalTone;\n /** Shader animation speed (0 pauses). */\n speed?: number;\n /** Pattern scale — higher spreads the bands out. Defaults per finish. */\n scale?: number;\n /** `\"paper\"` (Paper's LiquidMetal, default) or `\"native\"` (Argent's own shader). */\n engine?: MetalEngine;\n /** Shape-tuned shader preset. Defaults to `\"surface\"`. */\n finish?: MetalFinish;\n /** Motion character preset. Defaults to `\"flow\"`. */\n effect?: MetalEffect;\n /** Band direction in degrees — overrides the tone/finish default. */\n angle?: number;\n}\n\nconst FILL_STYLE: React.CSSProperties = { position: \"absolute\", inset: 0, width: \"100%\", height: \"100%\" };\n\n/** Argent's own clean-room shader on a plain canvas. */\nfunction NativeCanvas({ params }: { params: NativeMetalParams }) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const mountRef = useRef<MetalMount | null>(null);\n const initial = useRef(params);\n initial.current = params;\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n mountRef.current = mountMetal(canvas, initial.current);\n return () => {\n mountRef.current?.destroy();\n mountRef.current = null;\n };\n }, []);\n useEffect(() => {\n mountRef.current?.update(params);\n }, [params]);\n return <canvas ref={canvasRef} style={{ ...FILL_STYLE, display: \"block\" }} />;\n}\n\n/** The shader canvas, absolutely filling its positioned parent (when in view). */\nexport function MetalFill({ tone, speed = 1, scale, engine = \"paper\", finish = \"surface\", effect = \"flow\", angle }: MetalFillProps) {\n const ref = useRef<HTMLSpanElement>(null);\n const mounted = useMounted();\n const inView = useInView(ref);\n const reduced = useReducedMotion();\n const f = FINISHES[finish];\n const e = EFFECTS[effect];\n const [jitter] = useState(() => (f.angleJitter ? (Math.random() * 2 - 1) * f.angleJitter : 0));\n\n const base = TONE_PARAMS[tone];\n // precedence: explicit prop > effect > finish > tone\n const effAngle = (angle ?? e.angle ?? f.angle ?? base.angle ?? 70) + jitter;\n const effScale = scale ?? f.scale ?? 1.1;\n const effSpeed = (reduced ? 0 : speed) * (f.speed ?? 1) * (e.speed ?? 1);\n const shift = (f.shift ?? 1) * (e.shift ?? 1);\n const repetition = e.repetition ?? f.repetition ?? base.repetition;\n const softness = e.softness ?? f.softness ?? base.softness;\n const distortion = e.distortion ?? f.distortion ?? base.distortion;\n\n const native = NATIVE_TONES[tone];\n const nativeParams: NativeMetalParams = {\n ...native,\n angle: effAngle,\n repetition: repetition ?? native.repetition,\n softness: softness ?? native.softness,\n // the native warp amount runs ~3× paper's distortion scale\n distortion: distortion !== undefined ? distortion * 3 : native.distortion,\n dispersion: native.dispersion * shift,\n speed: effSpeed,\n scale: effScale,\n };\n\n return (\n <span ref={ref} aria-hidden=\"true\" style={{ position: \"absolute\", inset: 0 }}>\n {mounted && inView && (\n engine === \"native\" ? (\n <NativeCanvas params={nativeParams} />\n ) : (\n <LiquidMetal\n shape=\"none\"\n fit=\"cover\"\n scale={effScale}\n speed={effSpeed}\n {...base}\n angle={effAngle}\n repetition={repetition}\n softness={softness}\n distortion={distortion}\n shiftRed={(base.shiftRed ?? 0.3) * shift}\n shiftBlue={(base.shiftBlue ?? 0.3) * shift}\n style={FILL_STYLE}\n />\n )\n )}\n </span>\n );\n}\n","/**\n * Argent's own liquid-metal shader — a clean-room WebGL2 implementation of the\n * classic recipe: hard light→dark reflection banding, curvature-warped UVs,\n * time-driven simplex-noise flow, per-channel chromatic dispersion, and a rim\n * lift. No third-party shader code beyond the public-domain-style simplex\n * noise (Ashima Arts / Stefan Gustavson, MIT).\n *\n * Used when a surface sets `engine=\"native\"`; removes the need for\n * @paper-design/shaders-react entirely.\n */\n\nexport interface NativeMetalParams {\n /** Highlight band colour (hex). */\n light: string;\n /** Shadow band colour (hex). */\n dark: string;\n /** Stripe density. */\n repetition: number;\n /** Band direction in degrees. */\n angle: number;\n /** Band edge softness 0–1. */\n softness: number;\n /** Per-channel band offset (chromatic dispersion). */\n dispersion: number;\n /** Noise warp amount. */\n distortion: number;\n /** Animation speed (0 = still). */\n speed: number;\n /** Pattern scale — higher spreads the bands out. */\n scale: number;\n}\n\nexport type MetalEngine = \"paper\" | \"native\";\n\nconst VERT = `#version 300 es\nvoid main() {\n vec2 pos = vec2(float((gl_VertexID << 1) & 2), float(gl_VertexID & 2));\n gl_Position = vec4(pos * 2.0 - 1.0, 0.0, 1.0);\n}`;\n\nconst FRAG = `#version 300 es\nprecision highp float;\nuniform vec2 u_res;\nuniform float u_time;\nuniform vec3 u_light;\nuniform vec3 u_dark;\nuniform float u_rep;\nuniform float u_angle;\nuniform float u_soft;\nuniform float u_disp;\nuniform float u_dist;\nuniform float u_scale;\nout vec4 outColor;\n\n// 2D simplex noise — Ashima Arts / Stefan Gustavson (webgl-noise, MIT).\nvec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\nvec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\nvec3 permute(vec3 x) { return mod289(((x * 34.0) + 1.0) * x); }\nfloat snoise(vec2 v) {\n const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439);\n vec2 i = floor(v + dot(v, C.yy));\n vec2 x0 = v - i + dot(i, C.xx);\n vec2 i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n i = mod289(i);\n vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0)) + i.x + vec3(0.0, i1.x, 1.0));\n vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);\n m = m * m;\n m = m * m;\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n\n// One reflection band: a soft triangle wave over the warped coordinate.\nfloat stripe(float coord) {\n float f = fract(coord);\n float tri = abs(f * 2.0 - 1.0);\n return smoothstep(0.5 - u_soft, 0.5 + u_soft, tri);\n}\n\nvoid main() {\n vec2 uv = (gl_FragCoord.xy / u_res - 0.5);\n uv.x *= u_res.x / u_res.y;\n uv /= max(u_scale, 0.001);\n\n float t = u_time;\n\n // curvature: bands bend as if wrapping a bulged surface\n float d = length(uv);\n float bulge = 1.0 - 0.45 * d * d;\n\n // flowing warp — two noise octaves drifting at different rates\n float n = snoise(uv * 0.9 + vec2(0.0, -t * 0.28));\n n += 0.35 * snoise(uv * 1.8 + vec2(t * 0.1, -t * 0.45));\n\n // rotate so bands run along u_angle\n float c = cos(u_angle), s = sin(u_angle);\n vec2 ruv = mat2(c, -s, s, c) * uv;\n\n float coord = ruv.y * bulge * u_rep + n * u_dist * 2.2 - t * 0.22;\n\n // per-channel dispersion — the chrome fringing\n float r = stripe(coord + u_disp);\n float g = stripe(coord);\n float b = stripe(coord - u_disp);\n\n vec3 col = vec3(\n mix(u_dark.r, u_light.r, r),\n mix(u_dark.g, u_light.g, g),\n mix(u_dark.b, u_light.b, b)\n );\n\n // rim lift toward the edges\n col *= 0.94 + 0.14 * smoothstep(0.25, 0.85, d);\n\n outColor = vec4(col, 1.0);\n}`;\n\nfunction hexToRgb(hex: string): [number, number, number] {\n const h = hex.replace(\"#\", \"\");\n const v = h.length === 3 ? h.split(\"\").map((ch) => ch + ch).join(\"\") : h;\n const n = parseInt(v, 16);\n return [((n >> 16) & 255) / 255, ((n >> 8) & 255) / 255, (n & 255) / 255];\n}\n\nexport const NATIVE_TONES: Record<string, Omit<NativeMetalParams, \"speed\" | \"scale\">> = {\n silver: { light: \"#f8fafc\", dark: \"#23262b\", repetition: 1.8, angle: 68, softness: 0.34, dispersion: 0.03, distortion: 0.38 },\n gold: { light: \"#ffe9a8\", dark: \"#6e5408\", repetition: 1.8, angle: 68, softness: 0.34, dispersion: 0.028, distortion: 0.36 },\n gunmetal: { light: \"#b6bec9\", dark: \"#14161a\", repetition: 1.6, angle: 80, softness: 0.36, dispersion: 0.025, distortion: 0.34 },\n obsidian: { light: \"#787c88\", dark: \"#000000\", repetition: 1.4, angle: 92, softness: 0.42, dispersion: 0.02, distortion: 0.28 },\n};\n\nexport interface MetalMount {\n update(params: Partial<NativeMetalParams>): void;\n destroy(): void;\n}\n\nfunction compile(gl: WebGL2RenderingContext, type: number, src: string): WebGLShader | null {\n const sh = gl.createShader(type);\n if (!sh) return null;\n gl.shaderSource(sh, src);\n gl.compileShader(sh);\n if (!gl.getShaderParameter(sh, gl.COMPILE_STATUS)) {\n console.error(\"argent shader:\", gl.getShaderInfoLog(sh));\n gl.deleteShader(sh);\n return null;\n }\n return sh;\n}\n\n/** Mount the native liquid-metal shader on a canvas. Returns null without WebGL2. */\nexport function mountMetal(canvas: HTMLCanvasElement, params: NativeMetalParams): MetalMount | null {\n const gl = canvas.getContext(\"webgl2\", { antialias: true });\n if (!gl) return null;\n\n const vs = compile(gl, gl.VERTEX_SHADER, VERT);\n const fs = compile(gl, gl.FRAGMENT_SHADER, FRAG);\n if (!vs || !fs) return null;\n const prog = gl.createProgram()!;\n gl.attachShader(prog, vs);\n gl.attachShader(prog, fs);\n gl.linkProgram(prog);\n if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {\n console.error(\"argent shader link:\", gl.getProgramInfoLog(prog));\n return null;\n }\n gl.useProgram(prog);\n\n const U = (name: string) => gl.getUniformLocation(prog, name);\n const uRes = U(\"u_res\"), uTime = U(\"u_time\"), uLight = U(\"u_light\"), uDark = U(\"u_dark\");\n const uRep = U(\"u_rep\"), uAngle = U(\"u_angle\"), uSoft = U(\"u_soft\");\n const uDisp = U(\"u_disp\"), uDist = U(\"u_dist\"), uScale = U(\"u_scale\");\n\n let p = { ...params };\n let raf = 0;\n let tAcc = Math.random() * 40; // desync multiple surfaces\n let last = performance.now();\n let dead = false;\n\n function draw() {\n raf = 0;\n if (dead) return;\n const dpr = Math.min(window.devicePixelRatio || 1, 2);\n const w = Math.max(1, Math.round(canvas.clientWidth * dpr));\n const h = Math.max(1, Math.round(canvas.clientHeight * dpr));\n if (canvas.width !== w || canvas.height !== h) {\n canvas.width = w;\n canvas.height = h;\n gl!.viewport(0, 0, w, h);\n }\n const now = performance.now();\n tAcc += ((now - last) / 1000) * p.speed;\n last = now;\n\n gl!.uniform2f(uRes, w, h);\n gl!.uniform1f(uTime, tAcc);\n gl!.uniform3fv(uLight, hexToRgb(p.light));\n gl!.uniform3fv(uDark, hexToRgb(p.dark));\n gl!.uniform1f(uRep, p.repetition);\n gl!.uniform1f(uAngle, (p.angle * Math.PI) / 180);\n gl!.uniform1f(uSoft, Math.max(0.02, p.softness));\n gl!.uniform1f(uDisp, p.dispersion);\n gl!.uniform1f(uDist, p.distortion);\n gl!.uniform1f(uScale, p.scale);\n gl!.drawArrays(gl!.TRIANGLES, 0, 3);\n\n if (p.speed > 0) raf = requestAnimationFrame(draw);\n }\n draw();\n\n return {\n update(np) {\n p = { ...p, ...np };\n last = performance.now();\n if (!raf) raf = requestAnimationFrame(draw);\n },\n destroy() {\n dead = true;\n if (raf) cancelAnimationFrame(raf);\n gl.getExtension(\"WEBGL_lose_context\")?.loseContext();\n },\n };\n}\n","/**\n * Tiny haptics for metal presses — `navigator.vibrate` where available\n * (Android Chrome; iOS Safari ignores it). On by default, like Glacé.\n */\n\nlet enabled = true;\n\n/** Globally enable/disable Argent haptics. */\nexport function setHaptics(on: boolean) {\n enabled = on;\n}\n\nexport function vibrate(pattern: number | number[]) {\n if (!enabled || typeof navigator === \"undefined\" || !(\"vibrate\" in navigator)) return;\n try {\n navigator.vibrate(pattern);\n } catch {\n // some browsers throw on vibrate without user activation — fine to ignore\n }\n}\n\n/** The stamped-press click. */\nexport const PRESS_PATTERN = 8;\n","import { forwardRef, useState } from \"react\";\nimport { MetalFill, type MetalTone } from \"./metal\";\nimport { Metal, type MetalProps } from \"./surfaces\";\nimport { PRESS_PATTERN, vibrate } from \"./haptics\";\n\nexport interface MetalToggleProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"onChange\"> {\n tone?: MetalTone;\n checked?: boolean;\n defaultChecked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n /** Vibrate on toggle where supported. Defaults to `true`. */\n haptics?: boolean;\n}\n\n/**\n * A mercury switch — the thumb is a drop of liquid metal that slides (and\n * squishes) across a dark channel.\n */\nexport const MetalToggle = forwardRef<HTMLButtonElement, MetalToggleProps>(function MetalToggle(\n { tone = \"silver\", checked, defaultChecked = false, onCheckedChange, haptics = true, className, onClick, ...rest },\n ref,\n) {\n const [internal, setInternal] = useState(defaultChecked);\n const isOn = checked ?? internal;\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"switch\"\n aria-checked={isOn}\n data-tone={tone}\n data-checked={isOn || undefined}\n className={[\"argent-toggle\", className].filter(Boolean).join(\" \")}\n onClick={(e) => {\n if (haptics) vibrate(PRESS_PATTERN);\n if (checked === undefined) setInternal(!isOn);\n onCheckedChange?.(!isOn);\n onClick?.(e);\n }}\n {...rest}\n >\n <span className=\"argent-toggle-thumb\" aria-hidden=\"true\">\n <MetalFill tone={tone} finish=\"orb\" />\n </span>\n </button>\n );\n});\n\nexport interface MetalProgressProps extends React.HTMLAttributes<HTMLDivElement> {\n tone?: MetalTone;\n /** 0–100. Omit for an indeterminate molten sweep. */\n value?: number;\n /** Track height in px. */\n height?: number;\n}\n\n/** A molten progress bar — liquid metal rising in a dark channel. */\nexport const MetalProgress = forwardRef<HTMLDivElement, MetalProgressProps>(function MetalProgress(\n { tone = \"silver\", value, height = 10, className, style, ...rest },\n ref,\n) {\n const indeterminate = value === undefined;\n const clamped = indeterminate ? 0 : Math.max(0, Math.min(100, value));\n return (\n <div\n ref={ref}\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={indeterminate ? undefined : clamped}\n data-tone={tone}\n className={[\"argent-progress\", indeterminate && \"argent-progress--indeterminate\", className].filter(Boolean).join(\" \")}\n style={{ height, ...style }}\n {...rest}\n >\n <span\n className=\"argent-progress-fill\"\n style={indeterminate ? undefined : { width: `${clamped}%` }}\n aria-hidden=\"true\"\n >\n <MetalFill tone={tone} finish=\"bar\" />\n </span>\n </div>\n );\n});\n\nexport interface MetalBadgeProps extends Omit<MetalProps, \"as\" | \"variant\"> {}\n\n/** A small liquid-metal pill — a metal rim around a quiet label. */\nexport const MetalBadge = forwardRef<HTMLElement, MetalBadgeProps>(function MetalBadge(\n { className, radius = 999, borderWidth = 1, finish = \"rim\", ...rest },\n ref,\n) {\n return (\n <Metal\n ref={ref}\n as=\"span\"\n variant=\"border\"\n radius={radius}\n borderWidth={borderWidth}\n finish={finish}\n className={[\"argent-badge\", className].filter(Boolean).join(\" \")}\n {...rest}\n />\n );\n});\n","import { forwardRef, useEffect, useRef, useState } from \"react\";\nimport { LiquidMetal } from \"@paper-design/shaders-react\";\nimport { TONE_PARAMS, useInView, useMounted, useReducedMotion, useStaggeredMount, type MetalTone } from \"./metal\";\n\n/** Where the metal lives in shader text: the whole glyph, or just its edge. */\nexport type MetalTextVariant = \"fill\" | \"outline\";\n\nexport interface MetalTextProps extends React.HTMLAttributes<HTMLElement> {\n /** Element to render. Defaults to `span`. */\n as?: React.ElementType;\n tone?: MetalTone;\n /** Animate the highlight band across the glyphs (CSS mode). Defaults to `true`. */\n shimmer?: boolean;\n /**\n * Pour the real liquid-metal shader into the glyphs — flowing bands, liquid\n * edges, chromatic fringe. On by default (one WebGL canvas; the CSS chrome\n * gradient renders as a placeholder until the shader is ready, and stands in\n * wherever WebGL isn't). Set `shader={false}` for the pure-CSS gradient.\n * Shader mode requires a plain string child; element children fall back to CSS.\n */\n shader?: boolean;\n /**\n * Shader mode: `\"fill\"` (metal fills the glyphs, default) or `\"outline\"` —\n * the metal runs around the edge of each letterform and the interior takes\n * `fill` / `fillGradient`.\n */\n variant?: MetalTextVariant;\n /** Interior colour for `variant=\"outline\"`. */\n fill?: string;\n /** Interior vertical gradient `[top, bottom]` for `variant=\"outline\"` — wins over `fill`. */\n fillGradient?: [string, string];\n /** Metal edge thickness in px for `variant=\"outline\"`. Defaults to ~5% of the font size. */\n outlineWidth?: number;\n /** Type size in px (shader mode). Defaults to `64`. */\n fontSize?: number;\n /** Weight for the glyph silhouette (shader mode). Defaults to `800`. */\n fontWeight?: number;\n /**\n * Font for the silhouette (shader mode). Rendered inside an SVG image, which\n * sees system fonts only — to use a webfont, pass `fontCss` with a\n * data-URI @font-face for the same family.\n */\n fontFamily?: string;\n /**\n * Raw CSS embedded in the glyph SVG (shader mode) — typically a @font-face\n * whose `src` is a data: URI, which lets webfonts (e.g. Google Fonts) render\n * inside the silhouette. Load the same face into `document.fonts` so the\n * width measurement matches.\n */\n fontCss?: string;\n /** Shader animation speed (0 pauses). */\n speed?: number;\n}\n\nconst DEFAULT_STACK = \"-apple-system, 'Helvetica Neue', Helvetica, Arial, sans-serif\";\n\ninterface GlyphGeom {\n text: string;\n w: number;\n h: number;\n fontSize: number;\n fontWeight: number;\n fontFamily: string;\n fontCss?: string;\n}\n\nfunction svgOpen(g: GlyphGeom): string {\n const style = g.fontCss ? `<style>${g.fontCss}</style>` : \"\";\n return `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 ${g.w} ${g.h}' width='${g.w}' height='${g.h}'>${style}`;\n}\n\nfunction svgText(g: GlyphGeom, attrs: string): string {\n const safe = g.text.replace(/&/g, \"&\").replace(/</g, \"<\");\n return `<text x='50%' y='${Math.round(g.fontSize * 1.0)}' font-size='${g.fontSize}' font-family=\"${g.fontFamily.replace(/\"/g, \"'\")}\" font-weight='${g.fontWeight}' text-anchor='middle' ${attrs}>${safe}</text>`;\n}\n\nfunction encode(svg: string): string {\n return `data:image/svg+xml,${encodeURIComponent(svg)}`;\n}\n\n/** Solid glyphs — the shader fills the whole letterform. */\nfunction fillSilhouette(g: GlyphGeom): string {\n return encode(`${svgOpen(g)}${svgText(g, \"fill='#000'\")}</svg>`);\n}\n\n/** Stroke-only glyphs — the shader flows in a ring around each letterform. */\nfunction outlineSilhouette(g: GlyphGeom, ow: number): string {\n return encode(`${svgOpen(g)}${svgText(g, `fill='none' stroke='#000' stroke-width='${ow}' stroke-linejoin='round'`)}</svg>`);\n}\n\n/** The interior of outline text — flat or gradient fill, geometry-identical to the silhouette. */\nfunction interior(g: GlyphGeom, fill: string, gradient?: [string, string]): string {\n if (!gradient) return encode(`${svgOpen(g)}${svgText(g, `fill='${fill}'`)}</svg>`);\n const defs = `<defs><linearGradient id='g' x1='0' y1='0' x2='0' y2='1'><stop offset='0' stop-color='${gradient[0]}'/><stop offset='1' stop-color='${gradient[1]}'/></linearGradient></defs>`;\n return encode(`${svgOpen(g)}${defs}${svgText(g, \"fill='url(#g)'\")}</svg>`);\n}\n\nconst LAYER: React.CSSProperties = { position: \"absolute\", inset: 0, width: \"100%\", height: \"100%\" };\n\nfunction ShaderText({\n text,\n tone,\n variant,\n fill,\n fillGradient,\n outlineWidth,\n fontSize,\n fontWeight,\n fontFamily,\n fontCss,\n speed,\n shimmer,\n className,\n style,\n ...rest\n}: {\n text: string;\n tone: MetalTone;\n variant: MetalTextVariant;\n fill: string;\n fillGradient?: [string, string];\n outlineWidth?: number;\n fontSize: number;\n fontWeight: number;\n fontFamily: string;\n fontCss?: string;\n speed: number;\n shimmer: boolean;\n} & React.HTMLAttributes<HTMLElement>) {\n const ref = useRef<HTMLSpanElement>(null);\n const mounted = useMounted();\n const inView = useInView(ref);\n const reduced = useReducedMotion();\n const turn = useStaggeredMount();\n const [geom, setGeom] = useState<GlyphGeom | null>(null);\n\n const outlined = variant === \"outline\";\n const ow = outlineWidth ?? Math.max(2, Math.round(fontSize * 0.05));\n\n useEffect(() => {\n let alive = true;\n const fontSpec = `${fontWeight} ${fontSize}px ${fontFamily}`;\n const measure = () => {\n if (!alive) return;\n const ctx = document.createElement(\"canvas\").getContext(\"2d\");\n if (!ctx) return;\n ctx.font = fontSpec;\n const m = ctx.measureText(text);\n setGeom({\n text,\n w: Math.ceil(m.width + fontSize * 0.24 + ow * 2),\n h: Math.ceil(fontSize * 1.3 + ow),\n fontSize,\n fontWeight,\n fontFamily,\n fontCss,\n });\n };\n // wait for webfonts so the measured width matches the silhouette\n if (document.fonts?.load) document.fonts.load(fontSpec, text).then(measure, measure);\n else measure();\n return () => {\n alive = false;\n };\n }, [text, fontSize, fontWeight, fontFamily, fontCss, ow]);\n\n const ready = mounted && inView && turn && geom;\n const { colorBack: _drop, ...params } = TONE_PARAMS[tone];\n // a thin ring can't survive heavy edge distortion — calm it down for outlines\n const shaderParams = outlined ? { ...params, contour: 0.2, distortion: Math.min(params.distortion ?? 0.1, 0.08) } : params;\n\n return (\n <span\n ref={ref}\n role=\"img\"\n aria-label={text}\n className={className}\n style={{\n position: \"relative\",\n display: \"inline-block\",\n verticalAlign: \"middle\",\n width: geom?.w,\n height: geom?.h,\n ...style,\n }}\n {...rest}\n >\n {ready ? (\n <>\n {outlined && <img src={interior(geom, fill, fillGradient)} alt=\"\" aria-hidden=\"true\" style={LAYER} />}\n <LiquidMetal\n // keyed by silhouette: rapid prop changes can finish processing\n // out of order and leave stale glyphs — a clean re-init can't\n key={`${geom.text}|${geom.fontFamily}|${geom.w}|${outlined ? \"o\" : \"f\"}`}\n image={outlined ? outlineSilhouette(geom, ow) : fillSilhouette(geom)}\n suspendWhenProcessingImage={false}\n colorBack=\"#00000000\"\n fit=\"contain\"\n scale={0.97}\n speed={reduced ? 0 : speed}\n {...shaderParams}\n style={LAYER}\n />\n </>\n ) : (\n // CSS chrome stands in until the shader is ready (and during SSR)\n <span\n aria-hidden=\"true\"\n className={[\"argent-text\", shimmer && !outlined && \"argent-text--shimmer\"].filter(Boolean).join(\" \")}\n data-tone={tone}\n style={{\n fontSize,\n fontWeight,\n fontFamily,\n lineHeight: 1.3,\n whiteSpace: \"nowrap\",\n ...(outlined && {\n background: \"none\",\n WebkitTextFillColor: fillGradient?.[0] ?? fill,\n color: fillGradient?.[0] ?? fill,\n WebkitTextStroke: \"1px rgba(220, 224, 230, 0.55)\",\n }),\n }}\n >\n {text}\n </span>\n )}\n </span>\n );\n}\n\n/**\n * Metal type. By default the real liquid-metal shader is poured into the glyphs\n * — `variant=\"fill\"` floods them, `variant=\"outline\"` runs the metal around\n * their edges over a dark or gradient interior. The CSS chrome gradient stands\n * in until the shader loads. Set `shader={false}` for the pure-CSS gradient\n * (free at any scale); element children also fall back to it.\n */\nexport const MetalText = forwardRef<HTMLElement, MetalTextProps>(function MetalText(\n {\n as,\n tone = \"silver\",\n shimmer = true,\n shader = true,\n variant = \"fill\",\n fill = \"#101114\",\n fillGradient,\n outlineWidth,\n fontSize = 64,\n fontWeight = 800,\n fontFamily = DEFAULT_STACK,\n fontCss,\n speed = 1,\n className,\n children,\n ...rest\n },\n ref,\n) {\n if (shader && typeof children === \"string\") {\n return (\n <ShaderText\n text={String(children)}\n tone={tone}\n variant={variant}\n fill={fill}\n fillGradient={fillGradient}\n outlineWidth={outlineWidth}\n fontSize={fontSize}\n fontWeight={fontWeight}\n fontFamily={fontFamily}\n fontCss={fontCss}\n speed={speed}\n shimmer={shimmer}\n className={className}\n {...rest}\n />\n );\n }\n const Tag = (as ?? \"span\") as React.ElementType;\n return (\n <Tag\n ref={ref}\n className={[\"argent-text\", shimmer && \"argent-text--shimmer\", className].filter(Boolean).join(\" \")}\n data-tone={tone}\n {...rest}\n >\n {children}\n </Tag>\n );\n});\n","import { useRef } from \"react\";\nimport { LiquidMetal } from \"@paper-design/shaders-react\";\nimport { TONE_PARAMS, useInView, useMounted, useReducedMotion, useStaggeredMount, type MetalTone } from \"./metal\";\n\nexport interface MetalLogoProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Image URL (or data URI) with a transparent background — the metal flows inside its silhouette. */\n src: string;\n tone?: MetalTone;\n /** Rendered size in px (square by default). */\n size?: number;\n width?: number;\n height?: number;\n /** Shader animation speed (0 pauses). */\n speed?: number;\n}\n\n/**\n * Liquid metal poured into a logo — pass any image with a transparent\n * background and the metal flows inside its silhouette. The classic\n * liquid-metal treatment for marks, monograms, and icons.\n */\nexport function MetalLogo({ src, tone = \"silver\", size = 160, width, height, speed = 1, style, ...rest }: MetalLogoProps) {\n const ref = useRef<HTMLDivElement>(null);\n const mounted = useMounted();\n const inView = useInView(ref);\n const reduced = useReducedMotion();\n const turn = useStaggeredMount();\n const w = width ?? size;\n const h = height ?? size;\n const { colorBack: _drop, ...params } = TONE_PARAMS[tone];\n return (\n <div ref={ref} style={{ position: \"relative\", width: w, height: h, ...style }} {...rest}>\n {mounted && inView && turn && (\n <LiquidMetal\n key={src}\n image={src}\n suspendWhenProcessingImage={false}\n colorBack=\"#00000000\"\n fit=\"contain\"\n scale={0.92}\n speed={reduced ? 0 : speed}\n {...params}\n style={{ position: \"absolute\", inset: 0, width: \"100%\", height: \"100%\" }}\n />\n )}\n </div>\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { MetalLogo } from \"./logo\";\nimport type { MetalTone } from \"./metal\";\n\n/**\n * Liquid metal poured into an icon. Pass any SVG icon — a React element from\n * lucide-react / heroicons, a raw SVG string, or a URL — and it renders filled\n * with the liquid-metal shader (one WebGL canvas, gated to the viewport like\n * every metal surface). React icons are serialized from the DOM to a silhouette.\n */\nexport interface MetalIconProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, \"children\"> {\n /** A React SVG element, e.g. `<Beaker />` (lucide) or `<BeakerIcon />` (heroicons). */\n icon?: React.ReactNode;\n /** Raw SVG markup (alternative to `icon`). */\n svg?: string;\n /** SVG URL or data URI (alternative to `icon`). */\n src?: string;\n tone?: MetalTone;\n /** Rendered size in px (square). Defaults to `32`. */\n size?: number;\n /** Shader animation speed. */\n speed?: number;\n}\n\nfunction svgToUri(markup: string): string {\n return `data:image/svg+xml,${encodeURIComponent(markup)}`;\n}\n\nfunction serialize(svg: SVGElement): string {\n const clone = svg.cloneNode(true) as SVGElement;\n if (!clone.getAttribute(\"xmlns\")) clone.setAttribute(\"xmlns\", \"http://www.w3.org/2000/svg\");\n return svgToUri(new XMLSerializer().serializeToString(clone));\n}\n\n/** Resolve `svg`/`src`, or serialize the icon rendered into `ref`, to a data URI. */\nfunction useIconUri({ svg, src }: Pick<MetalIconProps, \"svg\" | \"src\">) {\n const ref = useRef<HTMLSpanElement>(null);\n const direct = src ?? (svg ? svgToUri(svg) : null);\n const [uri, setUri] = useState<string | null>(direct);\n useEffect(() => {\n if (direct) {\n setUri(direct);\n return;\n }\n const node = ref.current?.querySelector(\"svg\");\n if (!node) return;\n const next = serialize(node as unknown as SVGElement);\n // most icons are static — only re-set when the markup actually changes\n setUri((prev) => (prev === next ? prev : next));\n });\n return { ref, uri, fromNode: !direct };\n}\n\nexport function MetalIcon({ icon, svg, src, tone = \"silver\", size = 32, speed = 1, className, style, ...rest }: MetalIconProps) {\n const { ref, uri, fromNode } = useIconUri({ svg, src });\n const cls = [\"argent-icon-wrap\", className].filter(Boolean).join(\" \");\n return (\n <span className={cls} style={{ display: \"inline-flex\", width: size, height: size, ...style }} {...rest}>\n {fromNode && (\n <span ref={ref} aria-hidden=\"true\" style={{ position: \"absolute\", width: 0, height: 0, overflow: \"hidden\", color: \"#000\" }}>\n {icon}\n </span>\n )}\n {uri && <MetalLogo src={uri} tone={tone} size={size} speed={speed} />}\n </span>\n );\n}\n"],"mappings":"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","names":["jsx","Metal","MetalCard","MetalButton","forwardRef","useState","jsx","forwardRef","MetalToggle","useState","MetalProgress","MetalBadge","forwardRef","useEffect","useRef","useState","LiquidMetal","jsx","jsxs","useRef","useState","useEffect","LiquidMetal","forwardRef","MetalText","useRef","LiquidMetal","jsx","useRef","LiquidMetal","useEffect","useRef","useState","jsx","jsxs","useRef","useState","useEffect"]}
|
package/dist/styles.css
CHANGED
|
@@ -198,6 +198,13 @@
|
|
|
198
198
|
.argent-text--shimmer { animation: none; }
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
+
/* ── Metal icons ──────────────────────────────────────────────────────── */
|
|
202
|
+
.argent-icon-wrap { vertical-align: middle; line-height: 0; position: relative; }
|
|
203
|
+
|
|
204
|
+
/* button icon sits in the label, inheriting the label colour */
|
|
205
|
+
.argent-btn-icon { display: inline-flex; align-items: center; }
|
|
206
|
+
.argent-btn-icon svg { width: 1.05em; height: 1.05em; display: block; }
|
|
207
|
+
|
|
201
208
|
/* ── Toggle (mercury switch) ──────────────────────────────────────────── */
|
|
202
209
|
.argent-toggle {
|
|
203
210
|
position: relative;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "argentui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Argent — liquid-metal UI for React. Chrome, gold, and gunmetal surfaces that ripple like mercury, powered by Paper's LiquidMetal WebGL shader. A metal sibling to Glacé.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|