blume 1.6.5 → 1.7.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.
Files changed (179) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/bin/blume.mjs +3 -2
  3. package/dist/cli/chunk-0qhq7b8q.js +111 -0
  4. package/dist/cli/chunk-0qhq7b8q.js.map +11 -0
  5. package/dist/cli/chunk-18tjv4f7.js +96 -0
  6. package/dist/cli/chunk-18tjv4f7.js.map +10 -0
  7. package/dist/cli/chunk-27gtm2ym.js +69 -0
  8. package/dist/cli/chunk-27gtm2ym.js.map +11 -0
  9. package/dist/cli/chunk-2aj8ddew.js +72 -0
  10. package/dist/cli/chunk-2aj8ddew.js.map +10 -0
  11. package/dist/cli/chunk-3r94j3tc.js +221 -0
  12. package/dist/cli/chunk-3r94j3tc.js.map +10 -0
  13. package/dist/cli/chunk-4trphnvy.js +102 -0
  14. package/dist/cli/chunk-4trphnvy.js.map +11 -0
  15. package/dist/cli/chunk-4xyggvgf.js +21 -0
  16. package/dist/cli/chunk-4xyggvgf.js.map +10 -0
  17. package/dist/cli/chunk-5d4q7121.js +4064 -0
  18. package/dist/cli/chunk-5d4q7121.js.map +40 -0
  19. package/dist/cli/chunk-5hs6gb7n.js +32 -0
  20. package/dist/cli/chunk-5hs6gb7n.js.map +10 -0
  21. package/dist/cli/chunk-6kzzpsx8.js +26 -0
  22. package/dist/cli/chunk-6kzzpsx8.js.map +10 -0
  23. package/dist/cli/chunk-8gnpdsn1.js +952 -0
  24. package/dist/cli/chunk-8gnpdsn1.js.map +12 -0
  25. package/dist/cli/chunk-9qs6acpw.js +176 -0
  26. package/dist/cli/chunk-9qs6acpw.js.map +10 -0
  27. package/dist/cli/chunk-agy5rzxy.js +2453 -0
  28. package/dist/cli/chunk-agy5rzxy.js.map +15 -0
  29. package/dist/cli/chunk-bcy492zc.js +16 -0
  30. package/dist/cli/chunk-bcy492zc.js.map +10 -0
  31. package/dist/cli/chunk-btfr9yvw.js +41 -0
  32. package/dist/cli/chunk-btfr9yvw.js.map +10 -0
  33. package/dist/cli/chunk-cbjnx4s8.js +73 -0
  34. package/dist/cli/chunk-cbjnx4s8.js.map +10 -0
  35. package/dist/cli/chunk-cfw6x4rm.js +1967 -0
  36. package/dist/cli/chunk-cfw6x4rm.js.map +34 -0
  37. package/dist/cli/chunk-ckh3a410.js +277 -0
  38. package/dist/cli/chunk-ckh3a410.js.map +11 -0
  39. package/dist/cli/chunk-drke6t0h.js +259 -0
  40. package/dist/cli/chunk-drke6t0h.js.map +11 -0
  41. package/dist/cli/chunk-ev67ycx0.js +15 -0
  42. package/dist/cli/chunk-ev67ycx0.js.map +10 -0
  43. package/dist/cli/chunk-ey89bjj1.js +209 -0
  44. package/dist/cli/chunk-ey89bjj1.js.map +11 -0
  45. package/dist/cli/chunk-j6pxe0dt.js +69 -0
  46. package/dist/cli/chunk-j6pxe0dt.js.map +11 -0
  47. package/dist/cli/chunk-jk1zwka1.js +387 -0
  48. package/dist/cli/chunk-jk1zwka1.js.map +12 -0
  49. package/dist/cli/chunk-jtb45atp.js +467 -0
  50. package/dist/cli/chunk-jtb45atp.js.map +14 -0
  51. package/dist/cli/chunk-jxkxjsc1.js +76 -0
  52. package/dist/cli/chunk-jxkxjsc1.js.map +10 -0
  53. package/dist/cli/chunk-kwx90v78.js +81 -0
  54. package/dist/cli/chunk-kwx90v78.js.map +10 -0
  55. package/dist/cli/chunk-n0nyat6g.js +30 -0
  56. package/dist/cli/chunk-n0nyat6g.js.map +10 -0
  57. package/dist/cli/chunk-pxj10x8y.js +35 -0
  58. package/dist/cli/chunk-pxj10x8y.js.map +10 -0
  59. package/dist/cli/chunk-qq9nm3qd.js +1141 -0
  60. package/dist/cli/chunk-qq9nm3qd.js.map +19 -0
  61. package/dist/cli/chunk-s102bysw.js +5170 -0
  62. package/dist/cli/chunk-s102bysw.js.map +47 -0
  63. package/dist/cli/chunk-s5dsk8bj.js +769 -0
  64. package/dist/cli/chunk-s5dsk8bj.js.map +13 -0
  65. package/dist/cli/chunk-s5e5jt53.js +227 -0
  66. package/dist/cli/chunk-s5e5jt53.js.map +11 -0
  67. package/dist/cli/chunk-sbdqrjbb.js +81 -0
  68. package/dist/cli/chunk-sbdqrjbb.js.map +10 -0
  69. package/dist/cli/chunk-tnskyrej.js +117 -0
  70. package/dist/cli/chunk-tnskyrej.js.map +10 -0
  71. package/dist/cli/chunk-v2ymm99c.js +1016 -0
  72. package/dist/cli/chunk-v2ymm99c.js.map +13 -0
  73. package/dist/cli/chunk-v5mm027v.js +185 -0
  74. package/dist/cli/chunk-v5mm027v.js.map +11 -0
  75. package/dist/cli/chunk-vt8fgygt.js +23 -0
  76. package/dist/cli/chunk-vt8fgygt.js.map +10 -0
  77. package/dist/cli/chunk-vxv4x1n8.js +17 -0
  78. package/dist/cli/chunk-vxv4x1n8.js.map +10 -0
  79. package/dist/cli/chunk-wd27zjcz.js +60 -0
  80. package/dist/cli/chunk-wd27zjcz.js.map +10 -0
  81. package/dist/cli/chunk-x66c5yjn.js +23 -0
  82. package/dist/cli/chunk-x66c5yjn.js.map +10 -0
  83. package/dist/cli/chunk-xv91q4nm.js +5314 -0
  84. package/dist/cli/chunk-xv91q4nm.js.map +58 -0
  85. package/dist/cli/chunk-y3g15rvv.js +679 -0
  86. package/dist/cli/chunk-y3g15rvv.js.map +15 -0
  87. package/dist/cli/chunk-ye9zdkgv.js +136 -0
  88. package/dist/cli/chunk-ye9zdkgv.js.map +10 -0
  89. package/dist/cli/chunk-ynacq3ev.js +1062 -0
  90. package/dist/cli/chunk-ynacq3ev.js.map +25 -0
  91. package/dist/cli/chunk-zr3ygrq3.js +54 -0
  92. package/dist/cli/chunk-zr3ygrq3.js.map +10 -0
  93. package/dist/cli/index.js +55 -27597
  94. package/dist/cli/index.js.map +5 -243
  95. package/dist/types/ai/ask-context.d.ts +26 -0
  96. package/dist/types/components/layout/nav-utils.d.ts +33 -1
  97. package/dist/types/core/code-fences.d.ts +11 -0
  98. package/dist/types/core/package-root.d.ts +1 -1
  99. package/dist/types/core/schema.d.ts +70 -0
  100. package/dist/types/theme/fonts.d.ts +22 -22
  101. package/docs/02-deployment.mdx +22 -1
  102. package/docs/configuration/ask-ai.mdx +1 -1
  103. package/docs/configuration/customization.mdx +2 -9
  104. package/docs/content/navigation.mdx +2 -0
  105. package/docs/content/syntax.mdx +1 -1
  106. package/docs/discoverability/open-graph.mdx +4 -0
  107. package/docs/reference/cli.mdx +1 -1
  108. package/package.json +4 -2
  109. package/src/ai/api/handlers.ts +4 -7
  110. package/src/ai/api/paths.ts +8 -0
  111. package/src/ai/api/spec.ts +2 -1
  112. package/src/ai/ask-context.ts +378 -22
  113. package/src/astro/generate.ts +161 -28
  114. package/src/astro/include-hmr.ts +10 -13
  115. package/src/astro/include-refresh.ts +0 -0
  116. package/src/astro/index.ts +6 -1
  117. package/src/astro/integration.ts +280 -53
  118. package/src/astro/module-types.ts +83 -0
  119. package/src/astro/templates.ts +256 -108
  120. package/src/audit/image-size.ts +10 -8
  121. package/src/cli/command-meta.ts +77 -0
  122. package/src/cli/commands/add.ts +2 -4
  123. package/src/cli/commands/audit.ts +2 -4
  124. package/src/cli/commands/build.ts +70 -346
  125. package/src/cli/commands/check.ts +2 -4
  126. package/src/cli/commands/dev.ts +31 -42
  127. package/src/cli/commands/doctor.ts +2 -4
  128. package/src/cli/commands/eject.ts +3 -41
  129. package/src/cli/commands/eval.ts +2 -5
  130. package/src/cli/commands/init.ts +2 -4
  131. package/src/cli/commands/mcp-stdio.ts +2 -5
  132. package/src/cli/commands/preview.ts +3 -5
  133. package/src/cli/commands/sync.ts +2 -4
  134. package/src/cli/commands/translate.ts +2 -5
  135. package/src/cli/commands/validate.ts +2 -4
  136. package/src/cli/commands/version.ts +2 -4
  137. package/src/cli/eject-scripts.ts +0 -45
  138. package/src/cli/host-args.ts +16 -0
  139. package/src/cli/index.ts +84 -35
  140. package/src/cli/lazy-command.ts +47 -0
  141. package/src/components/Icon.astro +24 -0
  142. package/src/components/content/GithubInfo.astro +4 -1
  143. package/src/components/icon-sprite-middleware.ts +41 -0
  144. package/src/components/icon-sprite.ts +93 -0
  145. package/src/components/layout/IconSprite.astro +11 -0
  146. package/src/components/layout/NavTree.astro +156 -188
  147. package/src/components/layout/NavTreeCache.astro +45 -0
  148. package/src/components/layout/NavTreeScript.astro +256 -0
  149. package/src/components/layout/PageActions.astro +11 -5
  150. package/src/components/layout/PageLayout.astro +21 -3
  151. package/src/components/layout/ReferenceLayout.astro +21 -4
  152. package/src/components/layout/RootLayout.astro +44 -6
  153. package/src/components/layout/nav-cache.ts +49 -0
  154. package/src/components/layout/nav-utils.ts +69 -1
  155. package/src/components/layout/page-locale.ts +29 -0
  156. package/src/core/api-name.ts +18 -0
  157. package/src/core/code-fences.ts +48 -0
  158. package/src/core/content-assets.ts +3 -7
  159. package/src/core/includes.ts +3 -7
  160. package/src/core/package-root.ts +1 -1
  161. package/src/core/schema.ts +19 -0
  162. package/src/core/sources/normalize.ts +2 -37
  163. package/src/core/sources/obsidian.ts +3 -2
  164. package/src/core/svg-dimensions.ts +97 -0
  165. package/src/core/version-cut.ts +2 -2
  166. package/src/deploy/artifacts.ts +370 -0
  167. package/src/deploy/cloudflare-negotiation.ts +97 -32
  168. package/src/deploy/function-bundle.ts +66 -20
  169. package/src/deploy/sitemap.ts +6 -0
  170. package/src/deploy/vercel-negotiation.ts +8 -30
  171. package/src/markdown/language-icon.ts +64 -20
  172. package/src/markdown/mermaid.ts +11 -0
  173. package/src/og/cache.ts +236 -0
  174. package/src/og/card.ts +18 -16
  175. package/src/og/index.ts +8 -1
  176. package/src/openapi/render-mdx.ts +9 -5
  177. package/src/registry/eject.ts +23 -10
  178. package/src/theme/entry.ts +41 -7
  179. package/src/theme/fonts.ts +30 -23
@@ -3,6 +3,7 @@ import { fromMarkdown } from "mdast-util-from-markdown";
3
3
  import { toString as mdastToString } from "mdast-util-to-string";
4
4
  import stringWidth from "string-width";
5
5
 
6
+ import { apiNamePhrase } from "../core/api-name.ts";
6
7
  import { columnsPrefix } from "../core/text-width.ts";
7
8
  import type { GraphqlMember } from "./graphql.ts";
8
9
  import { isGraphqlOperationKind } from "./graphql.ts";
@@ -158,6 +159,8 @@ const clip = (text: string, max: number): string => {
158
159
  };
159
160
 
160
161
  const apiName = (spec: ApiSpecData): string => spec.title || spec.label;
162
+ /** The spec's name as "the ___" in generated prose (see `apiNamePhrase`). */
163
+ const apiPhrase = (spec: ApiSpecData): string => apiNamePhrase(apiName(spec));
161
164
 
162
165
  /** Human phrase for each GraphQL page kind, for meta descriptions. */
163
166
  const GRAPHQL_MEMBER_PHRASES = {
@@ -194,16 +197,17 @@ const operationDescription = (
194
197
  }
195
198
  // AsyncAPI operations act on a channel, not an HTTP endpoint; GraphQL pages
196
199
  // document a root field or a named type.
197
- let suffix: string;
200
+ let subject: string;
198
201
  if (spec.kind === "asyncapi") {
199
- suffix = `Reference for the ${operation.method} operation on ${operation.path} in the ${apiName(spec)} API.`;
202
+ subject = `${operation.method} operation on ${operation.path}`;
200
203
  } else if (spec.kind === "graphql") {
201
204
  // SAFETY: the GraphQL extractor only ever assigns member kinds as the
202
205
  // method (see `extractGraphqlOperations`).
203
- suffix = `Reference for the ${operation.path} ${GRAPHQL_MEMBER_PHRASES[operation.method as GraphqlMember]} in the ${apiName(spec)} API.`;
206
+ subject = `${operation.path} ${GRAPHQL_MEMBER_PHRASES[operation.method as GraphqlMember]}`;
204
207
  } else {
205
- suffix = `Reference for the ${operation.method.toUpperCase()} ${operation.path} endpoint in the ${apiName(spec)} API.`;
208
+ subject = `${operation.method.toUpperCase()} ${operation.path} endpoint`;
206
209
  }
210
+ const suffix = `Reference for the ${subject} in the ${apiPhrase(spec)}.`;
207
211
  const prose = clip(
208
212
  plainProse(operation.description || operation.summary),
209
213
  META_DESCRIPTION_MAX - stringWidth(suffix) - 1
@@ -350,7 +354,7 @@ export const overviewMdx = (
350
354
  const seo: RenderedPageData["seo"] = {
351
355
  description:
352
356
  clip(plainProse(spec.description), META_DESCRIPTION_MAX) ||
353
- `${apiName(spec)} API reference.`,
357
+ `${apiPhrase(spec)} reference.`,
354
358
  };
355
359
  if (reference?.noindex) {
356
360
  seo.noindex = true;
@@ -17,24 +17,26 @@ import {
17
17
  } from "../astro/examples.ts";
18
18
  import {
19
19
  buildRuntimeData,
20
+ clientFeaturesFor,
20
21
  collectStaged,
21
22
  detectNeedsReact,
22
23
  detectUsesMath,
24
+ languageIconCssFor,
23
25
  } from "../astro/generate.ts";
24
26
  import { discoverIslands } from "../astro/islands.ts";
25
27
  import { customOgRoutes, discoverPages, routeIsTaken } from "../astro/pages.ts";
26
28
  import {
27
- askEndpointTemplate,
28
29
  askComponentTemplate,
30
+ askEndpointTemplate,
29
31
  astroConfigTemplate,
30
32
  catchAllPageTemplate,
31
33
  changelogIndexTemplate,
32
34
  contentConfigTemplate,
33
- envTemplate,
34
35
  exampleMapTemplate,
35
- exampleWrapperTemplate,
36
- examplesPageTemplate,
37
36
  exampleSlug,
37
+ examplesPageTemplate,
38
+ exampleWrapperTemplate,
39
+ featuresTemplate,
38
40
  islandMapTemplate,
39
41
  islandWrapperTemplate,
40
42
  mcpEndpointTemplate,
@@ -388,6 +390,8 @@ export const eject = async (
388
390
  const staged = collectStaged(project);
389
391
  const hasStaged = staged.size > 0;
390
392
  const stagedDir = "blume-staged";
393
+ const features = await clientFeaturesFor(project);
394
+ const languageIcons = await languageIconCssFor(project);
391
395
 
392
396
  const files: {
393
397
  path: string;
@@ -404,6 +408,8 @@ export const eject = async (
404
408
  context: relContext,
405
409
  examplesPath: "./src/generated/examples.ts",
406
410
  examplesThemePath: "./src/generated/examples.css",
411
+ features,
412
+ featuresPath: "./src/generated/features.ts",
407
413
  // No CLI publishes the runtime data modules in memory after eject, so
408
414
  // the config aliases each to the JSON snapshot written below.
409
415
  generatedModulesDir: "./src/generated",
@@ -427,7 +433,6 @@ export const eject = async (
427
433
  // Never clobber a hand-tuned tsconfig; only write ours if none exists.
428
434
  skipIfExists: true,
429
435
  },
430
- { content: envTemplate(), path: join(srcDir, "env.d.ts") },
431
436
  {
432
437
  content: contentConfigTemplate({
433
438
  config,
@@ -478,6 +483,7 @@ export const eject = async (
478
483
  {
479
484
  content: tailwindEntryTemplate({
480
485
  configTokens: buildThemeCss(config.theme),
486
+ languageIcons,
481
487
  // Relative paths from src/generated/app.css keep the ejected app
482
488
  // portable; the blume glob resolves the real install location when
483
489
  // the package is hoisted out of the project's own node_modules.
@@ -560,11 +566,18 @@ export const eject = async (
560
566
  });
561
567
  }
562
568
 
563
- // The provider-specific client loader behind the `blume:search-client` alias.
564
- files.push({
565
- content: searchClientTemplate(config),
566
- path: join(genDir, "search-client.ts"),
567
- });
569
+ // The client-feature loaders behind the `blume:features` alias, and the
570
+ // provider-specific client loader behind `blume:search-client`.
571
+ files.push(
572
+ {
573
+ content: featuresTemplate(features),
574
+ path: join(genDir, "features.ts"),
575
+ },
576
+ {
577
+ content: searchClientTemplate(config),
578
+ path: join(genDir, "search-client.ts"),
579
+ }
580
+ );
568
581
 
569
582
  if (servesStaticIndex(config.search.provider)) {
570
583
  const documents = await buildSearchDocuments(project);
@@ -20,6 +20,8 @@ interface TailwindEntryOptions {
20
20
  userTheme: string;
21
21
  /** Twoslash rich-renderer styles (for fences with the `twoslash` meta). */
22
22
  twoslashCss?: string;
23
+ /** The code-block language icon rules (`languageIconCss`), if any. */
24
+ languageIcons?: string;
23
25
  }
24
26
 
25
27
  /** Dark mode is driven by `data-theme` on the root element (both sheets). */
@@ -244,6 +246,31 @@ ${THEME_MAPPING}
244
246
  unicode-bidi: isolate;
245
247
  }
246
248
 
249
+ /* The sidebar's rows. A docs site renders every sidebar row on every page,
250
+ so a large site's HTML is mostly this markup — one utility per row kind
251
+ instead of the dozen classes each expands to keeps every page (and the
252
+ build's HTML output) small. Kept in sync with NavTree.astro: a page row,
253
+ a page-mode group's drill-in button, a collapsible group's summary and
254
+ the link inside it, and a flat group's heading and the link inside it. */
255
+ @utility blume-nav-link {
256
+ @apply block rounded-[0.65rem] px-2.5 py-1.5 text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground aria-[current=page]:bg-muted aria-[current=page]:font-medium aria-[current=page]:text-foreground;
257
+ }
258
+ @utility blume-nav-drill {
259
+ @apply flex w-full items-center gap-2 rounded-[0.65rem] px-2.5 py-1.5 text-left font-medium text-foreground text-sm transition-colors hover:bg-muted;
260
+ }
261
+ @utility blume-nav-summary {
262
+ @apply flex cursor-pointer list-none items-center gap-1.5 rounded-[0.65rem] px-2.5 py-1.5 text-muted-foreground text-sm transition-colors hover:bg-muted hover:text-foreground [&::-webkit-details-marker]:hidden;
263
+ }
264
+ @utility blume-nav-summary-link {
265
+ @apply -my-1 flex flex-1 items-center gap-1.5 rounded py-1 transition-colors aria-[current=page]:text-foreground aria-[current=page]:font-semibold;
266
+ }
267
+ @utility blume-nav-heading {
268
+ @apply mb-2 flex items-center gap-1.5 px-2.5 font-medium text-foreground text-sm;
269
+ }
270
+ @utility blume-nav-heading-link {
271
+ @apply -ml-1 flex flex-1 items-center gap-1.5 rounded-[0.65rem] px-1 py-0.5 text-foreground transition-colors hover:bg-muted aria-[current=page]:bg-muted;
272
+ }
273
+
247
274
  /* Theme Tailwind Typography (prose) with Blume tokens. */
248
275
  .prose {
249
276
  --tw-prose-body: var(--blume-foreground);
@@ -459,15 +486,17 @@ blume-diff {
459
486
  CodeBlock (no title) never gets data-language, so without this gate the
460
487
  absolutely-positioned icon would overlap the first code line. Fenced code
461
488
  and titled blocks always have a header, so the icon shows there. */
462
- .blume-lang-icon {
463
- display: none;
464
- }
465
-
466
- .prose > :where(pre[data-language][data-icon]) > .blume-lang-icon {
467
- color: var(--blume-muted-foreground);
468
- display: block;
489
+ .prose > :where(pre[data-language][data-icon])::after {
490
+ content: "";
469
491
  height: 0.875rem;
470
492
  left: 1rem;
493
+ -webkit-mask-position: center;
494
+ -webkit-mask-repeat: no-repeat;
495
+ -webkit-mask-size: contain;
496
+ mask-position: center;
497
+ mask-repeat: no-repeat;
498
+ mask-size: contain;
499
+ pointer-events: none;
471
500
  position: absolute;
472
501
  top: 0.875rem;
473
502
  width: 0.875rem;
@@ -477,6 +506,11 @@ blume-diff {
477
506
  padding-left: 2.5rem;
478
507
  }
479
508
 
509
+ /* One mask rule per language the site's Markdown uses (see
510
+ markdown/language-icon.ts); the ::after above only gets a color and a mask
511
+ from these, so a block whose language has no rule paints nothing. */
512
+ ${options.languageIcons ?? ""}
513
+
480
514
  .prose :where(pre code) {
481
515
  background: transparent;
482
516
  border-radius: 0;
@@ -63,7 +63,14 @@ export type FontValue = string | RemoteFontConfig | LocalFontConfig;
63
63
  interface FontDef {
64
64
  category: FontCategory;
65
65
  family: string;
66
- weights: number[];
66
+ /**
67
+ * Discrete weights, or one `"min..max"` range for a family Google Fonts
68
+ * serves as a variable font: the range loads the same variable file the
69
+ * discrete weights did, declared as one `@font-face` per style instead of
70
+ * one per weight (16 rules down to 4 for Inter on every page). The three
71
+ * static families in the table keep discrete weights.
72
+ */
73
+ weights: (number | string)[];
67
74
  }
68
75
 
69
76
  /** Resolved theme fonts (a validated value per role, all optional). */
@@ -96,22 +103,22 @@ const FALLBACKS = {
96
103
 
97
104
  /** Slug -> Google family + weights + fallback category. Keep keys alphabetical. */
98
105
  export const GOOGLE_FONTS = {
99
- "dm-sans": { category: "sans", family: "DM Sans", weights: [400, 500, 700] },
106
+ "dm-sans": { category: "sans", family: "DM Sans", weights: ["400..700"] },
100
107
  figtree: {
101
108
  category: "sans",
102
109
  family: "Figtree",
103
- weights: [400, 500, 600, 700],
110
+ weights: ["400..700"],
104
111
  },
105
112
  "fira-code": {
106
113
  category: "mono",
107
114
  family: "Fira Code",
108
- weights: [400, 500, 700],
115
+ weights: ["400..700"],
109
116
  },
110
- geist: { category: "sans", family: "Geist", weights: [400, 500, 600, 700] },
117
+ geist: { category: "sans", family: "Geist", weights: ["400..700"] },
111
118
  "geist-mono": {
112
119
  category: "mono",
113
120
  family: "Geist Mono",
114
- weights: [400, 500, 600],
121
+ weights: ["400..600"],
115
122
  },
116
123
  "ibm-plex-mono": {
117
124
  category: "mono",
@@ -121,81 +128,81 @@ export const GOOGLE_FONTS = {
121
128
  "ibm-plex-sans": {
122
129
  category: "sans",
123
130
  family: "IBM Plex Sans",
124
- weights: [400, 500, 600, 700],
131
+ weights: ["400..700"],
125
132
  },
126
133
  "ibm-plex-serif": {
127
134
  category: "serif",
128
135
  family: "IBM Plex Serif",
129
136
  weights: [400, 500, 600],
130
137
  },
131
- inter: { category: "sans", family: "Inter", weights: [400, 500, 600, 700] },
138
+ inter: { category: "sans", family: "Inter", weights: ["400..700"] },
132
139
  "inter-tight": {
133
140
  category: "sans",
134
141
  family: "Inter Tight",
135
- weights: [400, 500, 600, 700],
142
+ weights: ["400..700"],
136
143
  },
137
144
  "jetbrains-mono": {
138
145
  category: "mono",
139
146
  family: "JetBrains Mono",
140
- weights: [400, 500, 700],
147
+ weights: ["400..700"],
141
148
  },
142
- lora: { category: "serif", family: "Lora", weights: [400, 500, 600, 700] },
149
+ lora: { category: "serif", family: "Lora", weights: ["400..700"] },
143
150
  manrope: {
144
151
  category: "sans",
145
152
  family: "Manrope",
146
- weights: [400, 500, 600, 700],
153
+ weights: ["400..700"],
147
154
  },
148
155
  merriweather: {
149
156
  category: "serif",
150
157
  family: "Merriweather",
151
- weights: [400, 700],
158
+ weights: ["400..700"],
152
159
  },
153
160
  "open-sans": {
154
161
  category: "sans",
155
162
  family: "Open Sans",
156
- weights: [400, 600, 700],
163
+ weights: ["400..700"],
157
164
  },
158
165
  "playfair-display": {
159
166
  category: "serif",
160
167
  family: "Playfair Display",
161
- weights: [400, 500, 700],
168
+ weights: ["400..700"],
162
169
  },
163
170
  "plus-jakarta-sans": {
164
171
  category: "sans",
165
172
  family: "Plus Jakarta Sans",
166
- weights: [400, 500, 600, 700],
173
+ weights: ["400..700"],
167
174
  },
168
- roboto: { category: "sans", family: "Roboto", weights: [400, 500, 700] },
175
+ roboto: { category: "sans", family: "Roboto", weights: ["400..700"] },
169
176
  "roboto-mono": {
170
177
  category: "mono",
171
178
  family: "Roboto Mono",
172
- weights: [400, 500, 700],
179
+ weights: ["400..700"],
173
180
  },
174
181
  "source-code-pro": {
175
182
  category: "mono",
176
183
  family: "Source Code Pro",
177
- weights: [400, 500, 600],
184
+ weights: ["400..600"],
178
185
  },
179
186
  "source-sans-3": {
180
187
  category: "sans",
181
188
  family: "Source Sans 3",
182
- weights: [400, 600, 700],
189
+ weights: ["400..700"],
183
190
  },
184
191
  "source-serif-4": {
185
192
  category: "serif",
186
193
  family: "Source Serif 4",
187
- weights: [400, 600, 700],
194
+ weights: ["400..700"],
188
195
  },
189
196
  "space-grotesk": {
190
197
  category: "sans",
191
198
  family: "Space Grotesk",
192
- weights: [400, 500, 700],
199
+ weights: ["400..700"],
193
200
  },
194
201
  "space-mono": { category: "mono", family: "Space Mono", weights: [400, 700] },
195
202
  "work-sans": {
196
203
  category: "sans",
197
204
  family: "Work Sans",
198
- weights: [400, 500, 600],
205
+ weights: ["400..600"],
199
206
  },
200
207
  } satisfies Record<string, FontDef>;
201
208