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.
- package/CHANGELOG.md +39 -0
- package/bin/blume.mjs +3 -2
- package/dist/cli/chunk-0qhq7b8q.js +111 -0
- package/dist/cli/chunk-0qhq7b8q.js.map +11 -0
- package/dist/cli/chunk-18tjv4f7.js +96 -0
- package/dist/cli/chunk-18tjv4f7.js.map +10 -0
- package/dist/cli/chunk-27gtm2ym.js +69 -0
- package/dist/cli/chunk-27gtm2ym.js.map +11 -0
- package/dist/cli/chunk-2aj8ddew.js +72 -0
- package/dist/cli/chunk-2aj8ddew.js.map +10 -0
- package/dist/cli/chunk-3r94j3tc.js +221 -0
- package/dist/cli/chunk-3r94j3tc.js.map +10 -0
- package/dist/cli/chunk-4trphnvy.js +102 -0
- package/dist/cli/chunk-4trphnvy.js.map +11 -0
- package/dist/cli/chunk-4xyggvgf.js +21 -0
- package/dist/cli/chunk-4xyggvgf.js.map +10 -0
- package/dist/cli/chunk-5d4q7121.js +4064 -0
- package/dist/cli/chunk-5d4q7121.js.map +40 -0
- package/dist/cli/chunk-5hs6gb7n.js +32 -0
- package/dist/cli/chunk-5hs6gb7n.js.map +10 -0
- package/dist/cli/chunk-6kzzpsx8.js +26 -0
- package/dist/cli/chunk-6kzzpsx8.js.map +10 -0
- package/dist/cli/chunk-8gnpdsn1.js +952 -0
- package/dist/cli/chunk-8gnpdsn1.js.map +12 -0
- package/dist/cli/chunk-9qs6acpw.js +176 -0
- package/dist/cli/chunk-9qs6acpw.js.map +10 -0
- package/dist/cli/chunk-agy5rzxy.js +2453 -0
- package/dist/cli/chunk-agy5rzxy.js.map +15 -0
- package/dist/cli/chunk-bcy492zc.js +16 -0
- package/dist/cli/chunk-bcy492zc.js.map +10 -0
- package/dist/cli/chunk-btfr9yvw.js +41 -0
- package/dist/cli/chunk-btfr9yvw.js.map +10 -0
- package/dist/cli/chunk-cbjnx4s8.js +73 -0
- package/dist/cli/chunk-cbjnx4s8.js.map +10 -0
- package/dist/cli/chunk-cfw6x4rm.js +1967 -0
- package/dist/cli/chunk-cfw6x4rm.js.map +34 -0
- package/dist/cli/chunk-ckh3a410.js +277 -0
- package/dist/cli/chunk-ckh3a410.js.map +11 -0
- package/dist/cli/chunk-drke6t0h.js +259 -0
- package/dist/cli/chunk-drke6t0h.js.map +11 -0
- package/dist/cli/chunk-ev67ycx0.js +15 -0
- package/dist/cli/chunk-ev67ycx0.js.map +10 -0
- package/dist/cli/chunk-ey89bjj1.js +209 -0
- package/dist/cli/chunk-ey89bjj1.js.map +11 -0
- package/dist/cli/chunk-j6pxe0dt.js +69 -0
- package/dist/cli/chunk-j6pxe0dt.js.map +11 -0
- package/dist/cli/chunk-jk1zwka1.js +387 -0
- package/dist/cli/chunk-jk1zwka1.js.map +12 -0
- package/dist/cli/chunk-jtb45atp.js +467 -0
- package/dist/cli/chunk-jtb45atp.js.map +14 -0
- package/dist/cli/chunk-jxkxjsc1.js +76 -0
- package/dist/cli/chunk-jxkxjsc1.js.map +10 -0
- package/dist/cli/chunk-kwx90v78.js +81 -0
- package/dist/cli/chunk-kwx90v78.js.map +10 -0
- package/dist/cli/chunk-n0nyat6g.js +30 -0
- package/dist/cli/chunk-n0nyat6g.js.map +10 -0
- package/dist/cli/chunk-pxj10x8y.js +35 -0
- package/dist/cli/chunk-pxj10x8y.js.map +10 -0
- package/dist/cli/chunk-qq9nm3qd.js +1141 -0
- package/dist/cli/chunk-qq9nm3qd.js.map +19 -0
- package/dist/cli/chunk-s102bysw.js +5170 -0
- package/dist/cli/chunk-s102bysw.js.map +47 -0
- package/dist/cli/chunk-s5dsk8bj.js +769 -0
- package/dist/cli/chunk-s5dsk8bj.js.map +13 -0
- package/dist/cli/chunk-s5e5jt53.js +227 -0
- package/dist/cli/chunk-s5e5jt53.js.map +11 -0
- package/dist/cli/chunk-sbdqrjbb.js +81 -0
- package/dist/cli/chunk-sbdqrjbb.js.map +10 -0
- package/dist/cli/chunk-tnskyrej.js +117 -0
- package/dist/cli/chunk-tnskyrej.js.map +10 -0
- package/dist/cli/chunk-v2ymm99c.js +1016 -0
- package/dist/cli/chunk-v2ymm99c.js.map +13 -0
- package/dist/cli/chunk-v5mm027v.js +185 -0
- package/dist/cli/chunk-v5mm027v.js.map +11 -0
- package/dist/cli/chunk-vt8fgygt.js +23 -0
- package/dist/cli/chunk-vt8fgygt.js.map +10 -0
- package/dist/cli/chunk-vxv4x1n8.js +17 -0
- package/dist/cli/chunk-vxv4x1n8.js.map +10 -0
- package/dist/cli/chunk-wd27zjcz.js +60 -0
- package/dist/cli/chunk-wd27zjcz.js.map +10 -0
- package/dist/cli/chunk-x66c5yjn.js +23 -0
- package/dist/cli/chunk-x66c5yjn.js.map +10 -0
- package/dist/cli/chunk-xv91q4nm.js +5314 -0
- package/dist/cli/chunk-xv91q4nm.js.map +58 -0
- package/dist/cli/chunk-y3g15rvv.js +679 -0
- package/dist/cli/chunk-y3g15rvv.js.map +15 -0
- package/dist/cli/chunk-ye9zdkgv.js +136 -0
- package/dist/cli/chunk-ye9zdkgv.js.map +10 -0
- package/dist/cli/chunk-ynacq3ev.js +1062 -0
- package/dist/cli/chunk-ynacq3ev.js.map +25 -0
- package/dist/cli/chunk-zr3ygrq3.js +54 -0
- package/dist/cli/chunk-zr3ygrq3.js.map +10 -0
- package/dist/cli/index.js +55 -27597
- package/dist/cli/index.js.map +5 -243
- package/dist/types/ai/ask-context.d.ts +26 -0
- package/dist/types/components/layout/nav-utils.d.ts +33 -1
- package/dist/types/core/code-fences.d.ts +11 -0
- package/dist/types/core/package-root.d.ts +1 -1
- package/dist/types/core/schema.d.ts +70 -0
- package/dist/types/theme/fonts.d.ts +22 -22
- package/docs/02-deployment.mdx +22 -1
- package/docs/configuration/ask-ai.mdx +1 -1
- package/docs/configuration/customization.mdx +2 -9
- package/docs/content/navigation.mdx +2 -0
- package/docs/content/syntax.mdx +1 -1
- package/docs/discoverability/open-graph.mdx +4 -0
- package/docs/reference/cli.mdx +1 -1
- package/package.json +4 -2
- package/src/ai/api/handlers.ts +4 -7
- package/src/ai/api/paths.ts +8 -0
- package/src/ai/api/spec.ts +2 -1
- package/src/ai/ask-context.ts +378 -22
- package/src/astro/generate.ts +161 -28
- package/src/astro/include-hmr.ts +10 -13
- package/src/astro/include-refresh.ts +0 -0
- package/src/astro/index.ts +6 -1
- package/src/astro/integration.ts +280 -53
- package/src/astro/module-types.ts +83 -0
- package/src/astro/templates.ts +256 -108
- package/src/audit/image-size.ts +10 -8
- package/src/cli/command-meta.ts +77 -0
- package/src/cli/commands/add.ts +2 -4
- package/src/cli/commands/audit.ts +2 -4
- package/src/cli/commands/build.ts +70 -346
- package/src/cli/commands/check.ts +2 -4
- package/src/cli/commands/dev.ts +31 -42
- package/src/cli/commands/doctor.ts +2 -4
- package/src/cli/commands/eject.ts +3 -41
- package/src/cli/commands/eval.ts +2 -5
- package/src/cli/commands/init.ts +2 -4
- package/src/cli/commands/mcp-stdio.ts +2 -5
- package/src/cli/commands/preview.ts +3 -5
- package/src/cli/commands/sync.ts +2 -4
- package/src/cli/commands/translate.ts +2 -5
- package/src/cli/commands/validate.ts +2 -4
- package/src/cli/commands/version.ts +2 -4
- package/src/cli/eject-scripts.ts +0 -45
- package/src/cli/host-args.ts +16 -0
- package/src/cli/index.ts +84 -35
- package/src/cli/lazy-command.ts +47 -0
- package/src/components/Icon.astro +24 -0
- package/src/components/content/GithubInfo.astro +4 -1
- package/src/components/icon-sprite-middleware.ts +41 -0
- package/src/components/icon-sprite.ts +93 -0
- package/src/components/layout/IconSprite.astro +11 -0
- package/src/components/layout/NavTree.astro +156 -188
- package/src/components/layout/NavTreeCache.astro +45 -0
- package/src/components/layout/NavTreeScript.astro +256 -0
- package/src/components/layout/PageActions.astro +11 -5
- package/src/components/layout/PageLayout.astro +21 -3
- package/src/components/layout/ReferenceLayout.astro +21 -4
- package/src/components/layout/RootLayout.astro +44 -6
- package/src/components/layout/nav-cache.ts +49 -0
- package/src/components/layout/nav-utils.ts +69 -1
- package/src/components/layout/page-locale.ts +29 -0
- package/src/core/api-name.ts +18 -0
- package/src/core/code-fences.ts +48 -0
- package/src/core/content-assets.ts +3 -7
- package/src/core/includes.ts +3 -7
- package/src/core/package-root.ts +1 -1
- package/src/core/schema.ts +19 -0
- package/src/core/sources/normalize.ts +2 -37
- package/src/core/sources/obsidian.ts +3 -2
- package/src/core/svg-dimensions.ts +97 -0
- package/src/core/version-cut.ts +2 -2
- package/src/deploy/artifacts.ts +370 -0
- package/src/deploy/cloudflare-negotiation.ts +97 -32
- package/src/deploy/function-bundle.ts +66 -20
- package/src/deploy/sitemap.ts +6 -0
- package/src/deploy/vercel-negotiation.ts +8 -30
- package/src/markdown/language-icon.ts +64 -20
- package/src/markdown/mermaid.ts +11 -0
- package/src/og/cache.ts +236 -0
- package/src/og/card.ts +18 -16
- package/src/og/index.ts +8 -1
- package/src/openapi/render-mdx.ts +9 -5
- package/src/registry/eject.ts +23 -10
- package/src/theme/entry.ts +41 -7
- 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
|
|
200
|
+
let subject: string;
|
|
198
201
|
if (spec.kind === "asyncapi") {
|
|
199
|
-
|
|
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
|
-
|
|
206
|
+
subject = `${operation.path} ${GRAPHQL_MEMBER_PHRASES[operation.method as GraphqlMember]}`;
|
|
204
207
|
} else {
|
|
205
|
-
|
|
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
|
-
`${
|
|
357
|
+
`${apiPhrase(spec)} reference.`,
|
|
354
358
|
};
|
|
355
359
|
if (reference?.noindex) {
|
|
356
360
|
seo.noindex = true;
|
package/src/registry/eject.ts
CHANGED
|
@@ -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
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
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);
|
package/src/theme/entry.ts
CHANGED
|
@@ -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
|
-
.
|
|
463
|
-
|
|
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;
|
package/src/theme/fonts.ts
CHANGED
|
@@ -63,7 +63,14 @@ export type FontValue = string | RemoteFontConfig | LocalFontConfig;
|
|
|
63
63
|
interface FontDef {
|
|
64
64
|
category: FontCategory;
|
|
65
65
|
family: string;
|
|
66
|
-
|
|
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
|
|
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
|
|
110
|
+
weights: ["400..700"],
|
|
104
111
|
},
|
|
105
112
|
"fira-code": {
|
|
106
113
|
category: "mono",
|
|
107
114
|
family: "Fira Code",
|
|
108
|
-
weights: [400
|
|
115
|
+
weights: ["400..700"],
|
|
109
116
|
},
|
|
110
|
-
geist: { category: "sans", family: "Geist", weights: [400
|
|
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
|
|
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
|
|
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
|
|
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
|
|
142
|
+
weights: ["400..700"],
|
|
136
143
|
},
|
|
137
144
|
"jetbrains-mono": {
|
|
138
145
|
category: "mono",
|
|
139
146
|
family: "JetBrains Mono",
|
|
140
|
-
weights: [400
|
|
147
|
+
weights: ["400..700"],
|
|
141
148
|
},
|
|
142
|
-
lora: { category: "serif", family: "Lora", weights: [400
|
|
149
|
+
lora: { category: "serif", family: "Lora", weights: ["400..700"] },
|
|
143
150
|
manrope: {
|
|
144
151
|
category: "sans",
|
|
145
152
|
family: "Manrope",
|
|
146
|
-
weights: [400
|
|
153
|
+
weights: ["400..700"],
|
|
147
154
|
},
|
|
148
155
|
merriweather: {
|
|
149
156
|
category: "serif",
|
|
150
157
|
family: "Merriweather",
|
|
151
|
-
weights: [400
|
|
158
|
+
weights: ["400..700"],
|
|
152
159
|
},
|
|
153
160
|
"open-sans": {
|
|
154
161
|
category: "sans",
|
|
155
162
|
family: "Open Sans",
|
|
156
|
-
weights: [400
|
|
163
|
+
weights: ["400..700"],
|
|
157
164
|
},
|
|
158
165
|
"playfair-display": {
|
|
159
166
|
category: "serif",
|
|
160
167
|
family: "Playfair Display",
|
|
161
|
-
weights: [400
|
|
168
|
+
weights: ["400..700"],
|
|
162
169
|
},
|
|
163
170
|
"plus-jakarta-sans": {
|
|
164
171
|
category: "sans",
|
|
165
172
|
family: "Plus Jakarta Sans",
|
|
166
|
-
weights: [400
|
|
173
|
+
weights: ["400..700"],
|
|
167
174
|
},
|
|
168
|
-
roboto: { category: "sans", family: "Roboto", weights: [400
|
|
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
|
|
179
|
+
weights: ["400..700"],
|
|
173
180
|
},
|
|
174
181
|
"source-code-pro": {
|
|
175
182
|
category: "mono",
|
|
176
183
|
family: "Source Code Pro",
|
|
177
|
-
weights: [400
|
|
184
|
+
weights: ["400..600"],
|
|
178
185
|
},
|
|
179
186
|
"source-sans-3": {
|
|
180
187
|
category: "sans",
|
|
181
188
|
family: "Source Sans 3",
|
|
182
|
-
weights: [400
|
|
189
|
+
weights: ["400..700"],
|
|
183
190
|
},
|
|
184
191
|
"source-serif-4": {
|
|
185
192
|
category: "serif",
|
|
186
193
|
family: "Source Serif 4",
|
|
187
|
-
weights: [400
|
|
194
|
+
weights: ["400..700"],
|
|
188
195
|
},
|
|
189
196
|
"space-grotesk": {
|
|
190
197
|
category: "sans",
|
|
191
198
|
family: "Space Grotesk",
|
|
192
|
-
weights: [400
|
|
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
|
|
205
|
+
weights: ["400..600"],
|
|
199
206
|
},
|
|
200
207
|
} satisfies Record<string, FontDef>;
|
|
201
208
|
|