@hanzo/ui 8.17.0 → 8.18.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.
@@ -128,12 +128,21 @@ const ScreenfulBlockComponent = ({ block, agent, initialInView = false, snapTile
128
128
  const video = b.banner && typeof b.banner === 'object';
129
129
  const oneColumn = b.contentColumns.length === 1;
130
130
  const vertCenter = spec('vert-center');
131
+ // The gutter GROWS with the viewport. It used to be `px-[8vw] xl:px-[1vw]`,
132
+ // which shrank from 8% of the screen to 1% at exactly the width where there
133
+ // is most room — measured at 1280px: 13px of margin and 82 characters to the
134
+ // line. `--gutter` is a clamp, so it opens up to 6rem and stops.
131
135
  const gutters = spec('narrow-gutters')
132
- ? (0, cn_1.cn)('px-6 lg:px-8 2xl:px-2 pb-4 lg:pb-6 xl:pb-8', snapTile && 'pt-15 md:pt-26 lg:pt-28')
136
+ ? (0, cn_1.cn)('px-6 lg:px-8 pb-4 lg:pb-6 xl:pb-8', snapTile && 'pt-15 md:pt-26 lg:pt-28')
133
137
  : spec('no-gutters')
134
138
  ? (0, cn_1.cn)('px-0 pb-0', snapTile && 'pt-11 lg:pt-20')
135
- : 'px-[8vw] xl:px-[1vw] pb-[8vh] pt-[calc(44px+4vh)] md:pt-[calc(80px+6vh)]';
136
- return ((0, jsx_runtime_1.jsxs)(box_1.Box, { tag: "section", ...(b.anchorId ? { id: b.anchorId } : {}), className: (0, cn_1.cn)(snapTile ? 'snap-start snap-always h-[100vh]' : 'min-h-screen', bottom && 'flex flex-col', className), children: [(0, jsx_runtime_1.jsx)(prose_1.ApplyTypography, { className: (0, cn_1.cn)('w-full flex flex-row justify-center self-stretch', snapTile && (agent === 'desktop' ? 'h-full' : 'h-[100svh]'), bottom && 'grow'), children: (0, jsx_runtime_1.jsxs)(Poster, { banner: b.banner, children: [video && ((0, jsx_runtime_1.jsx)(Backdrop, { block: b.banner, className: "absolute top-0 left-0 bottom-0 right-0", initialInView: initialInView })), (0, jsx_runtime_1.jsxs)(box_1.Box, { className: (0, cn_1.cn)('xl:mx-auto overflow-y-hidden h-full', !spec('full-screen-width') && 'max-w-screen-xl', gutters, agent && agent !== 'desktop' && 'pt-15 sm:pt-17 pb-0 px-3 sm:px-8', snapTile ? 'absolute left-0 right-0 top-0 bottom-0' : 'flex min-h-screen w-full', contentClassName, vertCenter && (0, cn_1.cn)('self-center', oneColumn && 'py-0')), children: [(0, jsx_runtime_1.jsx)(Columns, { block: b, agent: agent, className: "w-full" }), b.footer] })] }) }), bottom] }));
139
+ : 'px-[var(--gutter)] pb-[8vh] pt-[calc(44px+4vh)] md:pt-[calc(80px+6vh)]';
140
+ return ((0, jsx_runtime_1.jsxs)(box_1.Box, { tag: "section", ...(b.anchorId ? { id: b.anchorId } : {}), className: (0, cn_1.cn)(snapTile ? 'snap-start snap-always h-[100vh]' : 'min-h-screen', bottom && 'flex flex-col', className), children: [(0, jsx_runtime_1.jsx)(prose_1.ApplyTypography, { className: (0, cn_1.cn)('w-full flex flex-row justify-center self-stretch', snapTile && (agent === 'desktop' ? 'h-full' : 'h-[100svh]'), bottom && 'grow'), children: (0, jsx_runtime_1.jsxs)(Poster, { banner: b.banner, children: [video && ((0, jsx_runtime_1.jsx)(Backdrop, { block: b.banner, className: "absolute top-0 left-0 bottom-0 right-0", initialInView: initialInView })), (0, jsx_runtime_1.jsxs)(box_1.Box, { className: (0, cn_1.cn)('xl:mx-auto overflow-y-hidden h-full',
141
+ // `max-w-screen-xl` is 1280px — exactly the width most desktops
142
+ // are, so it capped nothing where it mattered. `--frame` is wider
143
+ // and is a real bound: the composition stops, the gutter takes the
144
+ // rest, and the column centres.
145
+ !spec('full-screen-width') && 'max-w-[var(--frame)]', gutters, agent && agent !== 'desktop' && 'pt-15 sm:pt-17 pb-0 px-3 sm:px-8', snapTile ? 'absolute left-0 right-0 top-0 bottom-0' : 'flex min-h-screen w-full', contentClassName, vertCenter && (0, cn_1.cn)('self-center', oneColumn && 'py-0')), children: [(0, jsx_runtime_1.jsx)(Columns, { block: b, agent: agent, className: "w-full" }), b.footer] })] }) }), bottom] }));
137
146
  };
138
147
  exports.ScreenfulBlockComponent = ScreenfulBlockComponent;
139
148
  exports.default = exports.ScreenfulBlockComponent;
@@ -1 +1 @@
1
- {"version":3,"file":"screenful.d.ts","sourceRoot":"","sources":["../../src/blocks/screenful.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAO9B,OAAO,EAAE,KAAK,mBAAmB,EAAO,MAAM,QAAQ,CAAA;AA0KtD;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,oFAQjC,mBAAmB,GAAG;IACvB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CACzB,4CA2DA,CAAA;eAEc,uBAAuB"}
1
+ {"version":3,"file":"screenful.d.ts","sourceRoot":"","sources":["../../src/blocks/screenful.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAO9B,OAAO,EAAE,KAAK,mBAAmB,EAAO,MAAM,QAAQ,CAAA;AA0KtD;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,oFAQjC,mBAAmB,GAAG;IACvB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CACzB,4CAmEA,CAAA;eAEc,uBAAuB"}
@@ -92,12 +92,21 @@ export const ScreenfulBlockComponent = ({ block, agent, initialInView = false, s
92
92
  const video = b.banner && typeof b.banner === 'object';
93
93
  const oneColumn = b.contentColumns.length === 1;
94
94
  const vertCenter = spec('vert-center');
95
+ // The gutter GROWS with the viewport. It used to be `px-[8vw] xl:px-[1vw]`,
96
+ // which shrank from 8% of the screen to 1% at exactly the width where there
97
+ // is most room — measured at 1280px: 13px of margin and 82 characters to the
98
+ // line. `--gutter` is a clamp, so it opens up to 6rem and stops.
95
99
  const gutters = spec('narrow-gutters')
96
- ? cn('px-6 lg:px-8 2xl:px-2 pb-4 lg:pb-6 xl:pb-8', snapTile && 'pt-15 md:pt-26 lg:pt-28')
100
+ ? cn('px-6 lg:px-8 pb-4 lg:pb-6 xl:pb-8', snapTile && 'pt-15 md:pt-26 lg:pt-28')
97
101
  : spec('no-gutters')
98
102
  ? cn('px-0 pb-0', snapTile && 'pt-11 lg:pt-20')
99
- : 'px-[8vw] xl:px-[1vw] pb-[8vh] pt-[calc(44px+4vh)] md:pt-[calc(80px+6vh)]';
100
- return (_jsxs(Box, { tag: "section", ...(b.anchorId ? { id: b.anchorId } : {}), className: cn(snapTile ? 'snap-start snap-always h-[100vh]' : 'min-h-screen', bottom && 'flex flex-col', className), children: [_jsx(ApplyTypography, { className: cn('w-full flex flex-row justify-center self-stretch', snapTile && (agent === 'desktop' ? 'h-full' : 'h-[100svh]'), bottom && 'grow'), children: _jsxs(Poster, { banner: b.banner, children: [video && (_jsx(Backdrop, { block: b.banner, className: "absolute top-0 left-0 bottom-0 right-0", initialInView: initialInView })), _jsxs(Box, { className: cn('xl:mx-auto overflow-y-hidden h-full', !spec('full-screen-width') && 'max-w-screen-xl', gutters, agent && agent !== 'desktop' && 'pt-15 sm:pt-17 pb-0 px-3 sm:px-8', snapTile ? 'absolute left-0 right-0 top-0 bottom-0' : 'flex min-h-screen w-full', contentClassName, vertCenter && cn('self-center', oneColumn && 'py-0')), children: [_jsx(Columns, { block: b, agent: agent, className: "w-full" }), b.footer] })] }) }), bottom] }));
103
+ : 'px-[var(--gutter)] pb-[8vh] pt-[calc(44px+4vh)] md:pt-[calc(80px+6vh)]';
104
+ return (_jsxs(Box, { tag: "section", ...(b.anchorId ? { id: b.anchorId } : {}), className: cn(snapTile ? 'snap-start snap-always h-[100vh]' : 'min-h-screen', bottom && 'flex flex-col', className), children: [_jsx(ApplyTypography, { className: cn('w-full flex flex-row justify-center self-stretch', snapTile && (agent === 'desktop' ? 'h-full' : 'h-[100svh]'), bottom && 'grow'), children: _jsxs(Poster, { banner: b.banner, children: [video && (_jsx(Backdrop, { block: b.banner, className: "absolute top-0 left-0 bottom-0 right-0", initialInView: initialInView })), _jsxs(Box, { className: cn('xl:mx-auto overflow-y-hidden h-full',
105
+ // `max-w-screen-xl` is 1280px — exactly the width most desktops
106
+ // are, so it capped nothing where it mattered. `--frame` is wider
107
+ // and is a real bound: the composition stops, the gutter takes the
108
+ // rest, and the column centres.
109
+ !spec('full-screen-width') && 'max-w-[var(--frame)]', gutters, agent && agent !== 'desktop' && 'pt-15 sm:pt-17 pb-0 px-3 sm:px-8', snapTile ? 'absolute left-0 right-0 top-0 bottom-0' : 'flex min-h-screen w-full', contentClassName, vertCenter && cn('self-center', oneColumn && 'py-0')), children: [_jsx(Columns, { block: b, agent: agent, className: "w-full" }), b.footer] })] }) }), bottom] }));
101
110
  };
102
111
  export default ScreenfulBlockComponent;
103
112
  //# sourceMappingURL=screenful.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"screenful.js","sourceRoot":"","sources":["../../src/blocks/screenful.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"screenful.js","sourceRoot":"","sources":["../../src/blocks/screenful.tsx"],"names":[],"mappings":"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"}
package/dist/gallery.html CHANGED
@@ -1,4 +1,4 @@
1
- <!doctype html><html lang="en" class="t_dark"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>@hanzo/ui 8.17.0</title><style>/* @hanzo/ui — generated by scripts/gen-css.mjs. Do not edit. */
1
+ <!doctype html><html lang="en" class="t_dark"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>@hanzo/ui 8.18.0</title><style>/* @hanzo/ui — generated by scripts/gen-css.mjs. Do not edit. */
2
2
  :root { --hanzo-ui-styles: 1; }
3
3
  /* Hanzo Design System — the entry point. Import THIS one file.
4
4
  *
@@ -1725,6 +1725,73 @@
1725
1725
  border-bottom-right-radius: 0 !important;
1726
1726
  }
1727
1727
 
1728
+ /* ── The crease — the valley where one sheet lies over another ───────────────
1729
+ The ladder lifts a sheet with a drop that falls STRAIGHT DOWN: design's rule
1730
+ is one light, above, and `check-tokens.mjs` fails the build on a sideways
1731
+ offset. That is right, and it means the ladder has nothing to say about a
1732
+ VERTICAL seam — and an app shell is nothing but vertical seams. A rail beside
1733
+ a sidebar beside a pane, each a step apart on the ladder, still reads as three
1734
+ abutting rectangles with lines ruled between them, because the only mark at
1735
+ the seam is the hairline.
1736
+
1737
+ What a real sheet lays on the one beneath it, side by side under a light from
1738
+ above, is not a cast shadow — it is the valley going dark. Ambient occlusion
1739
+ has no direction of its own, which is both why it is honest here and why it is
1740
+ NOT spelled as a --shadow-*: those are directional by definition and this is
1741
+ not one.
1742
+
1743
+ A PSEUDO-ELEMENT, at z-index -1 inside an isolated stacking context, so it
1744
+ paints above the sheet's own fill and below every child. That ordering is the
1745
+ whole reason it is not a `background-image` (which `.fold` already claims on
1746
+ this same element, !important, so the two would silently fight) and not an
1747
+ inset `box-shadow` (which `.elevation-*` claims, likewise).
1748
+
1749
+ No side named -> both edges, which is what a pane with a neighbour on each
1750
+ hand needs. Name one and the other stops being drawn. */
1751
+ :root {
1752
+ --crease-ink: rgb(0 0 0 / .28);
1753
+ --crease-depth: 20px;
1754
+ }
1755
+
1756
+ .light, :root.t_light, .t_light {
1757
+ /* On white the valley is a smudge, not a shadow — the same redistribution the
1758
+ drops make, and for the same reason. */
1759
+ --crease-ink: rgb(0 0 0 / .05);
1760
+ }
1761
+
1762
+ .hz-crease {
1763
+ position: relative;
1764
+ /* Without this the -1 escapes and paints behind an ancestor's fill, which is
1765
+ indistinguishable from the crease not being there at all. */
1766
+ isolation: isolate;
1767
+ }
1768
+
1769
+ .hz-crease::before,
1770
+ .hz-crease::after {
1771
+ content: "";
1772
+ position: absolute;
1773
+ top: 0;
1774
+ bottom: 0;
1775
+ width: var(--crease-depth);
1776
+ z-index: -1;
1777
+ pointer-events: none;
1778
+ }
1779
+
1780
+ .hz-crease::before {
1781
+ left: 0;
1782
+ background-image: linear-gradient(to right, var(--crease-ink), transparent);
1783
+ }
1784
+
1785
+ .hz-crease::after {
1786
+ right: 0;
1787
+ background-image: linear-gradient(to left, var(--crease-ink), transparent);
1788
+ }
1789
+
1790
+ .hz-crease[data-crease="left"]::after,
1791
+ .hz-crease[data-crease="right"]::before {
1792
+ content: none;
1793
+ }
1794
+
1728
1795
  /* ── The scrim ──────────────────────────────────────────────────────────────
1729
1796
  The dim that makes a floating panel read as floating rather than as more
1730
1797
  page. gui's overlay dims TWICE — a translucent ground under a further
@@ -2091,6 +2158,41 @@ input::-webkit-search-cancel-button,input::-webkit-search-decoration,input::-web
2091
2158
  * in a token or a component.
2092
2159
  */
2093
2160
 
2161
+ /* ── The measure ──────────────────────────────────────────────────────────
2162
+ How wide a thing is allowed to get, which the token set had no answer for.
2163
+ Type and spacing were both tokenised; width was left to whatever class the
2164
+ page happened to carry, and the lux slides ended up setting 82 characters to
2165
+ the line at 1280px with 13px of gutter — the viewport, not a column.
2166
+
2167
+ Three values, because a page needs three different widths:
2168
+
2169
+ --measure running text. 68 characters is the top of the comfortable
2170
+ range; past it the eye loses its place on the line return.
2171
+ In `ch` so it follows the type rather than fighting it.
2172
+ --frame the outer bound of a full-width composition — a slide, a
2173
+ header, a footer. Wider than the measure because a two-column
2174
+ layout is not running text.
2175
+ --gutter the margin outside the frame. It GROWS with the viewport: a
2176
+ wider screen should give the content more air, not less. The
2177
+ lux slides had this inverted — 8vw below xl, 1vw above — so
2178
+ the design got tighter exactly as the room appeared. */
2179
+ :root {
2180
+ --measure: 68ch;
2181
+ --frame: 90rem;
2182
+ --gutter: clamp(1.25rem, 5vw, 6rem);
2183
+ }
2184
+
2185
+ /* Running text is bounded; a heading is not. A heading is short, and the width
2186
+ is what gives it presence — so only the elements that set paragraphs are
2187
+ capped. A max-width can never make something wider, so this is safe inside a
2188
+ card or a column that is already narrower. */
2189
+ .hz-prose > p,
2190
+ .hz-prose > ul,
2191
+ .hz-prose > ol,
2192
+ .hz-prose > blockquote {
2193
+ max-width: var(--measure);
2194
+ }
2195
+
2094
2196
  *,
2095
2197
  *::before,
2096
2198
  *::after {
@@ -2370,6 +2472,52 @@ body {
2370
2472
  }
2371
2473
  }
2372
2474
 
2475
+ /* ── Unfold — how a sheet arrives ─────────────────────────────────────────────
2476
+ A panel that appears by fading is a rectangle switching on. A sheet of paper
2477
+ arrives by TURNING OPEN about the edge it is hinged on, so its near edge swings
2478
+ toward the reader and its far edge stays put — which is the one motion that
2479
+ says "this was already here, folded" rather than "this was drawn just now".
2480
+
2481
+ The hinge is the ONLY thing that varies, so it is the only knob: a drawer
2482
+ coming off the left wall turns about its left edge, a pane folding in from the
2483
+ right about its right. The angle follows the hinge — a sheet swings toward you
2484
+ from whichever side it is held — so naming the hinge sets both, and there is no
2485
+ way to ask for a turn that opens the wrong way.
2486
+
2487
+ `perspective()` inside the transform rather than on a parent: the vanishing
2488
+ point is then the sheet's own centre, so the turn reads at any size and the
2489
+ caller does not have to own a 3D context it did not ask for.
2490
+
2491
+ Seven degrees over 220ms. Enough to see the plane; short of the swinging-door
2492
+ effect that makes a workspace feel like a slideshow. */
2493
+ @keyframes hz-unfold {
2494
+ from {
2495
+ opacity: 0;
2496
+ transform: perspective(1600px) rotateY(var(--hz-turn, -7deg));
2497
+ }
2498
+ to {
2499
+ opacity: 1;
2500
+ transform: perspective(1600px) rotateY(0deg);
2501
+ }
2502
+ }
2503
+
2504
+ .hz-unfold {
2505
+ animation: hz-unfold 220ms cubic-bezier(0.2, 0.7, 0.3, 1) both;
2506
+ transform-origin: left center;
2507
+ will-change: transform, opacity;
2508
+ }
2509
+
2510
+ .hz-unfold[data-hinge="right"] {
2511
+ transform-origin: right center;
2512
+ --hz-turn: 7deg;
2513
+ }
2514
+
2515
+ @media (prefers-reduced-motion: reduce) {
2516
+ .hz-unfold {
2517
+ animation: none;
2518
+ }
2519
+ }
2520
+
2373
2521
  /* ── Layout guarantees ─────────────────────────────────────────────────────────
2374
2522
  Two rules, both structural. They are attached to `data-slot` rather than to a
2375
2523
  class because they are not styling a caller can opt out of — they are the
package/dist/glass.cjs CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.screen = exports.accent = exports.selected = exports.row = exports.rows = exports.panel = exports.scrim = exports.fold = exports.sheet = exports.glass = void 0;
3
+ exports.screen = exports.accent = exports.selected = exports.row = exports.rows = exports.panel = exports.scrim = exports.fold = exports.unfold = exports.crease = exports.sheet = exports.glass = void 0;
4
+ exports.paper = paper;
4
5
  /**
5
6
  * The chrome, as values — `@hanzo/ui/glass`.
6
7
  *
@@ -107,6 +108,51 @@ const SHEET_FILL = {
107
108
  1: 'var(--sheet-1, rgb(38 38 38 / .5))',
108
109
  2: 'var(--sheet-2, rgb(38 38 38 / .75))',
109
110
  };
111
+ /**
112
+ * The crease — the valley where a neighbouring sheet lies over this one.
113
+ *
114
+ * <YStack {...paper(sheet(0), crease('right'))}>
115
+ *
116
+ * The ladder's drops fall straight down (design's rule is one light, above), so
117
+ * it has nothing to say about a VERTICAL seam — and an app shell is nothing but
118
+ * vertical seams. Three sheets a rung apart, side by side, still read as three
119
+ * abutting rectangles. This is the mark that makes them read as paper: the
120
+ * ground going dark in the valley, which is what a sheet actually lays on the
121
+ * one beside it.
122
+ *
123
+ * It goes on the sheet that is COVERED, on the edge the neighbour lies over —
124
+ * a rail with a sidebar to its right takes `crease('right')`. Nothing can paint
125
+ * outside its own box, so the receiver draws it; the caster only has to be
126
+ * higher up the ladder.
127
+ *
128
+ * Spend it at a seam and nowhere else. A crease down the side of a card with
129
+ * nothing beside it is a gradient somebody liked.
130
+ */
131
+ const crease = (edge) => ({ className: 'hz-crease', ...(edge ? { 'data-crease': edge } : {}) });
132
+ exports.crease = crease;
133
+ /**
134
+ * Unfold — how a sheet ARRIVES: turning open about the edge it is hinged on,
135
+ * rather than fading up as a rectangle.
136
+ *
137
+ * <YStack {...paper(sheet(2), unfold('right'))}>
138
+ *
139
+ * The hinge is the only knob, and it sets the direction of the turn with it, so
140
+ * a sheet cannot be asked to swing the wrong way. A drawer off the left wall is
141
+ * `unfold()`; a pane folding in from the right edge is `unfold('right')`.
142
+ *
143
+ * Motion only — it says nothing about what the surface is made of, so it
144
+ * composes with `sheet`, `glass` or neither. Off under reduced motion, in
145
+ * `styles/motion.css` beside every other keyframe this package ships.
146
+ */
147
+ const unfold = (hinge = 'left') => ({ className: 'hz-unfold', ...(hinge === 'right' ? { 'data-hinge': 'right' } : {}) });
148
+ exports.unfold = unfold;
149
+ function paper(...marks) {
150
+ const className = marks
151
+ .map((mark) => mark.className)
152
+ .filter(Boolean)
153
+ .join(' ');
154
+ return { ...Object.assign({}, ...marks), ...(className ? { className } : {}) };
155
+ }
110
156
  /**
111
157
  * The fold — a corner turned back, and the ONE mark that says an item opens.
112
158
  *
package/dist/glass.css CHANGED
@@ -244,6 +244,73 @@
244
244
  border-bottom-right-radius: 0 !important;
245
245
  }
246
246
 
247
+ /* ── The crease — the valley where one sheet lies over another ───────────────
248
+ The ladder lifts a sheet with a drop that falls STRAIGHT DOWN: design's rule
249
+ is one light, above, and `check-tokens.mjs` fails the build on a sideways
250
+ offset. That is right, and it means the ladder has nothing to say about a
251
+ VERTICAL seam — and an app shell is nothing but vertical seams. A rail beside
252
+ a sidebar beside a pane, each a step apart on the ladder, still reads as three
253
+ abutting rectangles with lines ruled between them, because the only mark at
254
+ the seam is the hairline.
255
+
256
+ What a real sheet lays on the one beneath it, side by side under a light from
257
+ above, is not a cast shadow — it is the valley going dark. Ambient occlusion
258
+ has no direction of its own, which is both why it is honest here and why it is
259
+ NOT spelled as a --shadow-*: those are directional by definition and this is
260
+ not one.
261
+
262
+ A PSEUDO-ELEMENT, at z-index -1 inside an isolated stacking context, so it
263
+ paints above the sheet's own fill and below every child. That ordering is the
264
+ whole reason it is not a `background-image` (which `.fold` already claims on
265
+ this same element, !important, so the two would silently fight) and not an
266
+ inset `box-shadow` (which `.elevation-*` claims, likewise).
267
+
268
+ No side named -> both edges, which is what a pane with a neighbour on each
269
+ hand needs. Name one and the other stops being drawn. */
270
+ :root {
271
+ --crease-ink: rgb(0 0 0 / .28);
272
+ --crease-depth: 20px;
273
+ }
274
+
275
+ .light, :root.t_light, .t_light {
276
+ /* On white the valley is a smudge, not a shadow — the same redistribution the
277
+ drops make, and for the same reason. */
278
+ --crease-ink: rgb(0 0 0 / .05);
279
+ }
280
+
281
+ .hz-crease {
282
+ position: relative;
283
+ /* Without this the -1 escapes and paints behind an ancestor's fill, which is
284
+ indistinguishable from the crease not being there at all. */
285
+ isolation: isolate;
286
+ }
287
+
288
+ .hz-crease::before,
289
+ .hz-crease::after {
290
+ content: "";
291
+ position: absolute;
292
+ top: 0;
293
+ bottom: 0;
294
+ width: var(--crease-depth);
295
+ z-index: -1;
296
+ pointer-events: none;
297
+ }
298
+
299
+ .hz-crease::before {
300
+ left: 0;
301
+ background-image: linear-gradient(to right, var(--crease-ink), transparent);
302
+ }
303
+
304
+ .hz-crease::after {
305
+ right: 0;
306
+ background-image: linear-gradient(to left, var(--crease-ink), transparent);
307
+ }
308
+
309
+ .hz-crease[data-crease="left"]::after,
310
+ .hz-crease[data-crease="right"]::before {
311
+ content: none;
312
+ }
313
+
247
314
  /* ── The scrim ──────────────────────────────────────────────────────────────
248
315
  The dim that makes a floating panel read as floating rather than as more
249
316
  page. gui's overlay dims TWICE — a translucent ground under a further
package/dist/glass.d.ts CHANGED
@@ -75,6 +75,76 @@ export declare const sheet: (level?: 0 | 1 | 2) => {
75
75
  readonly backgroundColor: "var(--sheet-0, #0a0a0a)" | "var(--sheet-1, rgb(38 38 38 / .5))" | "var(--sheet-2, rgb(38 38 38 / .75))";
76
76
  readonly className?: "elevation-1" | "elevation-2" | undefined;
77
77
  };
78
+ /**
79
+ * Which of a surface's edges lies UNDER a neighbour. Omit for both, which is
80
+ * what a pane between two other panes needs.
81
+ */
82
+ export type Edge = 'left' | 'right';
83
+ /**
84
+ * The crease — the valley where a neighbouring sheet lies over this one.
85
+ *
86
+ * <YStack {...paper(sheet(0), crease('right'))}>
87
+ *
88
+ * The ladder's drops fall straight down (design's rule is one light, above), so
89
+ * it has nothing to say about a VERTICAL seam — and an app shell is nothing but
90
+ * vertical seams. Three sheets a rung apart, side by side, still read as three
91
+ * abutting rectangles. This is the mark that makes them read as paper: the
92
+ * ground going dark in the valley, which is what a sheet actually lays on the
93
+ * one beside it.
94
+ *
95
+ * It goes on the sheet that is COVERED, on the edge the neighbour lies over —
96
+ * a rail with a sidebar to its right takes `crease('right')`. Nothing can paint
97
+ * outside its own box, so the receiver draws it; the caster only has to be
98
+ * higher up the ladder.
99
+ *
100
+ * Spend it at a seam and nowhere else. A crease down the side of a card with
101
+ * nothing beside it is a gradient somebody liked.
102
+ */
103
+ export declare const crease: (edge?: Edge) => {
104
+ readonly className: 'hz-crease';
105
+ readonly 'data-crease'?: Edge | undefined;
106
+ };
107
+ /**
108
+ * Unfold — how a sheet ARRIVES: turning open about the edge it is hinged on,
109
+ * rather than fading up as a rectangle.
110
+ *
111
+ * <YStack {...paper(sheet(2), unfold('right'))}>
112
+ *
113
+ * The hinge is the only knob, and it sets the direction of the turn with it, so
114
+ * a sheet cannot be asked to swing the wrong way. A drawer off the left wall is
115
+ * `unfold()`; a pane folding in from the right edge is `unfold('right')`.
116
+ *
117
+ * Motion only — it says nothing about what the surface is made of, so it
118
+ * composes with `sheet`, `glass` or neither. Off under reduced motion, in
119
+ * `styles/motion.css` beside every other keyframe this package ships.
120
+ */
121
+ export declare const unfold: (hinge?: Edge) => {
122
+ readonly className: 'hz-unfold';
123
+ readonly 'data-hinge'?: string | undefined;
124
+ };
125
+ interface Mark {
126
+ className?: string;
127
+ }
128
+ /**
129
+ * Compose marks onto one surface, without losing a class.
130
+ *
131
+ * <YStack {...paper(sheet(1), crease('left'), fold)}>
132
+ *
133
+ * SPREADING TWO RECIPES SILENTLY DROPS ONE. `{...sheet(1)} {...fold}` — the
134
+ * composition `fold`'s own documentation shows — keeps only the last
135
+ * `className`, so the sheet arrives with its fill and its fold and WITHOUT
136
+ * `elevation-1`: the surface is a shade lighter than the page and flat, which
137
+ * looks like a design decision rather than a lost property. JSX assigns whole
138
+ * keys, and `className` is one key; this repo already records the same shape
139
+ * costing a breakpoint object.
140
+ *
141
+ * So marks are composed through here rather than beside each other. Every other
142
+ * key still takes the last writer, which is what a caller means by ordering
143
+ * them; only the class list accumulates.
144
+ */
145
+ export declare function paper<A extends Mark>(a: A): A;
146
+ export declare function paper<A extends Mark, B extends Mark>(a: A, b: B): A & B;
147
+ export declare function paper<A extends Mark, B extends Mark, C extends Mark>(a: A, b: B, c: C): A & B & C;
78
148
  /**
79
149
  * The fold — a corner turned back, and the ONE mark that says an item opens.
80
150
  *
@@ -289,4 +359,5 @@ export declare const screen: {
289
359
  readonly alignItems: 'center';
290
360
  readonly justifyContent: 'center';
291
361
  };
362
+ export {};
292
363
  //# sourceMappingURL=glass.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"glass.d.ts","sourceRoot":"","sources":["../src/glass.ts"],"names":[],"mappings":"AA8BA;;;;;GAKG;AACH,MAAM,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,KAAK,WAAW,IAAI;aAE7B,SAAS;aACT,eAAe,EAAE,aAAa;aAC9B,WAAW,EAAE,cAAc;CAClB,CAAA;AAEb;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,KAAK,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC;;;CAIzB,CAAA;AAQb;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,IAAI;aAAK,SAAS,EAAE,MAAM;CAAW,CAAA;AAElD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,KAAK;aAAK,eAAe,EAAE,uCAAuC;CAAW,CAAA;AAE1F;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,KAAK;aAChB,eAAe,EAAE,SAAS;aAC1B,WAAW,EAAE,CAAC;aACd,WAAW,EAAE,cAAc;aAC3B,YAAY,EAAE,IAAI;aAClB,SAAS,EAAE,aAAa;CAChB,CAAA;AAEV;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,IAAI;8BAxBE,SAAS;0BACb,CAAC;0BACD,cAAc;2BACb,IAAI;wBACP,aAAa;uBAuBd,QAAQ;CACV,CAAA;AAEV;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,GAAG;aACd,aAAa,EAAE,KAAK;aACpB,UAAU,EAAE,QAAQ;aACpB,cAAc,EAAE,eAAe;aAC/B,GAAG,EAAE,IAAI;aACT,iBAAiB,EAAE,IAAI;aACvB,eAAe,EAAE,IAAI;CACb,CAAA;AAEV;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,QAAQ,OAAQ,OAAO;8BAEV,SAAS;oBAAS,UAAU;;8BAC5B,aAAa;oBAAS,UAAU;CAAY,CAAA;AAEtE;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,MAAM;aACjB,eAAe,EAAE,SAAS;aAC1B,WAAW,EAAE,CAAC;aACd,WAAW,EAAE,SAAS;IACtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;aACH,KAAK,EAAE,UAAU;aACjB,UAAU;iBAAI,eAAe,EAAE,SAAS;iBAAE,KAAK,EAAE,UAAU;;CACnD,CAAA;AAEV;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,MAAM;aACjB,SAAS,EAAE,QAAQ;aACnB,UAAU,EAAE,QAAQ;aACpB,cAAc,EAAE,QAAQ;CAChB,CAAA"}
1
+ {"version":3,"file":"glass.d.ts","sourceRoot":"","sources":["../src/glass.ts"],"names":[],"mappings":"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"}
package/dist/glass.js CHANGED
@@ -102,6 +102,49 @@ const SHEET_FILL = {
102
102
  1: 'var(--sheet-1, rgb(38 38 38 / .5))',
103
103
  2: 'var(--sheet-2, rgb(38 38 38 / .75))',
104
104
  };
105
+ /**
106
+ * The crease — the valley where a neighbouring sheet lies over this one.
107
+ *
108
+ * <YStack {...paper(sheet(0), crease('right'))}>
109
+ *
110
+ * The ladder's drops fall straight down (design's rule is one light, above), so
111
+ * it has nothing to say about a VERTICAL seam — and an app shell is nothing but
112
+ * vertical seams. Three sheets a rung apart, side by side, still read as three
113
+ * abutting rectangles. This is the mark that makes them read as paper: the
114
+ * ground going dark in the valley, which is what a sheet actually lays on the
115
+ * one beside it.
116
+ *
117
+ * It goes on the sheet that is COVERED, on the edge the neighbour lies over —
118
+ * a rail with a sidebar to its right takes `crease('right')`. Nothing can paint
119
+ * outside its own box, so the receiver draws it; the caster only has to be
120
+ * higher up the ladder.
121
+ *
122
+ * Spend it at a seam and nowhere else. A crease down the side of a card with
123
+ * nothing beside it is a gradient somebody liked.
124
+ */
125
+ export const crease = (edge) => ({ className: 'hz-crease', ...(edge ? { 'data-crease': edge } : {}) });
126
+ /**
127
+ * Unfold — how a sheet ARRIVES: turning open about the edge it is hinged on,
128
+ * rather than fading up as a rectangle.
129
+ *
130
+ * <YStack {...paper(sheet(2), unfold('right'))}>
131
+ *
132
+ * The hinge is the only knob, and it sets the direction of the turn with it, so
133
+ * a sheet cannot be asked to swing the wrong way. A drawer off the left wall is
134
+ * `unfold()`; a pane folding in from the right edge is `unfold('right')`.
135
+ *
136
+ * Motion only — it says nothing about what the surface is made of, so it
137
+ * composes with `sheet`, `glass` or neither. Off under reduced motion, in
138
+ * `styles/motion.css` beside every other keyframe this package ships.
139
+ */
140
+ export const unfold = (hinge = 'left') => ({ className: 'hz-unfold', ...(hinge === 'right' ? { 'data-hinge': 'right' } : {}) });
141
+ export function paper(...marks) {
142
+ const className = marks
143
+ .map((mark) => mark.className)
144
+ .filter(Boolean)
145
+ .join(' ');
146
+ return { ...Object.assign({}, ...marks), ...(className ? { className } : {}) };
147
+ }
105
148
  /**
106
149
  * The fold — a corner turned back, and the ONE mark that says an item opens.
107
150
  *
package/dist/glass.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"glass.js","sourceRoot":"","sources":["../src/glass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAU1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,KAAK,GAAS,CAAC,EAAE,EAAE,CACvC,CAAC;IACC,SAAS,EAAE,mBAAmB,KAAK,EAAE;IACrC,eAAe,EAAE,aAAa;IAC9B,WAAW,EAAE,cAAc;CAC5B,CAAU,CAAA;AAEb;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,KAAK,GAAc,CAAC,EAAE,EAAE,CAC5C,CAAC;IACC,eAAe,EAAE,UAAU,CAAC,KAAK,CAAC;IAClC,GAAG,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,aAAa,KAAK,EAAW,EAAE,CAAC;CACrE,CAAU,CAAA;AAEb,MAAM,UAAU,GAAG;IACjB,CAAC,EAAE,yBAAyB;IAC5B,CAAC,EAAE,oCAAoC;IACvC,CAAC,EAAE,qCAAqC;CAChC,CAAA;AAEV;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,EAAE,SAAS,EAAE,MAAM,EAAW,CAAA;AAElD;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,EAAE,eAAe,EAAE,uCAAuC,EAAW,CAAA;AAE1F;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,eAAe,EAAE,SAAS;IAC1B,WAAW,EAAE,CAAC;IACd,WAAW,EAAE,cAAc;IAC3B,YAAY,EAAE,IAAI;IAClB,SAAS,EAAE,aAAa;CAChB,CAAA;AAEV;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,GAAG,KAAK;IACR,GAAG,IAAI,CAAC,MAAM,CAAC;IACf,QAAQ,EAAE,QAAQ;CACV,CAAA;AAEV;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,aAAa,EAAE,KAAK;IACpB,UAAU,EAAE,QAAQ;IACpB,cAAc,EAAE,eAAe;IAC/B,GAAG,EAAE,IAAI;IACT,iBAAiB,EAAE,IAAI;IACvB,eAAe,EAAE,IAAI;CACb,CAAA;AAEV;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,EAAW,EAAE,EAAE,CACtC,EAAE;IACA,CAAC,CAAE,EAAE,eAAe,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAY;IAC9D,CAAC,CAAE,EAAE,eAAe,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,EAAY,CAAA;AAEtE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,eAAe,EAAE,SAAS;IAC1B,WAAW,EAAE,CAAC;IACd,WAAW,EAAE,SAAS;IACtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,KAAK,EAAE,UAAU;IACjB,UAAU,EAAE,EAAE,eAAe,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE;CACrD,CAAA;AAEV;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,SAAS,EAAE,QAAQ;IACnB,UAAU,EAAE,QAAQ;IACpB,cAAc,EAAE,QAAQ;CAChB,CAAA"}
1
+ {"version":3,"file":"glass.js","sourceRoot":"","sources":["../src/glass.ts"],"names":[],"mappings":"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"}
@@ -217,6 +217,52 @@
217
217
  }
218
218
  }
219
219
 
220
+ /* ── Unfold — how a sheet arrives ─────────────────────────────────────────────
221
+ A panel that appears by fading is a rectangle switching on. A sheet of paper
222
+ arrives by TURNING OPEN about the edge it is hinged on, so its near edge swings
223
+ toward the reader and its far edge stays put — which is the one motion that
224
+ says "this was already here, folded" rather than "this was drawn just now".
225
+
226
+ The hinge is the ONLY thing that varies, so it is the only knob: a drawer
227
+ coming off the left wall turns about its left edge, a pane folding in from the
228
+ right about its right. The angle follows the hinge — a sheet swings toward you
229
+ from whichever side it is held — so naming the hinge sets both, and there is no
230
+ way to ask for a turn that opens the wrong way.
231
+
232
+ `perspective()` inside the transform rather than on a parent: the vanishing
233
+ point is then the sheet's own centre, so the turn reads at any size and the
234
+ caller does not have to own a 3D context it did not ask for.
235
+
236
+ Seven degrees over 220ms. Enough to see the plane; short of the swinging-door
237
+ effect that makes a workspace feel like a slideshow. */
238
+ @keyframes hz-unfold {
239
+ from {
240
+ opacity: 0;
241
+ transform: perspective(1600px) rotateY(var(--hz-turn, -7deg));
242
+ }
243
+ to {
244
+ opacity: 1;
245
+ transform: perspective(1600px) rotateY(0deg);
246
+ }
247
+ }
248
+
249
+ .hz-unfold {
250
+ animation: hz-unfold 220ms cubic-bezier(0.2, 0.7, 0.3, 1) both;
251
+ transform-origin: left center;
252
+ will-change: transform, opacity;
253
+ }
254
+
255
+ .hz-unfold[data-hinge="right"] {
256
+ transform-origin: right center;
257
+ --hz-turn: 7deg;
258
+ }
259
+
260
+ @media (prefers-reduced-motion: reduce) {
261
+ .hz-unfold {
262
+ animation: none;
263
+ }
264
+ }
265
+
220
266
  /* ── Layout guarantees ─────────────────────────────────────────────────────────
221
267
  Two rules, both structural. They are attached to `data-slot` rather than to a
222
268
  class because they are not styling a caller can opt out of — they are the
package/dist/styles.css CHANGED
@@ -1725,6 +1725,73 @@
1725
1725
  border-bottom-right-radius: 0 !important;
1726
1726
  }
1727
1727
 
1728
+ /* ── The crease — the valley where one sheet lies over another ───────────────
1729
+ The ladder lifts a sheet with a drop that falls STRAIGHT DOWN: design's rule
1730
+ is one light, above, and `check-tokens.mjs` fails the build on a sideways
1731
+ offset. That is right, and it means the ladder has nothing to say about a
1732
+ VERTICAL seam — and an app shell is nothing but vertical seams. A rail beside
1733
+ a sidebar beside a pane, each a step apart on the ladder, still reads as three
1734
+ abutting rectangles with lines ruled between them, because the only mark at
1735
+ the seam is the hairline.
1736
+
1737
+ What a real sheet lays on the one beneath it, side by side under a light from
1738
+ above, is not a cast shadow — it is the valley going dark. Ambient occlusion
1739
+ has no direction of its own, which is both why it is honest here and why it is
1740
+ NOT spelled as a --shadow-*: those are directional by definition and this is
1741
+ not one.
1742
+
1743
+ A PSEUDO-ELEMENT, at z-index -1 inside an isolated stacking context, so it
1744
+ paints above the sheet's own fill and below every child. That ordering is the
1745
+ whole reason it is not a `background-image` (which `.fold` already claims on
1746
+ this same element, !important, so the two would silently fight) and not an
1747
+ inset `box-shadow` (which `.elevation-*` claims, likewise).
1748
+
1749
+ No side named -> both edges, which is what a pane with a neighbour on each
1750
+ hand needs. Name one and the other stops being drawn. */
1751
+ :root {
1752
+ --crease-ink: rgb(0 0 0 / .28);
1753
+ --crease-depth: 20px;
1754
+ }
1755
+
1756
+ .light, :root.t_light, .t_light {
1757
+ /* On white the valley is a smudge, not a shadow — the same redistribution the
1758
+ drops make, and for the same reason. */
1759
+ --crease-ink: rgb(0 0 0 / .05);
1760
+ }
1761
+
1762
+ .hz-crease {
1763
+ position: relative;
1764
+ /* Without this the -1 escapes and paints behind an ancestor's fill, which is
1765
+ indistinguishable from the crease not being there at all. */
1766
+ isolation: isolate;
1767
+ }
1768
+
1769
+ .hz-crease::before,
1770
+ .hz-crease::after {
1771
+ content: "";
1772
+ position: absolute;
1773
+ top: 0;
1774
+ bottom: 0;
1775
+ width: var(--crease-depth);
1776
+ z-index: -1;
1777
+ pointer-events: none;
1778
+ }
1779
+
1780
+ .hz-crease::before {
1781
+ left: 0;
1782
+ background-image: linear-gradient(to right, var(--crease-ink), transparent);
1783
+ }
1784
+
1785
+ .hz-crease::after {
1786
+ right: 0;
1787
+ background-image: linear-gradient(to left, var(--crease-ink), transparent);
1788
+ }
1789
+
1790
+ .hz-crease[data-crease="left"]::after,
1791
+ .hz-crease[data-crease="right"]::before {
1792
+ content: none;
1793
+ }
1794
+
1728
1795
  /* ── The scrim ──────────────────────────────────────────────────────────────
1729
1796
  The dim that makes a floating panel read as floating rather than as more
1730
1797
  page. gui's overlay dims TWICE — a translucent ground under a further
@@ -2091,6 +2158,41 @@ input::-webkit-search-cancel-button,input::-webkit-search-decoration,input::-web
2091
2158
  * in a token or a component.
2092
2159
  */
2093
2160
 
2161
+ /* ── The measure ──────────────────────────────────────────────────────────
2162
+ How wide a thing is allowed to get, which the token set had no answer for.
2163
+ Type and spacing were both tokenised; width was left to whatever class the
2164
+ page happened to carry, and the lux slides ended up setting 82 characters to
2165
+ the line at 1280px with 13px of gutter — the viewport, not a column.
2166
+
2167
+ Three values, because a page needs three different widths:
2168
+
2169
+ --measure running text. 68 characters is the top of the comfortable
2170
+ range; past it the eye loses its place on the line return.
2171
+ In `ch` so it follows the type rather than fighting it.
2172
+ --frame the outer bound of a full-width composition — a slide, a
2173
+ header, a footer. Wider than the measure because a two-column
2174
+ layout is not running text.
2175
+ --gutter the margin outside the frame. It GROWS with the viewport: a
2176
+ wider screen should give the content more air, not less. The
2177
+ lux slides had this inverted — 8vw below xl, 1vw above — so
2178
+ the design got tighter exactly as the room appeared. */
2179
+ :root {
2180
+ --measure: 68ch;
2181
+ --frame: 90rem;
2182
+ --gutter: clamp(1.25rem, 5vw, 6rem);
2183
+ }
2184
+
2185
+ /* Running text is bounded; a heading is not. A heading is short, and the width
2186
+ is what gives it presence — so only the elements that set paragraphs are
2187
+ capped. A max-width can never make something wider, so this is safe inside a
2188
+ card or a column that is already narrower. */
2189
+ .hz-prose > p,
2190
+ .hz-prose > ul,
2191
+ .hz-prose > ol,
2192
+ .hz-prose > blockquote {
2193
+ max-width: var(--measure);
2194
+ }
2195
+
2094
2196
  *,
2095
2197
  *::before,
2096
2198
  *::after {
@@ -2370,6 +2472,52 @@ body {
2370
2472
  }
2371
2473
  }
2372
2474
 
2475
+ /* ── Unfold — how a sheet arrives ─────────────────────────────────────────────
2476
+ A panel that appears by fading is a rectangle switching on. A sheet of paper
2477
+ arrives by TURNING OPEN about the edge it is hinged on, so its near edge swings
2478
+ toward the reader and its far edge stays put — which is the one motion that
2479
+ says "this was already here, folded" rather than "this was drawn just now".
2480
+
2481
+ The hinge is the ONLY thing that varies, so it is the only knob: a drawer
2482
+ coming off the left wall turns about its left edge, a pane folding in from the
2483
+ right about its right. The angle follows the hinge — a sheet swings toward you
2484
+ from whichever side it is held — so naming the hinge sets both, and there is no
2485
+ way to ask for a turn that opens the wrong way.
2486
+
2487
+ `perspective()` inside the transform rather than on a parent: the vanishing
2488
+ point is then the sheet's own centre, so the turn reads at any size and the
2489
+ caller does not have to own a 3D context it did not ask for.
2490
+
2491
+ Seven degrees over 220ms. Enough to see the plane; short of the swinging-door
2492
+ effect that makes a workspace feel like a slideshow. */
2493
+ @keyframes hz-unfold {
2494
+ from {
2495
+ opacity: 0;
2496
+ transform: perspective(1600px) rotateY(var(--hz-turn, -7deg));
2497
+ }
2498
+ to {
2499
+ opacity: 1;
2500
+ transform: perspective(1600px) rotateY(0deg);
2501
+ }
2502
+ }
2503
+
2504
+ .hz-unfold {
2505
+ animation: hz-unfold 220ms cubic-bezier(0.2, 0.7, 0.3, 1) both;
2506
+ transform-origin: left center;
2507
+ will-change: transform, opacity;
2508
+ }
2509
+
2510
+ .hz-unfold[data-hinge="right"] {
2511
+ transform-origin: right center;
2512
+ --hz-turn: 7deg;
2513
+ }
2514
+
2515
+ @media (prefers-reduced-motion: reduce) {
2516
+ .hz-unfold {
2517
+ animation: none;
2518
+ }
2519
+ }
2520
+
2373
2521
  /* ── Layout guarantees ─────────────────────────────────────────────────────────
2374
2522
  Two rules, both structural. They are attached to `data-slot` rather than to a
2375
2523
  class because they are not styling a caller can opt out of — they are the
package/dist/theme.css CHANGED
@@ -1723,6 +1723,73 @@
1723
1723
  border-bottom-right-radius: 0 !important;
1724
1724
  }
1725
1725
 
1726
+ /* ── The crease — the valley where one sheet lies over another ───────────────
1727
+ The ladder lifts a sheet with a drop that falls STRAIGHT DOWN: design's rule
1728
+ is one light, above, and `check-tokens.mjs` fails the build on a sideways
1729
+ offset. That is right, and it means the ladder has nothing to say about a
1730
+ VERTICAL seam — and an app shell is nothing but vertical seams. A rail beside
1731
+ a sidebar beside a pane, each a step apart on the ladder, still reads as three
1732
+ abutting rectangles with lines ruled between them, because the only mark at
1733
+ the seam is the hairline.
1734
+
1735
+ What a real sheet lays on the one beneath it, side by side under a light from
1736
+ above, is not a cast shadow — it is the valley going dark. Ambient occlusion
1737
+ has no direction of its own, which is both why it is honest here and why it is
1738
+ NOT spelled as a --shadow-*: those are directional by definition and this is
1739
+ not one.
1740
+
1741
+ A PSEUDO-ELEMENT, at z-index -1 inside an isolated stacking context, so it
1742
+ paints above the sheet's own fill and below every child. That ordering is the
1743
+ whole reason it is not a `background-image` (which `.fold` already claims on
1744
+ this same element, !important, so the two would silently fight) and not an
1745
+ inset `box-shadow` (which `.elevation-*` claims, likewise).
1746
+
1747
+ No side named -> both edges, which is what a pane with a neighbour on each
1748
+ hand needs. Name one and the other stops being drawn. */
1749
+ :root {
1750
+ --crease-ink: rgb(0 0 0 / .28);
1751
+ --crease-depth: 20px;
1752
+ }
1753
+
1754
+ .light, :root.t_light, .t_light {
1755
+ /* On white the valley is a smudge, not a shadow — the same redistribution the
1756
+ drops make, and for the same reason. */
1757
+ --crease-ink: rgb(0 0 0 / .05);
1758
+ }
1759
+
1760
+ .hz-crease {
1761
+ position: relative;
1762
+ /* Without this the -1 escapes and paints behind an ancestor's fill, which is
1763
+ indistinguishable from the crease not being there at all. */
1764
+ isolation: isolate;
1765
+ }
1766
+
1767
+ .hz-crease::before,
1768
+ .hz-crease::after {
1769
+ content: "";
1770
+ position: absolute;
1771
+ top: 0;
1772
+ bottom: 0;
1773
+ width: var(--crease-depth);
1774
+ z-index: -1;
1775
+ pointer-events: none;
1776
+ }
1777
+
1778
+ .hz-crease::before {
1779
+ left: 0;
1780
+ background-image: linear-gradient(to right, var(--crease-ink), transparent);
1781
+ }
1782
+
1783
+ .hz-crease::after {
1784
+ right: 0;
1785
+ background-image: linear-gradient(to left, var(--crease-ink), transparent);
1786
+ }
1787
+
1788
+ .hz-crease[data-crease="left"]::after,
1789
+ .hz-crease[data-crease="right"]::before {
1790
+ content: none;
1791
+ }
1792
+
1726
1793
  /* ── The scrim ──────────────────────────────────────────────────────────────
1727
1794
  The dim that makes a floating panel read as floating rather than as more
1728
1795
  page. gui's overlay dims TWICE — a translucent ground under a further
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanzo/ui",
3
- "version": "8.17.0",
3
+ "version": "8.18.0",
4
4
  "type": "module",
5
5
  "description": "Hanzo UI — the one canonical Hanzo component library, on @hanzo/gui + @hanzo/design. ONE substrate: every component renders through @hanzo/gui primitives, so the same import works on web, native (expo) and desktop (Tauri). Self-contained (theme.css), presentational, host-agnostic, clean-room.",
6
6
  "exports": {