@uxelle/skills 0.2.0-beta.2

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 (117) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +58 -0
  3. package/dist/index.d.ts +26 -0
  4. package/dist/index.js +586 -0
  5. package/index.json +573 -0
  6. package/package.json +57 -0
  7. package/skills/uxelle-components/Accordion.md +51 -0
  8. package/skills/uxelle-components/AccordionGroup.md +39 -0
  9. package/skills/uxelle-components/Banner.md +73 -0
  10. package/skills/uxelle-components/BannerAnnouncement.md +63 -0
  11. package/skills/uxelle-components/Breadcrumb.md +38 -0
  12. package/skills/uxelle-components/Breadcrumbs.md +32 -0
  13. package/skills/uxelle-components/Bubble.md +34 -0
  14. package/skills/uxelle-components/Button.md +54 -0
  15. package/skills/uxelle-components/ButtonGroup.md +43 -0
  16. package/skills/uxelle-components/Card.md +35 -0
  17. package/skills/uxelle-components/Checkbox.md +57 -0
  18. package/skills/uxelle-components/CheckboxGroup.md +47 -0
  19. package/skills/uxelle-components/ChoiceChip.md +44 -0
  20. package/skills/uxelle-components/ChoiceChipGroup.md +50 -0
  21. package/skills/uxelle-components/DatePicker.md +59 -0
  22. package/skills/uxelle-components/DatePickerRange.md +73 -0
  23. package/skills/uxelle-components/Dialog.md +83 -0
  24. package/skills/uxelle-components/Divider.md +37 -0
  25. package/skills/uxelle-components/DynamicAngleLine.md +36 -0
  26. package/skills/uxelle-components/DynamicAngleLineCombo.md +30 -0
  27. package/skills/uxelle-components/DynamicAngleShape.md +32 -0
  28. package/skills/uxelle-components/DynamicAngleShapeSurface.md +35 -0
  29. package/skills/uxelle-components/DynamicAngleTexture.md +29 -0
  30. package/skills/uxelle-components/DynamicAngleTextureText.md +35 -0
  31. package/skills/uxelle-components/FieldMessage.md +31 -0
  32. package/skills/uxelle-components/FileUpload.md +53 -0
  33. package/skills/uxelle-components/FilterChip.md +35 -0
  34. package/skills/uxelle-components/FilterChipGroup.md +42 -0
  35. package/skills/uxelle-components/Footer.md +34 -0
  36. package/skills/uxelle-components/Hero.md +61 -0
  37. package/skills/uxelle-components/Icon.md +43 -0
  38. package/skills/uxelle-components/IconButton.md +44 -0
  39. package/skills/uxelle-components/Image.md +40 -0
  40. package/skills/uxelle-components/Label.md +35 -0
  41. package/skills/uxelle-components/LabelBadge.md +58 -0
  42. package/skills/uxelle-components/LanguageSelector.md +38 -0
  43. package/skills/uxelle-components/LanguageSelectorButton.md +34 -0
  44. package/skills/uxelle-components/Layout.md +81 -0
  45. package/skills/uxelle-components/LinearProgress.md +53 -0
  46. package/skills/uxelle-components/Link.md +52 -0
  47. package/skills/uxelle-components/List.md +35 -0
  48. package/skills/uxelle-components/ListControls.md +100 -0
  49. package/skills/uxelle-components/ListItem.md +69 -0
  50. package/skills/uxelle-components/Lockup.md +50 -0
  51. package/skills/uxelle-components/Logo.md +39 -0
  52. package/skills/uxelle-components/Menu.md +48 -0
  53. package/skills/uxelle-components/MultiSelect.md +54 -0
  54. package/skills/uxelle-components/NavLink.md +44 -0
  55. package/skills/uxelle-components/Navigation.md +61 -0
  56. package/skills/uxelle-components/NavigationSide.md +51 -0
  57. package/skills/uxelle-components/NavigationSideGroup.md +36 -0
  58. package/skills/uxelle-components/NavigationSideItem.md +56 -0
  59. package/skills/uxelle-components/NavigationSideSubItem.md +39 -0
  60. package/skills/uxelle-components/NotificationBadge.md +62 -0
  61. package/skills/uxelle-components/Pagination.md +49 -0
  62. package/skills/uxelle-components/PaginationComplex.md +51 -0
  63. package/skills/uxelle-components/PaginationSimple.md +44 -0
  64. package/skills/uxelle-components/ProductCard.md +46 -0
  65. package/skills/uxelle-components/Quantity.md +45 -0
  66. package/skills/uxelle-components/Radio.md +55 -0
  67. package/skills/uxelle-components/RadioGroup.md +49 -0
  68. package/skills/uxelle-components/SKILL.md +242 -0
  69. package/skills/uxelle-components/Scrim.md +28 -0
  70. package/skills/uxelle-components/SegmentedControl.md +118 -0
  71. package/skills/uxelle-components/Select.md +55 -0
  72. package/skills/uxelle-components/Sheet.md +31 -0
  73. package/skills/uxelle-components/Skeleton.md +35 -0
  74. package/skills/uxelle-components/Spinner.md +33 -0
  75. package/skills/uxelle-components/StatTile.md +150 -0
  76. package/skills/uxelle-components/Stepper.md +73 -0
  77. package/skills/uxelle-components/Switch.md +41 -0
  78. package/skills/uxelle-components/Tab.md +41 -0
  79. package/skills/uxelle-components/Table.md +55 -0
  80. package/skills/uxelle-components/TabsCompact.md +37 -0
  81. package/skills/uxelle-components/TabsStretch.md +35 -0
  82. package/skills/uxelle-components/Text.md +56 -0
  83. package/skills/uxelle-components/Textarea.md +77 -0
  84. package/skills/uxelle-components/Textfield.md +62 -0
  85. package/skills/uxelle-components/Tooltip.md +33 -0
  86. package/skills/uxelle-design-harness/SKILL.md +149 -0
  87. package/skills/uxelle-design-harness/a2ui.md +73 -0
  88. package/skills/uxelle-design-harness/how-to-accessibility.md +31 -0
  89. package/skills/uxelle-design-harness/how-to-color.md +82 -0
  90. package/skills/uxelle-design-harness/how-to-host.md +108 -0
  91. package/skills/uxelle-design-harness/how-to-page-layout.md +203 -0
  92. package/skills/uxelle-design-harness/principles.md +72 -0
  93. package/skills/uxelle-design-harness/recipe-app-chrome.md +168 -0
  94. package/skills/uxelle-design-harness/recipe-card-grid.md +104 -0
  95. package/skills/uxelle-design-harness/recipe-cta-band.md +91 -0
  96. package/skills/uxelle-design-harness/recipe-dashboard-overview.md +118 -0
  97. package/skills/uxelle-design-harness/recipe-data-table-page.md +323 -0
  98. package/skills/uxelle-design-harness/recipe-feature-section.md +96 -0
  99. package/skills/uxelle-design-harness/recipe-footer.md +156 -0
  100. package/skills/uxelle-design-harness/recipe-form-section.md +163 -0
  101. package/skills/uxelle-design-harness/recipe-hero.md +89 -0
  102. package/skills/uxelle-design-harness/recipe-landing-page.md +94 -0
  103. package/skills/uxelle-design-harness/recipe-logo-wall.md +80 -0
  104. package/skills/uxelle-design-harness/recipe-multi-step-flow.md +108 -0
  105. package/skills/uxelle-design-harness/recipe-page-header.md +102 -0
  106. package/skills/uxelle-design-harness/recipe-page-shell.md +82 -0
  107. package/skills/uxelle-design-harness/recipe-pricing.md +83 -0
  108. package/skills/uxelle-design-harness/recipe-query-bar.md +108 -0
  109. package/skills/uxelle-design-harness/recipe-record-detail.md +96 -0
  110. package/skills/uxelle-design-harness/recipe-settings-page.md +170 -0
  111. package/skills/uxelle-design-harness/recipe-stat-callouts.md +111 -0
  112. package/skills/uxelle-design-harness/recipe-states.md +119 -0
  113. package/skills/uxelle-design-harness/recipe-summary-list.md +88 -0
  114. package/skills/uxelle-design-harness/recipe-template.md +62 -0
  115. package/skills/uxelle-design-harness/recipe-testimonial.md +73 -0
  116. package/skills/uxelle-design-harness/spacing-steps.md +57 -0
  117. package/skills/uxelle-design-harness/tokens.md +101 -0
@@ -0,0 +1,156 @@
1
+ # Recipe: footer
2
+
3
+ A shared **piece**: the page footer — a directory of links anchored by brand
4
+ identity, over a quiet legal/utility bar. Used by [app-chrome](recipe-app-chrome.md)
5
+ (product) and [landing-page](recipe-landing-page.md) (marketing).
6
+
7
+ Composes [`Footer`](../uxelle-components/Footer.md) (two bands),
8
+ [`Layout`](../uxelle-components/Layout.md),
9
+ [`Text`](../uxelle-components/Text.md), [`Link`](../uxelle-components/Link.md),
10
+ [`Logo`](../uxelle-components/Logo.md), and — for marketing — a
11
+ [`Button`](../uxelle-components/Button.md) CTA and social marks.
12
+
13
+ ## When
14
+
15
+ The closing chrome of a page: wayfinding to the rest of the site, plus identity and
16
+ legal. Place `Footer` **inside** `<main>` after the page column so it scrolls with the
17
+ page ([app-chrome](recipe-app-chrome.md)).
18
+
19
+ ## When not
20
+
21
+ - Not primary navigation — top-level app routes stay in `Navigation`
22
+ ([app-chrome](recipe-app-chrome.md)).
23
+ - Omit `Footer` entirely on focused flows (checkout, auth) that should not invite
24
+ exit.
25
+ - Pass real content to the bands you use; omitting a slot (`undefined`) fills catalog
26
+ demo content, and `null` hides a band.
27
+
28
+ ## Information architecture
29
+
30
+ The ideals the layout serves — adapt them, don't copy any one site.
31
+
32
+ - **Anchor with identity.** A brand block (logo + a one-line tagline or mission,
33
+ optionally a CTA and social marks) grounds the footer; on marketing it adds a last
34
+ conversion nudge.
35
+ - **Group links by user intent.** A handful of labeled categories — what you offer,
36
+ resources, company, legal/trust — each a heading over a vertical link list. Name
37
+ groups for how people look for things, not your org chart. Sub-group a large
38
+ category instead of spawning another top-level column.
39
+ - **Separate a quiet utility bar.** Copyright and registration, legal links
40
+ (privacy / terms / cookie / disclosures), and social or app badges sit in a
41
+ lower-emphasis band beneath the directory.
42
+ - **Scale density to the surface.** The same architecture ranges from a compact
43
+ legal-only bar (a focused product app) up to a rich multi-column directory (a
44
+ marketing site). Add columns as the story grows; don't force a big directory onto a
45
+ small app.
46
+ - **Isolate fine print.** Regulated or legal-heavy products add a dense
47
+ disclosure/disclaimer block — keep it last, low-emphasis, and out of the primary
48
+ link flow.
49
+ - **Make outbound obvious.** Mark external or cross-property links (e.g. a trailing
50
+ outbound icon) so they read as leaving.
51
+
52
+ ## Regions
53
+
54
+ `Footer` `topMainContent` (the **directory**): brand block + categorized link
55
+ columns, optional CTA and social · `Footer` `bottomMainContent` (the **utility
56
+ bar**): copyright + legal links, optional social; optional fine-print block last.
57
+
58
+ The component places logo/legal in the bottom band and links/CTAs/social in the top
59
+ band by default — follow that grain unless the design needs otherwise.
60
+
61
+ ## Lay out the bands as tidy clusters
62
+
63
+ Each band reads as a cluster, not content stretched to the band edges.
64
+
65
+ - **Directory (top band).** Lead with the brand block, then the link groups. With a
66
+ few groups (2–4), lay them out as a **left-aligned wrapping cluster** with intrinsic
67
+ widths and `--uxl-breakpoints-gutter` between them — do **not** stretch a couple of
68
+ groups across the full width with `auto-fit` / `1fr` tracks (two `1fr` columns leave
69
+ a hollow center that reads off-center). Reserve
70
+ `repeat(auto-fit, minmax(MIN, 1fr))` for a **dense** directory with enough groups to
71
+ fill the row.
72
+
73
+ ```tsx
74
+ <Layout display="flex" flexWrap="wrap" gap="var(--uxl-breakpoints-gutter)">
75
+ {/* brand block leads */}
76
+ <Layout display="flex" flexDirection="column" gap="var(--uxl-theme-layout-spacing-small-4)">
77
+ <a href="/" aria-label="Home">
78
+ <Logo name="generic" width={40} interactive aria-hidden />
79
+ </a>
80
+ <Text type="Body Small" width={false}>One-line tagline or mission.</Text>
81
+ {/* optional CTA on marketing */}
82
+ <Button emphasis="high"><Text type="Button" width>Book a demo</Text></Button>
83
+ </Layout>
84
+
85
+ {/* each category is a content-sized column — repeat per group */}
86
+ <Layout display="flex" flexDirection="column" gap="var(--uxl-theme-layout-spacing-micro-2)">
87
+ <Text type="Body Medium Alt" width={false}>Product</Text>
88
+ <Link href="/how-it-works">How it works</Link>
89
+ <Link href="/pricing">Pricing</Link>
90
+ <Link href="/compare">Compare</Link>
91
+ </Layout>
92
+ </Layout>
93
+ ```
94
+
95
+ - **Utility bar (bottom band).** Keep copyright and legal links in a **left-aligned
96
+ wrapping row** (or stack), separated by the spacing ramp — prefer this over
97
+ `justifyContent="space-between"`, which pins content to both edges and hollows the
98
+ center (worse when it wraps on mobile). A two-end split (copyright left, social
99
+ right) is fine only when **both** sides carry enough to avoid that void.
100
+
101
+ ## Responsive
102
+
103
+ Few groups wrap from a single row to stacked as width narrows (no JS); a dense
104
+ directory uses `repeat(auto-fit, minmax(MIN, 1fr))` to shed columns. The brand block
105
+ leads. The legal bar wraps its links. See
106
+ [how-to-page-layout.md](how-to-page-layout.md#responsiveness).
107
+
108
+ ## Spacing
109
+
110
+ `--uxl-breakpoints-gutter` between columns; `micro-2` within a link list; `small-4`
111
+ inside the brand block and the legal bar. Band padding is component-owned — a single
112
+ remaining band is compact (`small-4`), two bands use the large step; do not wrap
113
+ `Footer` in extra `p` / `gap`.
114
+
115
+ ## A11y
116
+
117
+ `Footer` is the page `contentinfo` landmark (one per page). Head each link group so
118
+ its purpose is clear; wrap a substantial directory (or each column) in a named `nav`.
119
+ Social/app links carry an accessible name; a `Logo` beside a visible brand name is
120
+ decorative (`aria-hidden`). See [how-to-accessibility.md](how-to-accessibility.md).
121
+
122
+ ## Color
123
+
124
+ `Footer` sets each band's palette itself (top vs bottom) — style content with role
125
+ tokens and let the component own the surface; don't fight it with hardcoded color
126
+ ([how-to-color.md](how-to-color.md)).
127
+
128
+ ## React
129
+
130
+ Assemble the two bands into `Footer`. A legal-only footer (`topMainContent={null}`) is
131
+ the product default; add the directory band as the surface grows.
132
+
133
+ ```tsx
134
+ <Footer
135
+ topMainContent={/* directory cluster from above, or null for legal-only */ null}
136
+ bottomMainContent={
137
+ <Layout display="flex" flexWrap="wrap" alignItems="center" gap="var(--uxl-theme-layout-spacing-small-4)">
138
+ <Text type="Body Small" width={false}>© 2026 Organization. All rights reserved.</Text>
139
+ <Layout as="nav" aria-label="Legal" display="flex" flexWrap="wrap" gap="var(--uxl-theme-layout-spacing-small-4)">
140
+ <Link href="/privacy">Privacy</Link>
141
+ <Link href="/terms">Terms of Use</Link>
142
+ <Link href="/cookies">Cookie Settings</Link>
143
+ </Layout>
144
+ </Layout>
145
+ }
146
+ />
147
+ ```
148
+
149
+ `DefaultTopMainContent` / `DefaultBottomMainContent` from `@uxelle/components` give a
150
+ quick start; generated UI passes real nodes.
151
+
152
+ ## A2UI
153
+
154
+ No `getUxelleRecipe("footer")` — compose `A2uiFooter` with the same two slots, links
155
+ as `A2uiLink`, headings/copyright as `A2uiText` (no `Lockup`), layout-spacing only.
156
+ See [a2ui.md](a2ui.md).
@@ -0,0 +1,163 @@
1
+ # Recipe: form section
2
+
3
+ ## When
4
+
5
+ A labeled **group of fields** under a heading — stacking rule, not a new form component. Preference toggles and choice lists: [recipe-settings-page.md](recipe-settings-page.md) (`ListControls`).
6
+
7
+ ## When not
8
+
9
+ - Do not wrap fields that already ship Label + FieldMessage (`Textfield`, `Textarea`, `Select`, `MultiSelect`, `FileUpload`).
10
+ - Do not use `Textfield` for comments, notes, bios, or other multi-line copy — that is [`Textarea`](../uxelle-components/Textarea.md).
11
+ - Do not fake exclusive choice with `ListItem` clicks.
12
+ - Do not flatten `RadioGroup` / `CheckboxGroup` (they are already a `fieldset`).
13
+ - Do not collapse given name + family name (or city/state/ZIP, month/day/year) into one field.
14
+ - `Layout` has no `as="form"`. Host wraps a native `<form>` when submitting.
15
+
16
+ ## Allowed children
17
+
18
+ Any catalog field: [`Textfield`](../uxelle-components/Textfield.md), [`Textarea`](../uxelle-components/Textarea.md), [`Select`](../uxelle-components/Select.md), [`MultiSelect`](../uxelle-components/MultiSelect.md), [`FileUpload`](../uxelle-components/FileUpload.md), [`CheckboxGroup`](../uxelle-components/CheckboxGroup.md), [`RadioGroup`](../uxelle-components/RadioGroup.md), [`Switch`](../uxelle-components/Switch.md), [`ListControls`](../uxelle-components/ListControls.md), [`Quantity`](../uxelle-components/Quantity.md) when present.
19
+
20
+ ## Multi-line
21
+
22
+ `Textarea` for free-form copy (notes, comments, bio). `autoGrow` sizes the field to its content — `rows` (or `height`) is the minimum, `maxHeight` caps it, and the resize grip is hidden. `counter` + `maxLength` is a hard stop; add `softOverflow` to let the user type past the limit. Past the limit, the counter uses `data-color-switcher="warning"` (numbers still show `n/max`; do not set `aria-invalid` from overflow). Pass `softOverflowMessage` for the warning `FieldMessage` — do not rely on catalog copy. Search, email, and other single-line values stay on `Textfield`.
23
+
24
+ ## Spacing
25
+
26
+ `gap="var(--uxl-theme-layout-spacing-medium-8)"` between fields (or field **rows**). Header stack `var(--uxl-theme-layout-spacing-micro-2)`. Actions in `ButtonGroup` (not ad-hoc `Layout` for two buttons) — row from tablet up, column below tablet ([how-to-page-layout.md](how-to-page-layout.md#action-clusters)). Parts of one value on one row: `small-4` inside the grid.
27
+
28
+ **Separate the actions from the fields.** The submit / action cluster is a decision point, not one more field — give it `medium-12` from the last field (the page-section gap), not the `medium-8` field gap. At the field gap the primary button reads as grouped with the control above it (e.g. a submit sitting right under the last `Select`). Group the heading + fields in one stack and make the actions a sibling at `medium-12` (see the React example).
29
+
30
+ ## Measure
31
+
32
+ A **standalone** form section on a wider page (a marketing demo request, a contact form) caps the whole section — heading, fields, and actions — at the `maxWidth="600px"` reading measure and centers it with `mh="auto"`, so the heading sits directly above the fields on one left edge:
33
+
34
+ ```tsx
35
+ <Layout
36
+ as="section"
37
+ display="flex"
38
+ flexDirection="column"
39
+ gap="var(--uxl-theme-layout-spacing-medium-12)"
40
+ width="100%"
41
+ maxWidth="600px"
42
+ mh="auto"
43
+ >
44
+ ```
45
+
46
+ Cap the **section**, not just the inner field stack — capping only the fields leaves the heading full-width and the form stranded left of center. Match this measure to sibling reading sections (an FAQ above it) so they read as one column ([how-to-page-layout.md](how-to-page-layout.md#reading-measure)). A settings page is already one `600px` column — do not nest another.
47
+
48
+ ## Related fields
49
+
50
+ Parts of **one value** sit on one row. Separate fields — not a single “Full name” / “Address” / “Date” string. Use `display="grid"` (`Textfield` / `Select` are `width: 100%` of the parent). Do not `flexWrap="wrap"` them. Account pages: [recipe-settings-page.md](recipe-settings-page.md).
51
+
52
+ ```tsx
53
+ <Layout
54
+ display="grid"
55
+ gridTemplateColumns="1fr 1fr"
56
+ gap="var(--uxl-theme-layout-spacing-small-4)"
57
+ >
58
+ <Textfield labelText="First name" name="givenName" autoComplete="given-name" />
59
+ <Textfield labelText="Last name" name="familyName" autoComplete="family-name" />
60
+ </Layout>
61
+
62
+ <Layout
63
+ display="grid"
64
+ gridTemplateColumns="2fr 1fr 1fr"
65
+ gap="var(--uxl-theme-layout-spacing-small-4)"
66
+ >
67
+ <Textfield labelText="City" name="city" autoComplete="address-level2" />
68
+ <Select labelText="State" name="state" options={stateOptions} />
69
+ <Textfield labelText="ZIP" name="postalCode" autoComplete="postal-code" />
70
+ </Layout>
71
+
72
+ <Layout
73
+ display="grid"
74
+ gridTemplateColumns="1fr 1fr 1fr"
75
+ gap="var(--uxl-theme-layout-spacing-small-4)"
76
+ >
77
+ <Select labelText="Month" name="month" options={monthOptions} />
78
+ <Select labelText="Day" name="day" options={dayOptions} />
79
+ <Select labelText="Year" name="year" options={yearOptions} />
80
+ </Layout>
81
+ ```
82
+
83
+ A2UI: `A2uiLayout` has no `gridTemplateColumns` — stack these fields. Do not put unrelated fields on the same row.
84
+
85
+ ## Dialog
86
+
87
+ When this section is `Dialog` `centerSlotContent`, `Text` in `topSlotContent` and `centerSlotContent` uses `width={false}` (100% of the slot). `width` / `width={true}` shrinks to the string. Button labels stay `width` (fit). A2UI: `"width": false` on `A2uiText` in those slots.
88
+
89
+ ## A11y
90
+
91
+ [how-to-accessibility.md](how-to-accessibility.md). Section heading (typically `h2` under a page `h1`). Groups use the group component’s legend. Actions in a labeled `ButtonGroup` (`aria-label`). Action `direction`: [how-to-page-layout.md](how-to-page-layout.md#action-clusters).
92
+
93
+ ## Responsive
94
+
95
+ Related-field grids collapse to one column below tablet, and the action `ButtonGroup` stacks `fullWidth` (`useBreakpointUp("tablet")`, [how-to-page-layout.md](how-to-page-layout.md#action-clusters)). Standalone fields are already full-width, so they need nothing.
96
+
97
+ ## React
98
+
99
+ v1 example: heading + supporting copy + name fields, select, radios, notes, and actions. `tabletUp` comes from `useBreakpointUp("tablet")` ([how-to-page-layout.md](how-to-page-layout.md#action-clusters)).
100
+
101
+ ```tsx
102
+ // Section gap is medium-12 so the actions sit a decision-boundary apart from the
103
+ // fields. Heading + fields are grouped in one medium-8 stack.
104
+ <Layout as="section" display="flex" flexDirection="column" gap="var(--uxl-theme-layout-spacing-medium-12)">
105
+ <Layout display="flex" flexDirection="column" gap="var(--uxl-theme-layout-spacing-medium-8)">
106
+ <Layout display="flex" flexDirection="column" gap="var(--uxl-theme-layout-spacing-micro-2)">
107
+ <Text type="Display Extra Small" as="h2" width={false}>
108
+ Workspace details
109
+ </Text>
110
+ <Text type="Body Medium" width={false}>
111
+ Used on invoices and shared reports. Required fields are marked.
112
+ </Text>
113
+ </Layout>
114
+ <Layout
115
+ display="grid"
116
+ gridTemplateColumns="1fr 1fr"
117
+ gap="var(--uxl-theme-layout-spacing-small-4)"
118
+ >
119
+ <Textfield labelText="First name" name="givenName" autoComplete="given-name" />
120
+ <Textfield labelText="Last name" name="familyName" autoComplete="family-name" />
121
+ </Layout>
122
+ <Select
123
+ labelText="Department"
124
+ name="department"
125
+ options={[
126
+ { value: "engineering", label: "Engineering" },
127
+ { value: "design", label: "Design" },
128
+ { value: "product", label: "Product" },
129
+ ]}
130
+ />
131
+ <RadioGroup name="priority" label labelText="Priority" defaultValue="normal">
132
+ <Radio value="low">
133
+ <Text type="Body Medium">Low</Text>
134
+ </Radio>
135
+ <Radio value="normal">
136
+ <Text type="Body Medium">Normal</Text>
137
+ </Radio>
138
+ <Radio value="high">
139
+ <Text type="Body Medium">High</Text>
140
+ </Radio>
141
+ </RadioGroup>
142
+ <Textarea
143
+ labelText="Notes"
144
+ fieldDescription="Optional context for this workspace."
145
+ name="notes"
146
+ autoGrow
147
+ rows={3}
148
+ />
149
+ </Layout>
150
+ <ButtonGroup
151
+ direction={tabletUp ? "row" : "column"}
152
+ fullWidth={!tabletUp}
153
+ aria-label="Form actions"
154
+ >
155
+ <Button emphasis="medium">Cancel</Button>
156
+ <Button emphasis="high">Save</Button>
157
+ </ButtonGroup>
158
+ </Layout>
159
+ ```
160
+
161
+ ## A2UI
162
+
163
+ Same stacking and theme spacing vars. Bind values with `{ path: "/form/…" }`. Runtime: `getUxelleRecipe("form-section")` from `@uxelle/a2ui` ([a2ui.md](a2ui.md)). Nested in `A2uiDialog`: `A2uiText` in `topSlotContent` and `centerSlotContent` uses `"width": false`. Given-name and family-name are separate `A2uiTextfield`s, stacked (`A2uiLayout` has no `gridTemplateColumns`). Notes are `A2uiTextarea` with `"autoGrow": true`. Form actions: `"direction": "column"` on `A2uiButtonGroup` (no matchMedia).
@@ -0,0 +1,89 @@
1
+ # Recipe: hero
2
+
3
+ A marketing **piece**: the opening band of a public page — value proposition,
4
+ primary/secondary action, and a product visual. Usually the one loud brand band on
5
+ the page.
6
+
7
+ Composes [`Hero`](../uxelle-components/Hero.md),
8
+ [`Lockup`](../uxelle-components/Lockup.md),
9
+ [`ButtonGroup`](../uxelle-components/ButtonGroup.md),
10
+ [`Image`](../uxelle-components/Image.md), and optionally
11
+ [`DynamicAngle*`](../uxelle-components/DynamicAngleShape.md) accents elsewhere on the page.
12
+
13
+ ## When
14
+
15
+ The first impression: one sentence of value, one clear action, and supporting media.
16
+
17
+ ## When not
18
+
19
+ - One `h1` for the whole page lives here — later sections are `h2`.
20
+ - Keep the media non-interactive; actions go in `contentSlot`.
21
+ - Pass media as a **direct** `Image` / `img` / `picture` / `video` — no wrappers
22
+ (Hero owns the crop; a nested `Image.aspectRatio` has no effect).
23
+
24
+ ## Regions
25
+
26
+ `Hero` -> `image` (direct `Image`) + `contentSlot` (`Lockup` `h1` + `ButtonGroup`)
27
+
28
+ ## Responsive
29
+
30
+ `Hero` owns it: `contentDirection="Left" | "Right"` pins a side panel on tablet and
31
+ up and drops to a full-width bottom panel below; `Bottom` is full-width at every
32
+ size. The crop adapts automatically. If the two actions feel tight on mobile, switch
33
+ the `ButtonGroup` `direction` to `column` (`useBreakpointUp("tablet")`).
34
+
35
+ ## Spacing
36
+
37
+ Content-area spacing is component-owned. The hero is a full-bleed band, so it sits
38
+ outside the capped content column — following sections resume the column
39
+ ([how-to-page-layout.md](how-to-page-layout.md)).
40
+
41
+ ## A11y
42
+
43
+ The `h1` is here. `Hero` has no landmark by default — add `role="region"` with
44
+ `aria-label` / `aria-labelledby` if you need a named region. Meaningful media gets
45
+ real `alt`; decorative media uses `alt=""`. See
46
+ [how-to-accessibility.md](how-to-accessibility.md).
47
+
48
+ ## Color
49
+
50
+ `Hero` defaults to `data-color-switcher="brand-1"`. Choose the brand palette by the
51
+ look you want and override with the attribute — this is typically the single
52
+ dominant brand band; keep later sections calmer ([how-to-color.md](how-to-color.md)).
53
+
54
+ ## React
55
+
56
+ ```tsx
57
+ <Hero
58
+ contentDirection="Left"
59
+ data-color-switcher="brand-1"
60
+ image={<Image src="/hero.jpg" alt="Team collaborating around a screen" />}
61
+ contentSlot={
62
+ <>
63
+ <Lockup
64
+ overline={<Text type="Overline" width={false}>New</Text>}
65
+ title={
66
+ <Text type="Display Medium" as="h1" width={false}>
67
+ One workspace for every team
68
+ </Text>
69
+ }
70
+ body={
71
+ <Text type="Body Medium" width={false}>
72
+ Plan, build, and ship together — without the tool sprawl.
73
+ </Text>
74
+ }
75
+ />
76
+ <ButtonGroup aria-label="Get started">
77
+ <Button emphasis="high"><Text type="Button" width={false}>Start free</Text></Button>
78
+ <Button emphasis="medium"><Text type="Button" width={false}>Book a demo</Text></Button>
79
+ </ButtonGroup>
80
+ </>
81
+ }
82
+ />
83
+ ```
84
+
85
+ ## A2UI
86
+
87
+ `A2uiHero` with a nested `A2uiImage` and a `contentSlot` of stacked `A2uiText`
88
+ (no `Lockup` adapter) plus `A2uiButtonGroup`. Set the palette via the adapter's
89
+ `data-color-switcher` ([a2ui.md](a2ui.md)).
@@ -0,0 +1,94 @@
1
+ # Recipe: landing page
2
+
3
+ A marketing **experience**: a public page that builds trust and converts. It
4
+ assembles the marketing pieces in a dependable rhythm on one grid, with a single
5
+ dominant brand band.
6
+
7
+ Assembles [app-chrome](recipe-app-chrome.md) (marketing mode),
8
+ [hero](recipe-hero.md), [logo-wall](recipe-logo-wall.md),
9
+ [feature-section](recipe-feature-section.md), [stat-callouts](recipe-stat-callouts.md),
10
+ [testimonial](recipe-testimonial.md), [pricing](recipe-pricing.md),
11
+ [cta-band](recipe-cta-band.md), and [footer](recipe-footer.md).
12
+
13
+ ## When
14
+
15
+ A public page whose job is to explain value and drive one action.
16
+
17
+ ## When not
18
+
19
+ - Signed-in product screens are [dashboard-overview](recipe-dashboard-overview.md) /
20
+ [data-table-page](recipe-data-table-page.md).
21
+ - Do not stack multiple loud brand bands — pick one dominant (usually the hero).
22
+ - One `h1` (in the hero); every section below is `h2`.
23
+
24
+ ## Regions
25
+
26
+ [app-chrome](recipe-app-chrome.md) (marketing nav) -> `main`: full-bleed
27
+ [hero](recipe-hero.md) -> capped column ([logo-wall](recipe-logo-wall.md),
28
+ [feature-section](recipe-feature-section.md)s, [stat-callouts](recipe-stat-callouts.md),
29
+ [testimonial](recipe-testimonial.md), [pricing](recipe-pricing.md)) ->
30
+ full-bleed [cta-band](recipe-cta-band.md) -> [footer](recipe-footer.md)
31
+
32
+ Full-bleed bands (hero, CTA, and any brand band) span the viewport; in-column
33
+ sections cap with `--uxl-breakpoints-max-container-width`. Any section can become a
34
+ full-bleed brand band — keep to one dominant.
35
+
36
+ ## Responsive
37
+
38
+ Every piece carries its own responsiveness (hero panel, `auto-fit` grids, stacking
39
+ clusters) — no page-level breakpoint logic. See
40
+ [how-to-page-layout.md](how-to-page-layout.md#responsiveness).
41
+
42
+ ## Spacing
43
+
44
+ `medium-12` between in-column sections; `large-13`+ block padding for full-bleed
45
+ bands; `--uxl-breakpoints-gutter` inside grids ([spacing-steps.md](spacing-steps.md)).
46
+
47
+ ## A11y
48
+
49
+ One `main`, one `h1` (hero), section headings `h2` in order; skip link and landmarks
50
+ from [app-chrome](recipe-app-chrome.md). Name each section by its heading. See
51
+ [how-to-accessibility.md](how-to-accessibility.md).
52
+
53
+ ## Color
54
+
55
+ One dominant brand band (usually the hero). Apply palettes per section with
56
+ `data-color-switcher`, style with role tokens, keep the calmer sections on `default`
57
+ / `default-subtle` ([how-to-color.md](how-to-color.md)).
58
+
59
+ ## React
60
+
61
+ ```tsx
62
+ <main id="main-content" tabIndex={-1} style={{ flexGrow: 1, minHeight: 0, overflow: "auto" }}>
63
+ {/* Full-bleed hero — recipe-hero.md (contains the h1) */}
64
+ <MarketingHero />
65
+
66
+ {/* Capped content column for the mid-page sections */}
67
+ <Layout
68
+ display="flex"
69
+ flexDirection="column"
70
+ width="100%"
71
+ maxWidth="var(--uxl-breakpoints-max-container-width)"
72
+ mh="auto"
73
+ p="var(--uxl-breakpoints-margin)"
74
+ gap="var(--uxl-theme-layout-spacing-medium-12)"
75
+ >
76
+ <LogoWall /> {/* recipe-logo-wall.md */}
77
+ <FeatureSections /> {/* recipe-feature-section.md (alternating) */}
78
+ <StatCallouts /> {/* recipe-stat-callouts.md */}
79
+ <Testimonials /> {/* recipe-testimonial.md */}
80
+ <Pricing /> {/* recipe-pricing.md */}
81
+ </Layout>
82
+
83
+ {/* Full-bleed closing CTA — recipe-cta-band.md */}
84
+ <CtaBand />
85
+
86
+ {/* Footer — recipe-footer.md (marketing: directory band + legal bar) */}
87
+ <MarketingFooter />
88
+ </main>
89
+ ```
90
+
91
+ ## A2UI
92
+
93
+ No `getUxelleRecipe("landing-page")` — compose the piece adapters in one narrow
94
+ column, in the same order, dropping full-bleed layout (host-owned) ([a2ui.md](a2ui.md)).
@@ -0,0 +1,80 @@
1
+ # Recipe: logo wall
2
+
3
+ A shared **piece**: a row of customer, partner, or integration logos that builds
4
+ trust. Common just under a hero or between marketing sections; also used for an
5
+ "integrates with" band.
6
+
7
+ Composes [`Logo`](../uxelle-components/Logo.md) (brand marks in the catalog),
8
+ [`Image`](../uxelle-components/Image.md) (logos not in the catalog), and
9
+ [`Text`](../uxelle-components/Text.md) for the eyebrow.
10
+
11
+ ## When
12
+
13
+ A set of recognizable marks shown as social proof or integration coverage.
14
+
15
+ ## When not
16
+
17
+ - Not navigation and not a `Footer` — this is a proof band.
18
+ - Do not stretch or distort marks; keep a consistent height and let them wrap.
19
+ - Make a logo interactive only if it links somewhere, and name that control.
20
+
21
+ ## Regions
22
+
23
+ section -> optional eyebrow `Text` -> wrapping, centered row of `Logo` / `Image`
24
+
25
+ ## Responsive
26
+
27
+ `flexWrap="wrap"` with `justifyContent="center"` reflows to as many marks per row as
28
+ fit — no JS, no breakpoint literals. Bound each mark's `width` so rows stay even.
29
+
30
+ ## Spacing
31
+
32
+ `gap="var(--uxl-theme-layout-spacing-medium-8)"` between marks; `small-4` under the
33
+ eyebrow. As a band, add section breathing with `large-13`+ block padding
34
+ ([spacing-steps.md](spacing-steps.md)).
35
+
36
+ ## A11y
37
+
38
+ Name the region (`aria-label="Trusted by leading teams"`). If the mark is meaningful
39
+ and there is no adjacent text, give it an accessible name (`aria-label` on `Logo`,
40
+ `alt` on `Image`); if company names appear as text elsewhere, mark the logos
41
+ `aria-hidden`. See [how-to-accessibility.md](how-to-accessibility.md).
42
+
43
+ ## Color
44
+
45
+ On a brand band, set `data-color-switcher` on the **section** and tint monochrome
46
+ marks with `Logo` `color="colorSwitcherIcon"` (or `background="onDark"` for
47
+ full-color marks on dark). Keep one dominant brand band per view
48
+ ([how-to-color.md](how-to-color.md)).
49
+
50
+ ## React
51
+
52
+ ```tsx
53
+ <Layout
54
+ as="section"
55
+ display="flex"
56
+ flexDirection="column"
57
+ alignItems="center"
58
+ gap="var(--uxl-theme-layout-spacing-small-4)"
59
+ aria-label="Trusted by leading teams"
60
+ >
61
+ <Text type="Overline" width={false}>Trusted by teams at</Text>
62
+ <Layout
63
+ display="flex"
64
+ flexWrap="wrap"
65
+ justifyContent="center"
66
+ alignItems="center"
67
+ gap="var(--uxl-theme-layout-spacing-medium-8)"
68
+ >
69
+ <Logo name="generic" width={112} color="colorSwitcherIcon" aria-label="Northwind" />
70
+ <Logo name="generic" width={112} color="colorSwitcherIcon" aria-label="Acme" />
71
+ {/* Logos not in the catalog use Image */}
72
+ <Image src="/logos/contoso.svg" alt="Contoso" />
73
+ </Layout>
74
+ </Layout>
75
+ ```
76
+
77
+ ## A2UI
78
+
79
+ No `getUxelleRecipe("logo-wall")` — compose `A2uiLogo` / `A2uiImage` inside an
80
+ `A2uiLayout` (single wrapping row, layout-spacing only) ([a2ui.md](a2ui.md)).