@hanzo/ui 8.27.46 → 8.27.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/dist/backends/gui/control.cjs +18 -1
  2. package/dist/backends/gui/control.d.ts +33 -0
  3. package/dist/backends/gui/control.d.ts.map +1 -1
  4. package/dist/backends/gui/control.js +17 -0
  5. package/dist/backends/gui/control.js.map +1 -1
  6. package/dist/backends/gui/index.cjs +7 -6
  7. package/dist/backends/gui/index.d.ts +2 -1
  8. package/dist/backends/gui/index.d.ts.map +1 -1
  9. package/dist/backends/gui/index.js +1 -1
  10. package/dist/backends/gui/index.js.map +1 -1
  11. package/dist/backends/gui/input.cjs +10 -9
  12. package/dist/backends/gui/input.d.ts +6 -1
  13. package/dist/backends/gui/input.d.ts.map +1 -1
  14. package/dist/backends/gui/input.js +11 -10
  15. package/dist/backends/gui/input.js.map +1 -1
  16. package/dist/backends/gui/select.cjs +24 -1
  17. package/dist/backends/gui/select.d.ts +25 -2
  18. package/dist/backends/gui/select.d.ts.map +1 -1
  19. package/dist/backends/gui/select.js +26 -4
  20. package/dist/backends/gui/select.js.map +1 -1
  21. package/dist/backends/gui/textarea.cjs +5 -4
  22. package/dist/backends/gui/textarea.d.ts +7 -1
  23. package/dist/backends/gui/textarea.d.ts.map +1 -1
  24. package/dist/backends/gui/textarea.js +6 -5
  25. package/dist/backends/gui/textarea.js.map +1 -1
  26. package/dist/gallery.html +107 -7
  27. package/dist/index.cjs +8 -7
  28. package/dist/index.d.ts +2 -2
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +1 -1
  31. package/dist/index.js.map +1 -1
  32. package/dist/index.node.cjs +8 -7
  33. package/dist/index.node.js +1 -1
  34. package/dist/marketing/Cta.cjs +9 -3
  35. package/dist/marketing/Cta.d.ts +7 -5
  36. package/dist/marketing/Cta.d.ts.map +1 -1
  37. package/dist/marketing/Cta.js +10 -4
  38. package/dist/marketing/Cta.js.map +1 -1
  39. package/dist/marketing/controls.cjs +112 -0
  40. package/dist/marketing/controls.d.ts +42 -0
  41. package/dist/marketing/controls.d.ts.map +1 -0
  42. package/dist/marketing/controls.js +108 -0
  43. package/dist/marketing/controls.js.map +1 -0
  44. package/dist/marketing/document.cjs +7 -0
  45. package/dist/marketing/document.d.ts +22 -0
  46. package/dist/marketing/document.d.ts.map +1 -0
  47. package/dist/marketing/document.js +5 -0
  48. package/dist/marketing/document.js.map +1 -0
  49. package/dist/marketing/host.cjs +39 -0
  50. package/dist/marketing/host.d.ts +21 -0
  51. package/dist/marketing/host.d.ts.map +1 -0
  52. package/dist/marketing/host.js +35 -0
  53. package/dist/marketing/host.js.map +1 -0
  54. package/dist/marketing/index.cjs +24 -1
  55. package/dist/marketing/index.d.ts +8 -2
  56. package/dist/marketing/index.d.ts.map +1 -1
  57. package/dist/marketing/index.js +7 -1
  58. package/dist/marketing/index.js.map +1 -1
  59. package/dist/marketing/loose.cjs +2 -0
  60. package/dist/marketing/loose.d.ts +41 -0
  61. package/dist/marketing/loose.d.ts.map +1 -0
  62. package/dist/marketing/loose.js +2 -0
  63. package/dist/marketing/loose.js.map +1 -0
  64. package/dist/marketing/pager.cjs +22 -0
  65. package/dist/marketing/pager.d.ts +22 -0
  66. package/dist/marketing/pager.d.ts.map +1 -0
  67. package/dist/marketing/pager.js +20 -0
  68. package/dist/marketing/pager.js.map +1 -0
  69. package/dist/marketing/pair.cjs +21 -0
  70. package/dist/marketing/pair.d.ts +22 -0
  71. package/dist/marketing/pair.d.ts.map +1 -0
  72. package/dist/marketing/pair.js +19 -0
  73. package/dist/marketing/pair.js.map +1 -0
  74. package/dist/marketing/run.cjs +28 -0
  75. package/dist/marketing/run.d.ts +33 -0
  76. package/dist/marketing/run.d.ts.map +1 -0
  77. package/dist/marketing/run.js +26 -0
  78. package/dist/marketing/run.js.map +1 -0
  79. package/dist/marketing/surface.cjs +76 -0
  80. package/dist/marketing/surface.d.ts +59 -0
  81. package/dist/marketing/surface.d.ts.map +1 -0
  82. package/dist/marketing/surface.js +70 -0
  83. package/dist/marketing/surface.js.map +1 -0
  84. package/dist/marketing/type.cjs +29 -2
  85. package/dist/marketing/type.d.ts +43 -4
  86. package/dist/marketing/type.d.ts.map +1 -1
  87. package/dist/marketing/type.js +24 -1
  88. package/dist/marketing/type.js.map +1 -1
  89. package/dist/styles/document.css +93 -0
  90. package/dist/styles/motion.css +52 -2
  91. package/dist/styles.css +104 -4
  92. package/dist/theme.css +52 -2
  93. package/package.json +3 -2
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Run — a light crosses a set of things that are all true at once.
3
+ *
4
+ * Prose states invariants one at a time, and a reader has finished the first
5
+ * before the fourth exists; a run lays the set out and sweeps it, so several
6
+ * are lit together and none is ever "next". Each DIRECT child says where it
7
+ * stands with `data-beat={n}`, and is lit `n` steps after the first:
8
+ *
9
+ * <Run step={0.31}>{steps.map((s, i) => <Chip key={s} data-beat={i}>{s}</Chip>)}</Run>
10
+ *
11
+ * `step` is the delay per beat, short against the 5.4s cycle so several are lit
12
+ * at once; an ORDERED set takes a step near cycle/n, and the order is the
13
+ * content's to say, so the caller says it. `rest` is the ink the sweep returns
14
+ * to, because the animation owns `color` for the whole cycle.
15
+ *
16
+ * The keyframe is `@hanzo/ui/styles/motion.css`, keyed on `data-motion`, and
17
+ * reduced motion stills it. The two knobs ride this element's own custom
18
+ * properties, which no gui prop names. Colour and edge only, so it composes
19
+ * with an entrance that owns transform and opacity.
20
+ */
21
+ import { type ViewProps } from '@hanzo/gui';
22
+ import type { ReactNode } from 'react';
23
+ import type { Loose } from './loose.js';
24
+ export type RunProps = Loose<Omit<ViewProps, 'children'>> & {
25
+ children?: ReactNode;
26
+ /** Seconds between one beat and the next. */
27
+ step?: number;
28
+ /** The ink a lit child returns to. */
29
+ rest?: string;
30
+ };
31
+ declare const Run: ({ step, rest, ...p }: RunProps) => import("react").JSX.Element;
32
+ export { Run };
33
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/marketing/run.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAA;AAErD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAEpC,MAAM,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,GAAG;IAC1D,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sCAAsC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAED,QAAA,MAAM,GAAG,yBAAiC,QAAQ,gCAMjD,CAAA;AAED,OAAO,EAAE,GAAG,EAAE,CAAA"}
@@ -0,0 +1,26 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ /**
4
+ * Run — a light crosses a set of things that are all true at once.
5
+ *
6
+ * Prose states invariants one at a time, and a reader has finished the first
7
+ * before the fourth exists; a run lays the set out and sweeps it, so several
8
+ * are lit together and none is ever "next". Each DIRECT child says where it
9
+ * stands with `data-beat={n}`, and is lit `n` steps after the first:
10
+ *
11
+ * <Run step={0.31}>{steps.map((s, i) => <Chip key={s} data-beat={i}>{s}</Chip>)}</Run>
12
+ *
13
+ * `step` is the delay per beat, short against the 5.4s cycle so several are lit
14
+ * at once; an ORDERED set takes a step near cycle/n, and the order is the
15
+ * content's to say, so the caller says it. `rest` is the ink the sweep returns
16
+ * to, because the animation owns `color` for the whole cycle.
17
+ *
18
+ * The keyframe is `@hanzo/ui/styles/motion.css`, keyed on `data-motion`, and
19
+ * reduced motion stills it. The two knobs ride this element's own custom
20
+ * properties, which no gui prop names. Colour and edge only, so it composes
21
+ * with an entrance that owns transform and opacity.
22
+ */
23
+ import { View } from '@hanzo/gui';
24
+ const Run = ({ step = 0.22, rest, ...p }) => (_jsx(View, { "data-motion": "run", ...p, style: { '--run-step': `${step}s`, ...(rest ? { '--run-rest': rest } : null) } }));
25
+ export { Run };
26
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/marketing/run.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,IAAI,EAAkB,MAAM,YAAY,CAAA;AAajD,MAAM,GAAG,GAAG,CAAC,EAAE,IAAI,GAAG,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,EAAY,EAAE,EAAE,CAAC,CACrD,KAAC,IAAI,mBACS,KAAK,KACZ,CAAY,EACjB,KAAK,EAAE,EAAE,YAAY,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAmB,GAC/F,CACH,CAAA;AAED,OAAO,EAAE,GAAG,EAAE,CAAA"}
@@ -0,0 +1,76 @@
1
+ 'use client';"use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.Lattice = exports.Reveal = exports.Lift = exports.Cell = exports.Leaf = void 0;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ /**
7
+ * Surfaces that answer approach, and the marks inside them that answer with
8
+ * them.
9
+ *
10
+ * Leaf a card: a corner, an edge that brightens on hover, no ground
11
+ * Cell a tile of a ruled grid: no corner and no edge, a ground that brightens
12
+ * Lift ink that brightens when its card is hovered; `step` also moves it
13
+ * 2px toward where it goes
14
+ * Reveal a line offered only on approach — hover, or a keyboard's focus
15
+ * Lattice a ruled backdrop: a decorative grid behind a hero
16
+ *
17
+ * A Leaf or a Cell is a gui `group`, and the marks read it with `$group-hover`,
18
+ * so the card decides when and the mark decides how. It is a group and NOT a
19
+ * size container: gui's default `container-type: inline-size` sizes the box as
20
+ * if it were empty, so a card a row sizes by its content — a filter chip —
21
+ * collapsed to its own padding. No mark asks the group its size. An ink written on a mark
22
+ * is a prop beside the hover, so nothing has to out-rank anything: the lift a
23
+ * stylesheet used to apply lost to every atomic `color` a mark carried, and
24
+ * those cards never lifted.
25
+ *
26
+ * Every default is a prop a caller replaces: `p` for the padding, `borderColor`
27
+ * for the resting edge, `hoverStyle` for the approach, `bg` for a ground.
28
+ */
29
+ const gui_1 = require("@hanzo/gui");
30
+ const slot_1 = require("../backends/gui/slot.cjs");
31
+ const host_1 = require("./host.cjs");
32
+ /** The element's own display — what @hanzo/design's base or the browser gives
33
+ * it — under gui Text's `inline`. */
34
+ const OWN = 'revert-layer';
35
+ /** The element's own ink, the same way: @hanzo/design's base gives every `<a>`
36
+ * and every heading `--text-primary`, and anything else takes its parent's. */
37
+ const INK = 'revert-layer';
38
+ /** The lifted ink: white on the dark ground, ink on the light one. */
39
+ const LIFT = 'var(--text-primary)';
40
+ /** A card. The defaults change nothing but the corner and the hover edge: no
41
+ * ground, a transparent resting edge, so a card that names only a ground gets
42
+ * a ground and no lift. */
43
+ const Leaf = ({ render, ...p }) => {
44
+ const host = (0, host_1.useHost)(render, p.href, 'div');
45
+ return ((0, jsx_runtime_1.jsx)(gui_1.Text, { ...(0, slot_1.slot)('leaf'), group: true, containerType: "normal", render: host, display: "block", height: "100%", whiteSpace: "inherit", textDecorationLine: "none", color: INK, p: "$4", borderWidth: 1, borderStyle: "solid", borderColor: "transparent", rounded: "var(--radius-xl)", hoverStyle: { borderColor: 'var(--white-15)' }, ...p }));
46
+ };
47
+ exports.Leaf = Leaf;
48
+ /** A tile of a ruled grid, which rules its own lines with a 1px gap over a
49
+ * neutral ground — so a Cell adds no edge and no corner, which would break the
50
+ * flush rule the grid is made of, and no box: the element keeps the display the
51
+ * document gives it, so a row stays a row and an icon button stays centred. */
52
+ const Cell = ({ render, ...p }) => {
53
+ const host = (0, host_1.useHost)(render, p.href, 'div');
54
+ return ((0, jsx_runtime_1.jsx)(gui_1.Text, { ...(0, slot_1.slot)('cell'), group: true, containerType: "normal", render: host, display: OWN, whiteSpace: "inherit", textDecorationLine: "none", bg: "var(--pure-black)", color: "inherit", hoverStyle: { bg: 'var(--neutral-950)' }, ...p }));
55
+ };
56
+ exports.Cell = Cell;
57
+ /** Ink that brightens with its card. Inline, like the word or icon it wraps;
58
+ * a mark that steps is a box (`display="inline-flex"`), because an inline box
59
+ * does not move. */
60
+ const Lift = ({ render = 'span', step = false, ...p }) => ((0, jsx_runtime_1.jsx)(gui_1.Text, { ...(0, slot_1.slot)('lift'), render: render, display: OWN, whiteSpace: "inherit", color: INK, transition: (step
61
+ ? 'color var(--duration-fast) var(--ease-in-out), transform var(--duration-fast) var(--ease-in-out)'
62
+ : 'color var(--duration-fast) var(--ease-in-out)'), "$group-hover": step ? { color: LIFT, x: 2 } : { color: LIFT }, ...p }));
63
+ exports.Lift = Lift;
64
+ /** A line only offered on approach: hidden at rest, shown while its group is
65
+ * hovered or holds a keyboard's focus — a reveal a keyboard cannot reach is
66
+ * one half of the people never see. */
67
+ const Reveal = ({ render = 'span', ...p }) => ((0, jsx_runtime_1.jsx)(gui_1.Text, { ...(0, slot_1.slot)('reveal'), render: render, display: OWN, whiteSpace: "inherit", color: INK, opacity: 0, transition: 'opacity var(--duration-fast) var(--ease-in-out)', "$group-hover": { opacity: 1 }, "$group-focusVisible": { opacity: 1 }, "$group-focusWithin": { opacity: 1 }, ...p }));
68
+ exports.Reveal = Reveal;
69
+ /** A ruled backdrop, in the foreground ink so it reads on either ground. Two
70
+ * knobs, the pitch and the strength; everything else — where it sits, what
71
+ * masks it — is the caller's props. */
72
+ const Lattice = ({ size = 30, opacity = 0.05, ...p }) => {
73
+ const ink = `color-mix(in srgb, var(--foreground) ${opacity * 100}%, transparent)`;
74
+ return ((0, jsx_runtime_1.jsx)(gui_1.View, { ...(0, slot_1.slot)('lattice'), "aria-hidden": true, backgroundImage: `linear-gradient(to right, ${ink} 1px, transparent 1px), linear-gradient(to bottom, ${ink} 1px, transparent 1px)`, backgroundSize: `${size}px ${size}px`, ...p }));
75
+ };
76
+ exports.Lattice = Lattice;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Surfaces that answer approach, and the marks inside them that answer with
3
+ * them.
4
+ *
5
+ * Leaf a card: a corner, an edge that brightens on hover, no ground
6
+ * Cell a tile of a ruled grid: no corner and no edge, a ground that brightens
7
+ * Lift ink that brightens when its card is hovered; `step` also moves it
8
+ * 2px toward where it goes
9
+ * Reveal a line offered only on approach — hover, or a keyboard's focus
10
+ * Lattice a ruled backdrop: a decorative grid behind a hero
11
+ *
12
+ * A Leaf or a Cell is a gui `group`, and the marks read it with `$group-hover`,
13
+ * so the card decides when and the mark decides how. It is a group and NOT a
14
+ * size container: gui's default `container-type: inline-size` sizes the box as
15
+ * if it were empty, so a card a row sizes by its content — a filter chip —
16
+ * collapsed to its own padding. No mark asks the group its size. An ink written on a mark
17
+ * is a prop beside the hover, so nothing has to out-rank anything: the lift a
18
+ * stylesheet used to apply lost to every atomic `color` a mark carried, and
19
+ * those cards never lifted.
20
+ *
21
+ * Every default is a prop a caller replaces: `p` for the padding, `borderColor`
22
+ * for the resting edge, `hoverStyle` for the approach, `bg` for a ground.
23
+ */
24
+ import { type TextProps, type ViewProps } from '@hanzo/gui';
25
+ import type { Host, Loose } from './loose.js';
26
+ export type SurfaceProps = Loose<Omit<TextProps, 'render' | 'children'>> & Host & {
27
+ render?: TextProps['render'];
28
+ };
29
+ /** A card. The defaults change nothing but the corner and the hover edge: no
30
+ * ground, a transparent resting edge, so a card that names only a ground gets
31
+ * a ground and no lift. */
32
+ declare const Leaf: ({ render, ...p }: SurfaceProps) => import("react").JSX.Element;
33
+ /** A tile of a ruled grid, which rules its own lines with a 1px gap over a
34
+ * neutral ground — so a Cell adds no edge and no corner, which would break the
35
+ * flush rule the grid is made of, and no box: the element keeps the display the
36
+ * document gives it, so a row stays a row and an icon button stays centred. */
37
+ declare const Cell: ({ render, ...p }: SurfaceProps) => import("react").JSX.Element;
38
+ /** Ink that brightens with its card. Inline, like the word or icon it wraps;
39
+ * a mark that steps is a box (`display="inline-flex"`), because an inline box
40
+ * does not move. */
41
+ declare const Lift: ({ render, step, ...p }: SurfaceProps & {
42
+ step?: boolean;
43
+ }) => import("react").JSX.Element;
44
+ /** A line only offered on approach: hidden at rest, shown while its group is
45
+ * hovered or holds a keyboard's focus — a reveal a keyboard cannot reach is
46
+ * one half of the people never see. */
47
+ declare const Reveal: ({ render, ...p }: SurfaceProps) => import("react").JSX.Element;
48
+ export type LatticeProps = Loose<Omit<ViewProps, 'children'>> & {
49
+ /** The pitch of the rule, in px. */
50
+ size?: number;
51
+ /** How much of the foreground ink each line takes, 0..1. */
52
+ opacity?: number;
53
+ };
54
+ /** A ruled backdrop, in the foreground ink so it reads on either ground. Two
55
+ * knobs, the pitch and the strength; everything else — where it sits, what
56
+ * masks it — is the caller's props. */
57
+ declare const Lattice: ({ size, opacity, ...p }: LatticeProps) => import("react").JSX.Element;
58
+ export { Leaf, Cell, Lift, Reveal, Lattice };
59
+ //# sourceMappingURL=surface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surface.d.ts","sourceRoot":"","sources":["../../src/marketing/surface.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAc,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AAGvE,OAAO,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAE1C,MAAM,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,GAAG,UAAU,CAAC,CAAC,GACtE,IAAI,GAAG;IACL,MAAM,CAAC,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAA;CAC7B,CAAA;AAaH;;4BAE4B;AAC5B,QAAA,MAAM,IAAI,qBAAsB,YAAY,gCAsB3C,CAAA;AAED;;;gFAGgF;AAChF,QAAA,MAAM,IAAI,qBAAsB,YAAY,gCAiB3C,CAAA;AAED;;qBAEqB;AACrB,QAAA,MAAM,IAAI,2BAA6C,YAAY,GAAG;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,gCAavF,CAAA;AAED;;wCAEwC;AACxC,QAAA,MAAM,MAAM,qBAA+B,YAAY,gCActD,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,GAAG;IAC9D,oCAAoC;IACpC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED;;wCAEwC;AACxC,QAAA,MAAM,OAAO,4BAAyC,YAAY,gCAWjE,CAAA;AAED,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAA"}
@@ -0,0 +1,70 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ /**
4
+ * Surfaces that answer approach, and the marks inside them that answer with
5
+ * them.
6
+ *
7
+ * Leaf a card: a corner, an edge that brightens on hover, no ground
8
+ * Cell a tile of a ruled grid: no corner and no edge, a ground that brightens
9
+ * Lift ink that brightens when its card is hovered; `step` also moves it
10
+ * 2px toward where it goes
11
+ * Reveal a line offered only on approach — hover, or a keyboard's focus
12
+ * Lattice a ruled backdrop: a decorative grid behind a hero
13
+ *
14
+ * A Leaf or a Cell is a gui `group`, and the marks read it with `$group-hover`,
15
+ * so the card decides when and the mark decides how. It is a group and NOT a
16
+ * size container: gui's default `container-type: inline-size` sizes the box as
17
+ * if it were empty, so a card a row sizes by its content — a filter chip —
18
+ * collapsed to its own padding. No mark asks the group its size. An ink written on a mark
19
+ * is a prop beside the hover, so nothing has to out-rank anything: the lift a
20
+ * stylesheet used to apply lost to every atomic `color` a mark carried, and
21
+ * those cards never lifted.
22
+ *
23
+ * Every default is a prop a caller replaces: `p` for the padding, `borderColor`
24
+ * for the resting edge, `hoverStyle` for the approach, `bg` for a ground.
25
+ */
26
+ import { Text, View } from '@hanzo/gui';
27
+ import { slot } from '../backends/gui/slot.js';
28
+ import { useHost } from './host.js';
29
+ /** The element's own display — what @hanzo/design's base or the browser gives
30
+ * it — under gui Text's `inline`. */
31
+ const OWN = 'revert-layer';
32
+ /** The element's own ink, the same way: @hanzo/design's base gives every `<a>`
33
+ * and every heading `--text-primary`, and anything else takes its parent's. */
34
+ const INK = 'revert-layer';
35
+ /** The lifted ink: white on the dark ground, ink on the light one. */
36
+ const LIFT = 'var(--text-primary)';
37
+ /** A card. The defaults change nothing but the corner and the hover edge: no
38
+ * ground, a transparent resting edge, so a card that names only a ground gets
39
+ * a ground and no lift. */
40
+ const Leaf = ({ render, ...p }) => {
41
+ const host = useHost(render, p.href, 'div');
42
+ return (_jsx(Text, { ...slot('leaf'), group: true, containerType: "normal", render: host, display: "block", height: "100%", whiteSpace: "inherit", textDecorationLine: "none", color: INK, p: "$4", borderWidth: 1, borderStyle: "solid", borderColor: "transparent", rounded: "var(--radius-xl)", hoverStyle: { borderColor: 'var(--white-15)' }, ...p }));
43
+ };
44
+ /** A tile of a ruled grid, which rules its own lines with a 1px gap over a
45
+ * neutral ground — so a Cell adds no edge and no corner, which would break the
46
+ * flush rule the grid is made of, and no box: the element keeps the display the
47
+ * document gives it, so a row stays a row and an icon button stays centred. */
48
+ const Cell = ({ render, ...p }) => {
49
+ const host = useHost(render, p.href, 'div');
50
+ return (_jsx(Text, { ...slot('cell'), group: true, containerType: "normal", render: host, display: OWN, whiteSpace: "inherit", textDecorationLine: "none", bg: "var(--pure-black)", color: "inherit", hoverStyle: { bg: 'var(--neutral-950)' }, ...p }));
51
+ };
52
+ /** Ink that brightens with its card. Inline, like the word or icon it wraps;
53
+ * a mark that steps is a box (`display="inline-flex"`), because an inline box
54
+ * does not move. */
55
+ const Lift = ({ render = 'span', step = false, ...p }) => (_jsx(Text, { ...slot('lift'), render: render, display: OWN, whiteSpace: "inherit", color: INK, transition: (step
56
+ ? 'color var(--duration-fast) var(--ease-in-out), transform var(--duration-fast) var(--ease-in-out)'
57
+ : 'color var(--duration-fast) var(--ease-in-out)'), "$group-hover": step ? { color: LIFT, x: 2 } : { color: LIFT }, ...p }));
58
+ /** A line only offered on approach: hidden at rest, shown while its group is
59
+ * hovered or holds a keyboard's focus — a reveal a keyboard cannot reach is
60
+ * one half of the people never see. */
61
+ const Reveal = ({ render = 'span', ...p }) => (_jsx(Text, { ...slot('reveal'), render: render, display: OWN, whiteSpace: "inherit", color: INK, opacity: 0, transition: 'opacity var(--duration-fast) var(--ease-in-out)', "$group-hover": { opacity: 1 }, "$group-focusVisible": { opacity: 1 }, "$group-focusWithin": { opacity: 1 }, ...p }));
62
+ /** A ruled backdrop, in the foreground ink so it reads on either ground. Two
63
+ * knobs, the pitch and the strength; everything else — where it sits, what
64
+ * masks it — is the caller's props. */
65
+ const Lattice = ({ size = 30, opacity = 0.05, ...p }) => {
66
+ const ink = `color-mix(in srgb, var(--foreground) ${opacity * 100}%, transparent)`;
67
+ return (_jsx(View, { ...slot('lattice'), "aria-hidden": true, backgroundImage: `linear-gradient(to right, ${ink} 1px, transparent 1px), linear-gradient(to bottom, ${ink} 1px, transparent 1px)`, backgroundSize: `${size}px ${size}px`, ...p }));
68
+ };
69
+ export { Leaf, Cell, Lift, Reveal, Lattice };
70
+ //# sourceMappingURL=surface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surface.js","sourceRoot":"","sources":["../../src/marketing/surface.tsx"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  'use client';"use strict";
2
2
  'use client';
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.Line = void 0;
4
+ exports.Claim = exports.Lede = exports.Eyebrow = exports.Title = exports.Display = exports.Line = void 0;
5
5
  const jsx_runtime_1 = require("react/jsx-runtime");
6
6
  /**
7
7
  * Line — one line of type on the marketing ramp.
@@ -15,6 +15,8 @@ const jsx_runtime_1 = require("react/jsx-runtime");
15
15
  * so, and a page with no headings passes every visual check.
16
16
  */
17
17
  const gui_1 = require("@hanzo/gui");
18
+ const slot_1 = require("../backends/gui/slot.cjs");
19
+ const host_1 = require("./host.cjs");
18
20
  const SIZE = {
19
21
  xs: { fontSize: '$1', lineHeight: '$1' },
20
22
  sm: { fontSize: '$2', lineHeight: '$2' },
@@ -33,6 +35,31 @@ const TONE = {
33
35
  };
34
36
  const Line = ({ size, tone = 'plain', weight, align, render, children, ...p }) => {
35
37
  const pair = size ? SIZE[size] : undefined;
36
- return ((0, jsx_runtime_1.jsx)(gui_1.Text, { render: render, fontSize: pair?.fontSize, lineHeight: pair?.lineHeight, fontWeight: weight, color: TONE[tone], text: align, ...p, children: children }));
38
+ const host = (0, host_1.useHost)(render, p.href, 'span');
39
+ return ((0, jsx_runtime_1.jsx)(gui_1.Text, { render: host, fontSize: pair?.fontSize, lineHeight: pair?.lineHeight, fontWeight: weight, color: TONE[tone], text: align, ...p, children: children }));
37
40
  };
38
41
  exports.Line = Line;
42
+ /** The element's own box — a heading's or a paragraph's block, a span's line —
43
+ * which is what the document gives it under gui Text's `inline`. */
44
+ const BLOCK = { display: 'revert-layer', whiteSpace: 'inherit' };
45
+ /** How a heading and a paragraph break: evened out, and no lone last word. A
46
+ * web-only prop, typed once here. */
47
+ const BALANCE = { textWrap: 'balance' };
48
+ const PRETTY = { textWrap: 'pretty' };
49
+ /** The page heading: three rungs of one ramp, 32 / 40 / 52. */
50
+ const Display = ({ render = 'h1', ...p }) => ((0, jsx_runtime_1.jsx)(gui_1.Text, { ...(0, slot_1.slot)('display'), render: render, ...BLOCK, fontFamily: "$heading", fontSize: "$10", fontWeight: '497', lineHeight: '1.19', letterSpacing: '-0.012em', color: "var(--foreground)", ...BALANCE, ...(p.fontSize === undefined ? { $sm: { fontSize: '$11' }, $lg: { fontSize: 'var(--text-6xl)' } } : null), ...p }));
51
+ exports.Display = Display;
52
+ /** The section heading: one size at every width, so it never grows into a page
53
+ * heading. `quiet` is one rung down, for a heading under another section's. */
54
+ const Title = ({ render = 'h2', quiet = false, ...p }) => ((0, jsx_runtime_1.jsx)(gui_1.Text, { ...(0, slot_1.slot)('title'), render: render, ...BLOCK, fontFamily: "$heading", fontSize: quiet ? '$7' : '$8', fontWeight: '497', lineHeight: (quiet ? '1.2' : '1.22'), letterSpacing: '-0.01em', color: "var(--foreground)", ...BALANCE, ...p }));
55
+ exports.Title = Title;
56
+ /** The small caps line above a heading. */
57
+ const Eyebrow = ({ render = 'p', ...p }) => ((0, jsx_runtime_1.jsx)(gui_1.Text, { ...(0, slot_1.slot)('eyebrow'), render: render, ...BLOCK, fontSize: "$2", fontWeight: "500", lineHeight: 'calc(1.25 / 0.875)', letterSpacing: '0.2em', textTransform: "uppercase", color: "var(--muted-foreground)", ...p }));
58
+ exports.Eyebrow = Eyebrow;
59
+ /** The paragraph under a heading. */
60
+ const Lede = ({ render = 'p', ...p }) => ((0, jsx_runtime_1.jsx)(gui_1.Text, { ...(0, slot_1.slot)('lede'), render: render, ...BLOCK, fontSize: "$3", lineHeight: '1.65', letterSpacing: 0, color: "var(--muted-foreground)", ...PRETTY, ...p }));
61
+ exports.Lede = Lede;
62
+ /** The category line under the promise: read second, so bigger and brighter than
63
+ * a lede, a rung up at 640 the way the display above it steps. */
64
+ const Claim = ({ render = 'p', ...p }) => ((0, jsx_runtime_1.jsx)(gui_1.Text, { ...(0, slot_1.slot)('claim'), render: render, ...BLOCK, fontSize: "$7", lineHeight: 'var(--leading-snug)', color: "var(--text-secondary)", ...(p.fontSize === undefined ? { $sm: { fontSize: '$8' } } : null), ...p }));
65
+ exports.Claim = Claim;
@@ -10,7 +10,7 @@
10
10
  * so, and a page with no headings passes every visual check.
11
11
  */
12
12
  import { type TextProps } from '@hanzo/gui';
13
- import type { ReactNode } from 'react';
13
+ import type { Host, Loose } from './loose.js';
14
14
  declare const SIZE: {
15
15
  readonly xs: {
16
16
  readonly fontSize: '$1';
@@ -53,14 +53,53 @@ declare const TONE: {
53
53
  };
54
54
  export type LineSize = keyof typeof SIZE;
55
55
  export type LineTone = keyof typeof TONE;
56
- export type LineProps = Omit<TextProps, 'children' | 'render' | 'color'> & {
56
+ export type LineProps = Loose<Omit<TextProps, 'children' | 'render' | 'color'>> & Host & {
57
57
  size?: LineSize;
58
58
  tone?: LineTone;
59
+ /** An ink of its own, in place of a tone. */
60
+ color?: string;
59
61
  weight?: '400' | '500' | '600' | '700';
60
- render?: 'h1' | 'h2' | 'h3' | 'h4' | 'p' | 'span' | 'div' | 'li' | 'blockquote' | 'cite';
62
+ render?: TextProps['render'];
61
63
  align?: 'center' | 'right';
62
- children?: ReactNode;
63
64
  };
64
65
  declare const Line: ({ size, tone, weight, align, render, children, ...p }: LineProps) => import("react").JSX.Element;
65
66
  export { Line };
67
+ /**
68
+ * The type a page's own copy is set in: the page heading, the section heading,
69
+ * the small caps line above one and the paragraph under it, and the category
70
+ * line under the promise. One rung of @hanzo/design's ramp each, said once here
71
+ * so a call site passes words and spacing, never type.
72
+ *
73
+ * Each is a block of running text: `display="revert-layer"` and
74
+ * `whiteSpace="inherit"` undo gui Text's inline, pre-wrap default, which is
75
+ * right for a label and wrong for a paragraph — the element is the box the
76
+ * document makes it, and takes the white space of the page it sits in. `render` picks the element and defaults to the one the role
77
+ * is — a page heading is an `<h1>` — and accepts an element, so a link or a
78
+ * motion host can carry the role: `render={<motion.p {...reveal} />}`.
79
+ *
80
+ * A stated `fontSize` is the whole size: the display and claim ramps step up at
81
+ * 640 and 1024, and a breakpoint would otherwise re-grow a size the caller set.
82
+ *
83
+ * Hierarchy is by scale, not weight: the headings are book weight (497, the
84
+ * Zen cut that reads as regular at display size) with leading that lets them
85
+ * breathe, and one ink — the heading owns its colour.
86
+ */
87
+ export type RoleProps = Loose<Omit<TextProps, 'render' | 'children'>> & Host & {
88
+ render?: TextProps['render'];
89
+ };
90
+ /** The page heading: three rungs of one ramp, 32 / 40 / 52. */
91
+ declare const Display: ({ render, ...p }: RoleProps) => import("react").JSX.Element;
92
+ /** The section heading: one size at every width, so it never grows into a page
93
+ * heading. `quiet` is one rung down, for a heading under another section's. */
94
+ declare const Title: ({ render, quiet, ...p }: RoleProps & {
95
+ quiet?: boolean;
96
+ }) => import("react").JSX.Element;
97
+ /** The small caps line above a heading. */
98
+ declare const Eyebrow: ({ render, ...p }: RoleProps) => import("react").JSX.Element;
99
+ /** The paragraph under a heading. */
100
+ declare const Lede: ({ render, ...p }: RoleProps) => import("react").JSX.Element;
101
+ /** The category line under the promise: read second, so bigger and brighter than
102
+ * a lede, a rung up at 640 the way the display above it steps. */
103
+ declare const Claim: ({ render, ...p }: RoleProps) => import("react").JSX.Element;
104
+ export { Display, Title, Eyebrow, Lede, Claim };
66
105
  //# sourceMappingURL=type.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../src/marketing/type.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,QAAA,MAAM,IAAI;aACR,EAAE;iBAAI,QAAQ,EAAE,IAAI;iBAAE,UAAU,EAAE,IAAI;;aACtC,EAAE;iBAAI,QAAQ,EAAE,IAAI;iBAAE,UAAU,EAAE,IAAI;;aACtC,IAAI;iBAAI,QAAQ,EAAE,IAAI;iBAAE,UAAU,EAAE,IAAI;;aACxC,EAAE;iBAAI,QAAQ,EAAE,IAAI;iBAAE,UAAU,EAAE,IAAI;;aACtC,EAAE;iBAAI,QAAQ,EAAE,IAAI;iBAAE,UAAU,EAAE,IAAI;;aACtC,EAAE;iBAAI,QAAQ,EAAE,IAAI;iBAAE,UAAU,EAAE,IAAI;;aACtC,EAAE;iBAAI,QAAQ,EAAE,IAAI;iBAAE,UAAU,EAAE,IAAI;;aACtC,EAAE;iBAAI,QAAQ,EAAE,KAAK;iBAAE,UAAU,EAAE,KAAK;;CAChC,CAAA;AAEV,QAAA,MAAM,IAAI;aACR,KAAK,EAAE,MAAM;aACb,KAAK,EAAE,OAAO;aACd,IAAI,EAAE,QAAQ;aACd,GAAG,EAAE,QAAQ;CACL,CAAA;AAEV,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,IAAI,CAAA;AACxC,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,IAAI,CAAA;AAExC,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAC,GAAG;IACzE,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAA;IACtC,MAAM,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,MAAM,GAAG,KAAK,GAAG,IAAI,GAAG,YAAY,GAAG,MAAM,CAAA;IACxF,KAAK,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAA;IAC1B,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB,CAAA;AAED,QAAA,MAAM,IAAI,0DAAqE,SAAS,gCAevF,CAAA;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
1
+ {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../src/marketing/type.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AAKjD,OAAO,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAE1C,QAAA,MAAM,IAAI;aACR,EAAE;iBAAI,QAAQ,EAAE,IAAI;iBAAE,UAAU,EAAE,IAAI;;aACtC,EAAE;iBAAI,QAAQ,EAAE,IAAI;iBAAE,UAAU,EAAE,IAAI;;aACtC,IAAI;iBAAI,QAAQ,EAAE,IAAI;iBAAE,UAAU,EAAE,IAAI;;aACxC,EAAE;iBAAI,QAAQ,EAAE,IAAI;iBAAE,UAAU,EAAE,IAAI;;aACtC,EAAE;iBAAI,QAAQ,EAAE,IAAI;iBAAE,UAAU,EAAE,IAAI;;aACtC,EAAE;iBAAI,QAAQ,EAAE,IAAI;iBAAE,UAAU,EAAE,IAAI;;aACtC,EAAE;iBAAI,QAAQ,EAAE,IAAI;iBAAE,UAAU,EAAE,IAAI;;aACtC,EAAE;iBAAI,QAAQ,EAAE,KAAK;iBAAE,UAAU,EAAE,KAAK;;CAChC,CAAA;AAEV,QAAA,MAAM,IAAI;aACR,KAAK,EAAE,MAAM;aACb,KAAK,EAAE,OAAO;aACd,IAAI,EAAE,QAAQ;aACd,GAAG,EAAE,QAAQ;CACL,CAAA;AAEV,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,IAAI,CAAA;AACxC,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,IAAI,CAAA;AAExC,MAAM,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAC,CAAC,GAC7E,IAAI,GAAG;IACL,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAA;IACtC,MAAM,CAAC,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAA;IAC5B,KAAK,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAA;CAC3B,CAAA;AAEH,QAAA,MAAM,IAAI,0DAAqE,SAAS,gCAgBvF,CAAA;AAED,OAAO,EAAE,IAAI,EAAE,CAAA;AAEf;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,GAAG,UAAU,CAAC,CAAC,GACnE,IAAI,GAAG;IACL,MAAM,CAAC,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAA;CAC7B,CAAA;AAWH,+DAA+D;AAC/D,QAAA,MAAM,OAAO,qBAA6B,SAAS,gCAelD,CAAA;AAED;gFACgF;AAChF,QAAA,MAAM,KAAK,4BAA4C,SAAS,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,gCAcrF,CAAA;AAED,2CAA2C;AAC3C,QAAA,MAAM,OAAO,qBAA4B,SAAS,gCAajD,CAAA;AAED,qCAAqC;AACrC,QAAA,MAAM,IAAI,qBAA4B,SAAS,gCAY9C,CAAA;AAED;mEACmE;AACnE,QAAA,MAAM,KAAK,qBAA4B,SAAS,gCAW/C,CAAA;AAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA"}
@@ -12,6 +12,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
12
12
  * so, and a page with no headings passes every visual check.
13
13
  */
14
14
  import { Text } from '@hanzo/gui';
15
+ import { slot } from '../backends/gui/slot.js';
16
+ import { useHost } from './host.js';
15
17
  const SIZE = {
16
18
  xs: { fontSize: '$1', lineHeight: '$1' },
17
19
  sm: { fontSize: '$2', lineHeight: '$2' },
@@ -30,7 +32,28 @@ const TONE = {
30
32
  };
31
33
  const Line = ({ size, tone = 'plain', weight, align, render, children, ...p }) => {
32
34
  const pair = size ? SIZE[size] : undefined;
33
- return (_jsx(Text, { render: render, fontSize: pair?.fontSize, lineHeight: pair?.lineHeight, fontWeight: weight, color: TONE[tone], text: align, ...p, children: children }));
35
+ const host = useHost(render, p.href, 'span');
36
+ return (_jsx(Text, { render: host, fontSize: pair?.fontSize, lineHeight: pair?.lineHeight, fontWeight: weight, color: TONE[tone], text: align, ...p, children: children }));
34
37
  };
35
38
  export { Line };
39
+ /** The element's own box — a heading's or a paragraph's block, a span's line —
40
+ * which is what the document gives it under gui Text's `inline`. */
41
+ const BLOCK = { display: 'revert-layer', whiteSpace: 'inherit' };
42
+ /** How a heading and a paragraph break: evened out, and no lone last word. A
43
+ * web-only prop, typed once here. */
44
+ const BALANCE = { textWrap: 'balance' };
45
+ const PRETTY = { textWrap: 'pretty' };
46
+ /** The page heading: three rungs of one ramp, 32 / 40 / 52. */
47
+ const Display = ({ render = 'h1', ...p }) => (_jsx(Text, { ...slot('display'), render: render, ...BLOCK, fontFamily: "$heading", fontSize: "$10", fontWeight: '497', lineHeight: '1.19', letterSpacing: '-0.012em', color: "var(--foreground)", ...BALANCE, ...(p.fontSize === undefined ? { $sm: { fontSize: '$11' }, $lg: { fontSize: 'var(--text-6xl)' } } : null), ...p }));
48
+ /** The section heading: one size at every width, so it never grows into a page
49
+ * heading. `quiet` is one rung down, for a heading under another section's. */
50
+ const Title = ({ render = 'h2', quiet = false, ...p }) => (_jsx(Text, { ...slot('title'), render: render, ...BLOCK, fontFamily: "$heading", fontSize: quiet ? '$7' : '$8', fontWeight: '497', lineHeight: (quiet ? '1.2' : '1.22'), letterSpacing: '-0.01em', color: "var(--foreground)", ...BALANCE, ...p }));
51
+ /** The small caps line above a heading. */
52
+ const Eyebrow = ({ render = 'p', ...p }) => (_jsx(Text, { ...slot('eyebrow'), render: render, ...BLOCK, fontSize: "$2", fontWeight: "500", lineHeight: 'calc(1.25 / 0.875)', letterSpacing: '0.2em', textTransform: "uppercase", color: "var(--muted-foreground)", ...p }));
53
+ /** The paragraph under a heading. */
54
+ const Lede = ({ render = 'p', ...p }) => (_jsx(Text, { ...slot('lede'), render: render, ...BLOCK, fontSize: "$3", lineHeight: '1.65', letterSpacing: 0, color: "var(--muted-foreground)", ...PRETTY, ...p }));
55
+ /** The category line under the promise: read second, so bigger and brighter than
56
+ * a lede, a rung up at 640 the way the display above it steps. */
57
+ const Claim = ({ render = 'p', ...p }) => (_jsx(Text, { ...slot('claim'), render: render, ...BLOCK, fontSize: "$7", lineHeight: 'var(--leading-snug)', color: "var(--text-secondary)", ...(p.fontSize === undefined ? { $sm: { fontSize: '$8' } } : null), ...p }));
58
+ export { Display, Title, Eyebrow, Lede, Claim };
36
59
  //# sourceMappingURL=type.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"type.js","sourceRoot":"","sources":["../../src/marketing/type.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;;;;;;;GAUG;AACH,OAAO,EAAE,IAAI,EAAkB,MAAM,YAAY,CAAA;AAGjD,MAAM,IAAI,GAAG;IACX,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;IACxC,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;IACxC,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;IAC1C,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;IACxC,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;IACxC,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;IACxC,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;IACxC,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE;CAClC,CAAA;AAEV,MAAM,IAAI,GAAG;IACX,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,QAAQ;IACd,GAAG,EAAE,QAAQ;CACL,CAAA;AAcV,MAAM,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,EAAa,EAAE,EAAE;IAC1F,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC1C,OAAO,CACL,KAAC,IAAI,IACH,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,IAAI,EAAE,QAAQ,EACxB,UAAU,EAAE,IAAI,EAAE,UAAU,EAC5B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,EACjB,IAAI,EAAE,KAAK,KACN,CAAY,YAEhB,QAAQ,GACJ,CACR,CAAA;AACH,CAAC,CAAA;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
1
+ {"version":3,"file":"type.js","sourceRoot":"","sources":["../../src/marketing/type.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ /* @hanzo/ui document — the body of a long document: a policy, a set of terms, an
2
+ explanation authored in markdown.
3
+
4
+ Import once at the app root: import '@hanzo/ui/styles/document.css'
5
+
6
+ KEYED ON `data-slot='document'`, NEVER ON A CLASS. `<Document>` stamps the
7
+ slot. The content arrives as bare tags rendered from markdown, which is the
8
+ one case no prop can reach, so these rules select by tag from the container.
9
+ Everything else on a page is props.
10
+
11
+ A contents list in a <nav> is chrome, and its links do not underline. A
12
+ table is the one thing that can outgrow its column, and nothing wraps it, so
13
+ the scroll goes on the table itself. */
14
+
15
+ [data-slot='document'] {
16
+ display: flex;
17
+ flex-direction: column;
18
+ gap: var(--space-4);
19
+ font-size: var(--text-base);
20
+ line-height: var(--leading-relaxed);
21
+ color: var(--muted-foreground);
22
+ }
23
+
24
+ [data-slot='document'] a {
25
+ color: var(--foreground);
26
+ text-underline-offset: 4px;
27
+ }
28
+
29
+ [data-slot='document'] a:not(:is(nav, aside, header, [role=navigation]) a) {
30
+ text-decoration: underline;
31
+ }
32
+
33
+ [data-slot='document'] :is(strong, th) {
34
+ font-weight: var(--weight-medium);
35
+ color: var(--foreground);
36
+ }
37
+
38
+ [data-slot='document'] :is(h2, h3) {
39
+ font-weight: var(--weight-medium);
40
+ color: var(--foreground);
41
+ }
42
+
43
+ [data-slot='document'] h2 {
44
+ margin-top: var(--space-6);
45
+ font-size: var(--text-xl);
46
+ }
47
+
48
+ [data-slot='document'] h3 {
49
+ margin-top: var(--space-4);
50
+ font-size: var(--text-base);
51
+ }
52
+
53
+ [data-slot='document'] ul { list-style: disc; }
54
+ [data-slot='document'] ol { list-style: decimal; }
55
+
56
+ [data-slot='document'] :is(ul, ol) {
57
+ display: flex;
58
+ flex-direction: column;
59
+ gap: var(--space-2);
60
+ padding-left: var(--space-5);
61
+ }
62
+
63
+ [data-slot='document'] blockquote {
64
+ padding: var(--space-4);
65
+ border: 1px solid var(--border);
66
+ border-radius: var(--radius-lg);
67
+ background-color: var(--secondary);
68
+ }
69
+
70
+ [data-slot='document'] code {
71
+ font-family: var(--font-mono);
72
+ font-size: var(--text-sm);
73
+ color: var(--foreground);
74
+ }
75
+
76
+ [data-slot='document'] hr {
77
+ border: 0;
78
+ border-top: 1px solid var(--border);
79
+ }
80
+
81
+ [data-slot='document'] table {
82
+ display: block;
83
+ overflow-x: auto;
84
+ border-collapse: collapse;
85
+ font-size: var(--text-sm);
86
+ }
87
+
88
+ [data-slot='document'] :is(th, td) {
89
+ padding: var(--space-2) var(--space-3);
90
+ border: 1px solid var(--border);
91
+ text-align: start;
92
+ vertical-align: top;
93
+ }