@tenphi/cookbook 0.20.4 → 0.21.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.
@@ -24,6 +24,13 @@ Start with a complete [configuration recipe](./recipes.md) for common tasks.
24
24
  This page documents the available options; [working examples](./examples.md)
25
25
  covers repository layouts and shared presets.
26
26
 
27
+ For a focused explanation, use [content sources](./content-sources.md),
28
+ [theme basics](./theme-and-components.md),
29
+ [fonts and typography](./fonts-and-typography.md),
30
+ [component styles](./component-styles.md), or
31
+ [publishing metadata](./publishing.md). The sections below are the complete
32
+ configuration reference.
33
+
27
34
  ## Project resolution and presets
28
35
 
29
36
  `cookbook()` and CLI commands discover the same `docs.config.ts`. Set `root`
@@ -105,7 +112,7 @@ single-version site can continue using `site.version` for a simple label.
105
112
  with `src` (one image) or `light` and `dark` (appearance variants). Optional
106
113
  `alt`, `decorative`, `href`, `width`, and `height` control accessible text,
107
114
  destination, and intrinsic sizing. It applies to the header and mobile drawer.
108
- See the [shared logo guide](./theme-and-components.md#a-shared-site-logo).
115
+ See the [shared logo guide](./custom-components.md#a-shared-site-logo).
109
116
  The logo and favicon are independent.
110
117
 
111
118
  ## Site icons
@@ -217,6 +224,10 @@ renderer frontmatter. Use `content.frontmatter: "reject"` to reject unrelated
217
224
  fields. Other supported fields include `aliases`, `template`, `hero`, `editUrl`,
218
225
  `lastUpdated`, `prev`, `next`, `head`, `draft`, and `slug`.
219
226
 
227
+ Set `pagefind: false` to omit an individual published page from search while
228
+ keeping its normal route and navigation. A draft is excluded from search
229
+ regardless of `pagefind`.
230
+
220
231
  ### Draft pages
221
232
 
222
233
  Set `draft: true` to publish a page for review at its normal URL. Drafts remain
@@ -388,7 +399,7 @@ theme: {
388
399
  saturation: 0,
389
400
  contrast: { wcag: [7, 10] }
390
401
  },
391
- textSoft: {
402
+ "text-soft": {
392
403
  base: "surface",
393
404
  tone: [25, 10],
394
405
  saturation: 0.05,
@@ -421,43 +432,47 @@ theme: {
421
432
  },
422
433
  styles: {
423
434
  ThemeSelect: {
424
- Select: { border: "#border-strong" },
425
- Picker: { shadow: "0 1rem 3rem #shadow" }
435
+ Trigger: { border: "#border-strong" },
436
+ Panel: { shadow: "0 1rem 3rem #shadow" }
426
437
  }
427
438
  },
428
439
  contrastLevel: "auto"
429
440
  }
430
441
  ```
431
442
 
432
- The default brand is `okhsl(266 68% 48%)`, a blue with 68% saturation; controls
433
- use an `8px` radius and cards use `16px`. Onest is the default body and heading family, while JetBrains Mono is
434
- used for code. `theme.fonts` loads Google families by name or local files from
435
- `public/`, and applies them to the body, heading, and code presets. See
436
- [Change font families](./theme-and-components.md#change-font-families) for both
437
- flows. The default layout is capped at `87.5rem` (1400px), matching the
438
- Tasty site, with a `58rem` reading column and a `17.5rem` sidebar. `brand.from`
439
- supplies the color seed. `palette` supplies semantic Glaze declarations that
440
- inherit its hue and saturation unless a role supplies its own `from`. `tone` and
441
- a saturation factor set the surface. Reading text uses absolute tones: body
442
- text starts at 0, and headings at 4. Glaze applies normal-mode tone boundaries
443
- and adapts the values for dark mode; `base` and `contrast` provide minimum
444
- contrast safeguards. `palette.heading` follows an explicit `palette.text`
445
- declaration unless customized separately. Glaze resolves light, dark, and both
446
- high-contrast modes independently. Literal color shorthand and structured
447
- brand hue/saturation/tone remain supported. A requested APCA floor below 45 requires the explicit
448
- `unsafeContrast: true` escape hatch. Learn more in
449
- [Theme and components](./theme-and-components.md).
443
+ The default brand is `okhsl(266 68% 48%)`, a blue with 68% saturation.
444
+ Controls use an `8px` radius and cards use `16px`. Onest is the default body
445
+ and heading family; JetBrains Mono is used for code. `theme.fonts` loads Google
446
+ families by name or local files from `public/`. See
447
+ [Fonts and typography](./fonts-and-typography.md) for both flows.
448
+
449
+ The default layout is capped at `87.5rem` (1400px), with a `58rem` reading
450
+ column and a `17.5rem` sidebar. `brand.from` supplies the color seed.
451
+ `theme.palette` supplies semantic Glaze declarations that inherit its hue and
452
+ saturation unless a role has its own `from`. Reading text uses absolute tones:
453
+ body text starts at 0 and headings at 4. Glaze applies normal-mode tone
454
+ boundaries and adapts the values for dark mode; `base` and `contrast` supply
455
+ minimum contrast safeguards. `palette.heading` follows an explicit
456
+ `palette.text` declaration unless configured separately.
457
+
458
+ Glaze resolves light, dark, and both high-contrast modes independently.
459
+ Literal brand color shorthand and structured hue/saturation/tone declarations
460
+ remain supported. An APCA floor below 45 requires `unsafeContrast: true`.
461
+ See [Theme and components](./theme-and-components.md) for the color model and
462
+ examples.
450
463
 
451
464
  `theme.styles` is keyed by Cookbook UI surface name. A plain Tasty style object
452
465
  contains only the properties to override; Cookbook deep-merges it into that
453
466
  surface's complete base object internally. Unknown built-in names and sub-elements are rejected. Register custom
454
467
  component names and their overrides in `theme.customStyles`. Structural Astro overrides under
455
468
  `components.overrides` remain available when styling alone is insufficient.
456
- `theme.states` registers additional Tasty state shorthands, and `contrastLevel`
457
- is forwarded to Glaze's palette resolution.
469
+ `theme.states` registers additional Tasty state shorthands or replaces a
470
+ built-in alias; see the [responsive state reference](./component-styles.md#responsive-states)
471
+ for all nine defaults. `contrastLevel` is forwarded to Glaze's palette
472
+ resolution.
458
473
  The built-in documentation navigation surfaces are available as `Sidebar`,
459
474
  `TableOfContents`, `MobileMenuToggle`, and `MobileNavigationTabs`; see
460
- [Theme and components](./theme-and-components.md#style-customization) for their
475
+ [Component styles](./component-styles.md#style-customization) for their
461
476
  complete sub-element lists.
462
477
 
463
478
  ## Markdown
@@ -521,7 +536,11 @@ search: {
521
536
  ```
522
537
 
523
538
  Search is generated locally with Pagefind during a static build. Disable it
524
- for hosts or fixtures that do not need an index.
539
+ for hosts or fixtures that do not need an index. Readers can open the search
540
+ dialog with Ctrl+K (⌘+K on macOS), type a query, and close it with Escape.
541
+ Search loads its index when opened, so a development server shows a notice
542
+ instead of results. Build and preview the site to test actual results. See
543
+ [Search and navigation](./site-navigation.md) for the reader experience.
525
544
 
526
545
  ## Components
527
546
 
@@ -537,6 +556,20 @@ components: {
537
556
  Component replacement is the advanced escape hatch. Prefer theme tokens and
538
557
  named styles for visual changes that do not need new structure.
539
558
 
559
+ Cookbook uses these Astro component slots. A relative override path resolves
560
+ from the project root; a package specifier resolves from the app's dependencies:
561
+
562
+ | Area | Override names |
563
+ | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
564
+ | Page shell | `Head`, `PageFrame`, `Header`, `Footer`, `Sidebar`, `Hero`, `SiteTitle` |
565
+ | Navigation and controls | `Search`, `LanguageSelect`, `ThemeSelect`, `SocialIcons`, `MobileMenuToggle`, `MobileMenuFooter`, `MobileTableOfContents`, `TableOfContents`, `Pagination` |
566
+ | Content and metadata | `MarkdownContent`, `DraftContentNotice`, `EditLink`, `LastUpdated` |
567
+
568
+ An override owns its markup and interaction behavior. Page overrides can read
569
+ the validated route and navigation data from `Astro.locals.cookbookRoute`;
570
+ see [Extending Cookbook](./plugins.md#read-the-content-graph). Use
571
+ [Custom components](./custom-components.md) for a complete site title example.
572
+
540
573
  Cookbook uses its built-in footer by default, including the “Generated with
541
574
  Cookbook” credit. Replace the complete footer with the `Footer` component path
542
575
  shown above, or remove it with:
@@ -0,0 +1,367 @@
1
+ ---
2
+ title: Custom components
3
+ description: Style your Astro and MDX components with Tasty and validate their tokens and parts.
4
+ ---
5
+
6
+ Use this guide after [theme configuration](./theme-and-components.md) when you
7
+ need markup beyond Cookbook's built-in surfaces. For ordinary visual changes,
8
+ consult the [component styles](./component-styles.md) reference first.
9
+
10
+ ## Authoring custom components
11
+
12
+ Import styling tools from `@tenphi/cookbook/styling`. They use the same Tasty
13
+ runtime as Cookbook, with its semantic colors, typography presets, units, and
14
+ responsive states. The renderer package also exposes them from
15
+ `@tenphi/renderer/styling`.
16
+
17
+ | Export | Purpose |
18
+ | ------------------------ | ---------------------------------------------------------------------------------- |
19
+ | `defineComponent` | Create a named Tasty component with its `theme.customStyles[name]` overrides. |
20
+ | `tasty` | Use Tasty directly without binding a component to `theme.customStyles`. |
21
+ | `useGlobalStyles` | Collect a global Tasty style tree while rendering a page. |
22
+ | `resolveComponentStyles` | Merge `theme.customStyles[name]` into a complete base style tree for global rules. |
23
+ | `mergeStyles` | Compose your own base styles with Tasty's deep-merge semantics. |
24
+ | `Styles` | TypeScript type for a Tasty style object. |
25
+
26
+ Cookbook supplies the React renderer and extracts these styles into its static
27
+ CSS. No additional Tasty dependency, Astro integration, or `client:*` directive
28
+ is needed for static components. Set shared tokens, presets, and states in
29
+ `docs.config.ts` before rendering. Import the styling entry point in component
30
+ modules; configuration files should import `defineDocsConfig()` from
31
+ `@tenphi/cookbook/config`.
32
+
33
+ ### A small named component
34
+
35
+ For a component used by your pages, give its root a name and define its parts
36
+ inside the same style object:
37
+
38
+ ```ts
39
+ // src/components/StatusBadge.ts
40
+ import { defineComponent } from "@tenphi/cookbook/styling";
41
+
42
+ export const StatusBadge = defineComponent("StatusBadge", {
43
+ as: "span",
44
+ styles: {
45
+ display: "inline-flex",
46
+ padding: "0.5x 1x",
47
+ radius: "$radius",
48
+ fill: "#surface-2",
49
+ color: "#text",
50
+ preset: "small",
51
+ Label: { $: "> strong", preset: "strong" },
52
+ },
53
+ });
54
+ ```
55
+
56
+ Use `<StatusBadge><strong>Stable</strong></StatusBadge>` in a local MDX page.
57
+ A site can change just one part in `docs.config.ts`:
58
+
59
+ ```ts
60
+ theme: {
61
+ customStyles: {
62
+ StatusBadge: { Label: { color: "#accent-text" } },
63
+ },
64
+ }
65
+ ```
66
+
67
+ `theme.customStyles` supplies a partial style object. `defineComponent()`
68
+ merges it with the base styles while rendering on the server. Document the
69
+ root name and every named part when sharing a custom component.
70
+
71
+ ### A shared site logo
72
+
73
+ Set `site.logo` once to use your artwork in the header and mobile drawer:
74
+
75
+ ```ts
76
+ site: {
77
+ title: "Acme",
78
+ logo: "./assets/acme.svg"
79
+ }
80
+ ```
81
+
82
+ Paths are local files relative to the resolved project root, just like
83
+ `site.favicon`. Cookbook reads the intrinsic dimensions and copies the image to
84
+ a content-hashed URL under the deployment base. SVG, PNG, JPEG, WebP, AVIF, and
85
+ GIF are supported. Missing or invalid files fail during setup.
86
+
87
+ ```ts
88
+ site: {
89
+ title: "Acme",
90
+ logo: {
91
+ light: "./assets/acme-light.svg",
92
+ dark: "./assets/acme-dark.svg",
93
+ alt: "Acme documentation",
94
+ href: "/",
95
+ decorative: true
96
+ },
97
+ favicon: "./assets/acme-icon.svg"
98
+ }
99
+ ```
100
+
101
+ Use `src` for one image, or both `light` and `dark`. Variants follow the
102
+ appearance control and the system preference in Auto mode. They must share an
103
+ aspect ratio to prevent layout shifts. Optional `width` and `height` describe
104
+ intrinsic dimensions; Tasty controls display size. Customize
105
+ `theme.styles.SiteLogo` and its complete anatomy: `Image`, `Light`, and `Dark`.
106
+ Wide wordmarks retain their proportions within the header.
107
+
108
+ The logo is decorative by default because the neighboring title labels the
109
+ site. Set `decorative: false` and `alt` when the image itself carries meaningful
110
+ text. The header logo link still has a name when the image is decorative.
111
+ `href` defaults to the localized documentation home; it accepts a root-relative
112
+ documentation route or HTTP(S) destination. The header title and drawer use the
113
+ same destination. `site.logo: false` removes the mark from both locations.
114
+
115
+ A logo does not change the favicon or touch icons. Configure `site.favicon`
116
+ separately for square artwork; the default Cookbook icon set remains in place
117
+ until changed. `Logo` remains available as the standalone Cookbook book mark.
118
+
119
+ The built-in mark uses `theme.palette["logo-surface"]` and `theme.palette["logo-mark"]`.
120
+ The default homepage hero artwork also uses `logo-surface` for its brand fill.
121
+ Both default to Glaze `mode: "fixed"`: the brand background and light book keep
122
+ their polarity in dark mode while respecting Glaze's tone boundaries and
123
+ high-contrast settings. The mark-to-background contrast floor is 3:1 normally
124
+ and 4.5:1 in high contrast. These colors are separate from interactive accents.
125
+ For example, to customize the logo background while retaining brand hue:
126
+
127
+ ```ts
128
+ theme: {
129
+ brand: { from: "#315efb" },
130
+ palette: {
131
+ "logo-surface": {
132
+ base: "logo-mark",
133
+ tone: 40,
134
+ saturation: 0.8,
135
+ mode: "fixed",
136
+ contrast: { wcag: [3, 4.5] },
137
+ },
138
+ "logo-mark": { tone: 100, saturation: 0, mode: "fixed" },
139
+ },
140
+ }
141
+ ```
142
+
143
+ Custom image assets keep their authored colors; use `light`/`dark` files when
144
+ you want distinct artwork. Header and drawer home links center logos with the
145
+ site title regardless of their aspect ratio. Use `theme.styles.SiteLogo` for
146
+ image size and `theme.styles.Header.SiteTitle` / `Sidebar.HomeLink`
147
+ for typography; they do not need baseline offsets for a different preset.
148
+
149
+ ### Advanced site title markup
150
+
151
+ To put your own logo and title in one home link, create
152
+ `docs/components/site-title.ts`:
153
+
154
+ ```ts
155
+ import { defineComponent } from "@tenphi/cookbook/styling";
156
+
157
+ export const SiteTitleRoot = defineComponent("ProjectSiteTitle", {
158
+ as: "a",
159
+ styles: {
160
+ display: "flex",
161
+ alignItems: "center",
162
+ gap: "1x",
163
+ inlineSize: "min 0",
164
+ color: "#text",
165
+ preset: { "": "h4 / strong", "@mobile": "h5 / strong" },
166
+ textDecoration: "none",
167
+ Logo: {
168
+ $: "> svg",
169
+ display: "block",
170
+ flexShrink: "0",
171
+ inlineSize: { "": "2rem", "@mobile": "1.75rem" },
172
+ blockSize: { "": "2rem", "@mobile": "1.75rem" },
173
+ color: "#accent-text",
174
+ },
175
+ Label: {
176
+ $: "> span",
177
+ inlineSize: "min 0",
178
+ overflow: "hidden",
179
+ textOverflow: "ellipsis",
180
+ whiteSpace: "nowrap",
181
+ },
182
+ },
183
+ });
184
+ ```
185
+
186
+ Then create `docs/components/SiteTitle.astro`, using an SVG whose paths use
187
+ `currentColor` to follow the semantic accent color:
188
+
189
+ ```astro
190
+ ---
191
+ import ProjectLogo from "../../public/logo.svg";
192
+ import { SiteTitleRoot } from "./site-title.js";
193
+
194
+ const { siteTitle, siteTitleHref } = Astro.locals.cookbookRoute;
195
+ ---
196
+
197
+ <SiteTitleRoot href={siteTitleHref}>
198
+ <ProjectLogo aria-hidden="true" focusable="false" />
199
+ <span translate="no">{siteTitle}</span>
200
+ </SiteTitleRoot>
201
+ ```
202
+
203
+ Register the replacement in `docs.config.ts` and disable the shared mark.
204
+ A `SiteTitle` override affects the header; use `site.logo` above for ordinary
205
+ branding shared with the drawer. For custom drawer markup, override `Sidebar`.
206
+ The custom component supports root styles plus its complete list of named
207
+ sub-elements: `Logo` and `Label`.
208
+
209
+ ```ts
210
+ site: { logo: false },
211
+ components: {
212
+ overrides: {
213
+ SiteTitle: "./docs/components/SiteTitle.astro"
214
+ }
215
+ },
216
+ theme: {
217
+ customStyles: {
218
+ ProjectSiteTitle: { Logo: { color: "#text" } }
219
+ }
220
+ }
221
+ ```
222
+
223
+ `defineComponent(name, options)` accepts Tasty factory options and a name for
224
+ `theme.customStyles[name]`. It merges the configured partial style object before
225
+ creating the component, retaining the other base properties and responsive
226
+ states. Tasty options such as `elements`, `variants`, `styleProps`, `modProps`,
227
+ and `tokenProps` keep their behavior and inferred types, including generated
228
+ subcomponents such as `Component.Label`.
229
+ Configured styles become the component's defaults; variants and styles passed
230
+ at render time follow Tasty's usual precedence.
231
+
232
+ Use `defineComponent` when authoring a component that should support
233
+ `theme.customStyles`. Use `tasty` directly for ordinary Tasty creation or composition
234
+ that does not need a configuration name. To define a named component around
235
+ an existing React component that forwards `className`, pass it as `as` in the options. Use `className`
236
+ when passing a class to a Tasty component from Astro.
237
+
238
+ ### Global style trees
239
+
240
+ For markup you do not render through a Tasty component, call
241
+ `useGlobalStyles()` during rendering. For example, this Astro component
242
+ supports root styles and a `Label` sub-element through `theme.customStyles.ProjectNote`:
243
+
244
+ ```astro
245
+ ---
246
+ import {
247
+ resolveComponentStyles,
248
+ useGlobalStyles,
249
+ } from "@tenphi/cookbook/styling";
250
+
251
+ useGlobalStyles(
252
+ ".project-note",
253
+ resolveComponentStyles("ProjectNote", {
254
+ padding: "2x",
255
+ fill: "#surface-2",
256
+ Label: { $: "> strong", color: "#text", preset: "strong" },
257
+ }),
258
+ );
259
+ ---
260
+
261
+ <aside class="project-note"><strong>Note</strong><slot /></aside>
262
+ ```
263
+
264
+ `defineComponent` and `resolveComponentStyles` read the same `theme.customStyles`
265
+ configuration; user configuration contains only the properties to change. Each custom style name must match a call to one of these helpers.
266
+
267
+ ## Linting custom styles
268
+
269
+ `@tenphi/cookbook/eslint-plugin` re-exports the Tasty ESLint plugin together with
270
+ Cookbook's `validationConfig`. The renderer offers the same exports from
271
+ `@tenphi/renderer/eslint-plugin`. Keep style definitions in `.ts` or `.tsx`
272
+ modules, as in the site title example above, to lint them with either ESLint or
273
+ oxlint.
274
+
275
+ Create `tasty.config.ts` at your project root:
276
+
277
+ ```ts
278
+ export default {
279
+ extends: "@tenphi/cookbook",
280
+ };
281
+ ```
282
+
283
+ Renderer-only consumers can use `extends: "@tenphi/renderer"` instead.
284
+ The preset registers both Cookbook styling import paths, its built-in tokens,
285
+ units, responsive states, and typography presets. It also describes
286
+ `defineComponent`, `resolveComponentStyles`, and `mergeStyles`, so their inline
287
+ style objects, variants, and named sub-elements receive the same checks as
288
+ `tasty()` calls. Partial overrides passed to `mergeStyles` may omit default state
289
+ values and retain the plugin's safeguards against fixes that replace base styles.
290
+
291
+ ### ESLint
292
+
293
+ Install ESLint and a TypeScript parser:
294
+
295
+ ```sh
296
+ pnpm add -D eslint @typescript-eslint/parser
297
+ ```
298
+
299
+ Add the plugin to `eslint.config.mjs`:
300
+
301
+ ```js
302
+ import parser from "@typescript-eslint/parser";
303
+ import tasty from "@tenphi/cookbook/eslint-plugin";
304
+
305
+ export default [
306
+ {
307
+ ...tasty.configs.recommended,
308
+ files: ["**/*.{ts,tsx}"],
309
+ languageOptions: { parser },
310
+ },
311
+ ];
312
+ ```
313
+
314
+ Run `pnpm exec eslint docs/components --max-warnings 0`. Use
315
+ `tasty.configs.strict` for additional checks, including custom property names and
316
+ runtime style values. The named `recommended` and `strict` exports contain rule
317
+ maps for configurations that register the plugin themselves.
318
+
319
+ ### oxlint
320
+
321
+ Install oxlint:
322
+
323
+ ```sh
324
+ pnpm add -D oxlint
325
+ ```
326
+
327
+ Create `oxlint.config.mjs` using its JavaScript plugin support:
328
+
329
+ ```js
330
+ import { recommended } from "@tenphi/cookbook/eslint-plugin";
331
+
332
+ export default {
333
+ jsPlugins: [{ name: "tasty", specifier: "@tenphi/cookbook/eslint-plugin" }],
334
+ rules: recommended,
335
+ };
336
+ ```
337
+
338
+ Run `pnpm exec oxlint --config oxlint.config.mjs docs/components --deny-warnings`.
339
+ The `tasty` alias keeps rule names such as `tasty/known-property` consistent with
340
+ ESLint. Import `strict` instead of `recommended` to enable the stricter rule map.
341
+ Both presets are tested with oxlint 1.83.0; JavaScript plugin support is experimental.
342
+
343
+ ### Custom theme names
344
+
345
+ Add names introduced by your `docs.config.ts` theme to the validation config.
346
+ For example, after defining `theme.tokens["$project-gap"]`, `theme.states["@project-wide"]`,
347
+ and `theme.presets["project-title"]`:
348
+
349
+ ```ts
350
+ import type { TastyValidationConfig } from "@tenphi/cookbook/eslint-plugin";
351
+
352
+ export default {
353
+ extends: "@tenphi/cookbook",
354
+ tokens: ["$project-gap"],
355
+ states: ["@project-wide"],
356
+ presets: ["project-title"],
357
+ } satisfies TastyValidationConfig;
358
+ ```
359
+
360
+ `extends` merges and deduplicates these arrays with the inherited configuration,
361
+ so list only your additions. It also inherits the styling helper signatures;
362
+ entries you add to `styleFunctions` override inherited signatures by function name.
363
+ The exported `validationConfig` object remains available for programmatic use.
364
+ The entry point also exports the upstream `StyleFunctionConfig` and
365
+ `ResolvedConfig` types for shared lint configurations. Additional imported
366
+ helpers can be registered in `styleFunctions`; use `partial: true` for helpers
367
+ that merge overrides into existing styles.
@@ -14,7 +14,7 @@ registries or internal helpers.
14
14
  Inspect `docs.config.ts`, `tasty.config.ts`, and the components you are changing.
15
15
  Reuse the site's existing semantic colors, tokens, presets, responsive states,
16
16
  and named sub-elements. Do not invent configuration names. Consult the complete
17
- [component anatomy reference](./theme-and-components.md#style-customization)
17
+ [component anatomy reference](./component-styles.md#style-customization)
18
18
  before overriding a built-in component.
19
19
 
20
20
  ## Choose the customization surface
@@ -76,8 +76,9 @@ belong in `docs.config.ts`.
76
76
  of spreading component anatomy across unrelated global rules.
77
77
  * Use semantic color tokens such as `#text`, `#surface`, and `#accent-text`
78
78
  in component styles. Configure Glaze color declarations through `theme.brand`
79
- and the supported `theme.palette` roles so Glaze can resolve every scheme and
80
- contrast mode. Do not hard-code component colors or invent palette keys.
79
+ and `theme.palette` so Glaze can resolve every scheme and contrast mode.
80
+ Declare any new semantic color role in `theme.palette` before using its
81
+ `#name` token. Do not hard-code component colors.
81
82
  * Apply semantic typography with `preset`, for example `"small"` or
82
83
  `"h2 / strong"`. Do not reconstruct presets from individual font tokens or
83
84
  wire modifier internals such as `$bold-font-weight` yourself.
@@ -88,7 +89,7 @@ belong in `docs.config.ts`.
88
89
  * When replacing a component, own its markup and behavior. Keep keyboard
89
90
  access, focus, semantics, responsive behavior, and appearance modes intact.
90
91
 
91
- The [custom component examples](./theme-and-components.md#authoring-custom-components)
92
+ The [custom component examples](./custom-components.md#authoring-custom-components)
92
93
  show both a component root and a global style tree using these APIs.
93
94
 
94
95
  ## Read the underlying references
@@ -151,7 +152,7 @@ cookbook doctor, and build commands after changes.
151
152
 
152
153
  ## Check the result
153
154
 
154
- Adopt the [Cookbook Tasty lint configuration](./theme-and-components.md#linting-custom-styles)
155
+ Adopt the [Cookbook Tasty lint configuration](./custom-components.md#linting-custom-styles)
155
156
  and extend its built-in vocabulary in `tasty.config.ts`:
156
157
 
157
158
  ```ts
@@ -0,0 +1,109 @@
1
+ ---
2
+ title: Primeros pasos
3
+ description: Crea un sitio de documentación, documenta un repositorio existente o usa un paquete npm publicado.
4
+ sidebar:
5
+ order: 2
6
+ ---
7
+
8
+ Cookbook requiere Node.js 22.19 o una versión posterior.
9
+
10
+ ## Crea tu primer sitio
11
+
12
+ ```sh
13
+ npm create @tenphi/cookbook@latest my-docs -- --yes
14
+ cd my-docs
15
+ npm run dev
16
+ ```
17
+
18
+ El creador genera un README, la configuración de Astro y `docs.config.ts`, e instala las dependencias. También escribe `AGENTS.md` con instrucciones para agentes de programación. Edita `README.md` para cambiar la página de inicio. Añade `docs/guide.md` para crear `/guide`. Las páginas nuevas o modificadas aparecen en el servidor de desarrollo sin reiniciarlo.
19
+
20
+ ## Documenta un repositorio existente
21
+
22
+ Ejecuta estos comandos desde la raíz del repositorio:
23
+
24
+ ```sh
25
+ npm create @tenphi/cookbook@latest docs-site -- --source . --yes
26
+ cd docs-site
27
+ npm run dev
28
+ ```
29
+
30
+ El archivo `docs.config.ts` generado apunta a tu repositorio. El README de la raíz se convierte en la página de inicio y `docs/**/*.{md,mdx}` aporta las demás páginas. Cookbook lee esos archivos sin copiarlos ni modificarlos.
31
+
32
+ Usa `--no-install` para generar los archivos sin instalar las dependencias. En modo no interactivo, el creador se niega a sobrescribir un directorio de destino que no esté vacío.
33
+
34
+ ## Documenta un paquete npm publicado
35
+
36
+ ```sh
37
+ npm create @tenphi/cookbook@latest my-package-docs -- \
38
+ --package @scope/package@latest --yes
39
+ cd my-package-docs
40
+ npm run dev
41
+ ```
42
+
43
+ El creador descubre la documentación dentro del paquete publicado y guarda su versión exacta y su valor de integridad en `cookbook.lock.json`. Incluye este archivo en Git. El paquete documentado no se instala ni se ejecutan sus scripts. Ejecuta `npm run update` cuando quieras resolver de nuevo la etiqueta o el rango de versiones solicitado.
44
+
45
+ ## Añádelo a un proyecto Astro existente
46
+
47
+ Cookbook requiere `output: "static"` en Astro. Si tu proyecto usa `output: "server"`, crea un proyecto Astro independiente para la documentación estática.
48
+
49
+ ```sh
50
+ npx astro add @tenphi/cookbook
51
+ ```
52
+
53
+ La configuración de Astro necesita una sola integración:
54
+
55
+ ```ts
56
+ import { defineConfig } from "astro/config";
57
+ import cookbook from "@tenphi/cookbook";
58
+
59
+ export default defineConfig({ integrations: [cookbook()] });
60
+ ```
61
+
62
+ Cookbook incluye su renderizador Astro y detecta `docs.config.ts` automáticamente. Sin configuración de documentación, usa las convenciones de README y `docs/`.
63
+
64
+ ## Configura el sitio
65
+
66
+ Empieza con las [recetas completas de marca, logotipo y fuentes](../recipes.md). Para cambios de estilo más detallados o componentes nuevos, consulta las [reglas de personalización](../customization-rules.md). Estas reglas y las referencias originales también se incluyen en el paquete instalado de Cookbook.
67
+
68
+ Crea `docs.config.ts` junto a `astro.config.ts`:
69
+
70
+ ```ts
71
+ import { defineDocsConfig } from "@tenphi/cookbook/config";
72
+
73
+ export default defineDocsConfig({
74
+ site: {
75
+ title: "Example Project",
76
+ description: "Documentation for Example Project",
77
+ repository: "https://github.com/example/project",
78
+ },
79
+ theme: {
80
+ brand: { from: "#2f5bff" },
81
+ fonts: { body: "Inter", heading: "Newsreader" },
82
+ },
83
+ });
84
+ ```
85
+
86
+ Cambia `theme.fonts` para usar [Google Fonts por nombre o tus propios archivos de fuentes](../fonts-and-typography.md). Usa `theme.presets` para los detalles tipográficos, `theme.styles` para los elementos integrados y `defineComponent()` con `theme.customStyles` para añadir elementos. La [guía del tema](../theme-and-components.md) es un punto de partida; la [referencia de estilos de componentes](../component-styles.md) enumera todas las partes personalizables.
87
+
88
+ La integración y la CLI cargan la misma configuración. Se admiten `docs.config.ts`, `.mts`, `.js` y `.mjs`, en ese orden. Un objeto `config` explícito en la integración tiene prioridad; `configFile: false` desactiva la detección. Usa `cookbook({ configFile: "./config/manual.ts" })` y `cookbook doctor --config ./config/manual.ts` para una ubicación no estándar.
89
+
90
+ ## Raíces de monorepositorios
91
+
92
+ Una aplicación en `apps/docs/` puede usar el contenido del repositorio con:
93
+
94
+ ```ts
95
+ import { defineDocsConfig } from "@tenphi/cookbook/config";
96
+
97
+ export default defineDocsConfig({ root: "../.." });
98
+ ```
99
+
100
+ `root` es relativo al archivo de configuración de la documentación. Determina dónde se encuentran el contenido, los recursos locales y `cookbook.lock.json`. Ejecuta `npm run doctor` desde el directorio de la aplicación: resolverá la misma raíz que la integración. Cada fuente también puede declarar su propia raíz para sitios con varios paquetes.
101
+
102
+ ## Valida y publica
103
+
104
+ ```sh
105
+ npm run validate
106
+ npm run preview
107
+ ```
108
+
109
+ El resto de las guías se encuentra actualmente en inglés: [ejemplos](../examples.md), [componentes para redactar](../authoring.mdx), [flujo para agentes de IA](../ai-agents.md), [despliegue](../deployment.md) y [actualización entre versiones](../migration.md). Puedes partir de las [recetas](../recipes.md) para adaptar una configuración completa. Si falla la validación, consulta [solución de problemas](../troubleshooting.md).