@volter/twin-googlefonts 1.0.2 → 1.0.3

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.
@@ -1,6 +1,6 @@
1
1
  // Google supplies catalog records and keys outside the read-only Fonts API.
2
2
  import type { HandlerContext } from '@volter/world-core';
3
- import { FONT, CATALOG, CSS, FILE, KEY, object, assetKey, cssKey, css2Key, css2Query, googleError } from './shared.ts';
3
+ import { FONT, CATALOG, CSS, FILE, KEY, object, assetKey, browserClass, cssKey, css2Key, css2Query, googleError } from './shared.ts';
4
4
 
5
5
  // source: https://developers.google.com/fonts/docs/developer_api
6
6
  export async function appCredentials(ctx: HandlerContext): Promise<Response> {
@@ -83,8 +83,9 @@ export async function publishCatalog(ctx: HandlerContext): Promise<Response> {
83
83
  if (!font || !(font.variants as string[]).includes(variant) ||
84
84
  sheet.subset.split(',').some(s => !(font.subsets as string[]).includes(s)))
85
85
  throw new Error('Stylesheet request must name a published font, variant and subset');
86
+ // a stylesheet is one browser class's representation (shared.ts browserClass): its user agent is that class's sample
86
87
  const key = cssKey(ctx, sheet.family, sheet.subset, sheet.userAgent);
87
- if (representations.has(key)) throw new Error('Duplicate stylesheet request');
88
+ if (representations.has(key)) throw new Error('Duplicate stylesheet request for browser class ' + browserClass(sheet.userAgent));
88
89
  representations.add(key);
89
90
  const urls = [...sheet.css.matchAll(/url\((https?:\/\/[^)]+)\)/g)].map(m => m[1]!);
90
91
  if (urls.length === 0 || urls.some(url => !decoded.has(assetKey(url))))
@@ -95,7 +96,7 @@ export async function publishCatalog(ctx: HandlerContext): Promise<Response> {
95
96
  if (!pairs || typeof sheet.userAgent !== 'string' || typeof sheet.css !== 'string' || !sheet.css.includes('@font-face'))
96
97
  throw new Error('Invalid CSS2 stylesheet representation');
97
98
  const key = css2Key(ctx, pairs, sheet.userAgent);
98
- if (representations.has(key)) throw new Error('Duplicate stylesheet request');
99
+ if (representations.has(key)) throw new Error('Duplicate stylesheet request for browser class ' + browserClass(sheet.userAgent));
99
100
  representations.add(key);
100
101
  const urls = [...sheet.css.matchAll(/url\((https?:\/\/[^)]+)\)/g)].map(m => m[1]!);
101
102
  if (urls.length === 0 || urls.some(url => !decoded.has(assetKey(url))))
@@ -122,13 +123,13 @@ export async function publishCatalog(ctx: HandlerContext): Promise<Response> {
122
123
  const key = cssKey(ctx, sheet.family as string, sheet.subset as string, sheet.userAgent as string);
123
124
  const blob = 'css-' + ctx.crypto.digest('sha256', sheet.css as string);
124
125
  await ctx.blobs.put(blob, new TextEncoder().encode(sheet.css as string));
125
- await ctx.record(CSS, { family: sheet.family, subset: sheet.subset, userAgent: sheet.userAgent, blob }, fingerprint + ':' + key);
126
+ await ctx.record(CSS, { family: sheet.family, subset: sheet.subset, userAgent: sheet.userAgent, browserClass: browserClass(sheet.userAgent as string), blob }, fingerprint + ':' + key);
126
127
  }
127
128
  for (const sheet of sheets2) {
128
129
  const key = css2Key(ctx, css2Query(new URLSearchParams(sheet.query as string))!, sheet.userAgent as string);
129
130
  const blob = 'css-' + ctx.crypto.digest('sha256', sheet.css as string);
130
131
  await ctx.blobs.put(blob, new TextEncoder().encode(sheet.css as string));
131
- await ctx.record(CSS, { query: sheet.query, userAgent: sheet.userAgent, blob }, fingerprint + ':' + key);
132
+ await ctx.record(CSS, { query: sheet.query, userAgent: sheet.userAgent, browserClass: browserClass(sheet.userAgent as string), blob }, fingerprint + ':' + key);
132
133
  }
133
134
  await ctx.record(CATALOG, { families: [...names], fingerprint }, 'published');
134
135
  return Response.json({ families: [...names] }, { status: 201 });
@@ -1,4 +1,4 @@
1
- // GENERATED by scripts/create-pack.ts --index: the handler map, by operationId, from the families' files (each
1
+ // GENERATED by twin-standard create --index: the handler map, by operationId, from the families' files (each
2
2
  // handler named as its operation). Do not edit; add a handler to its family's file and generate again.
3
3
  import type { Handler } from '@volter/world-core';
4
4
  import * as webfonts from './webfonts.ts';
@@ -1,4 +1,4 @@
1
- // GENERATED by scripts/create-pack.ts --index: the handler map, by operationId, from the families' files (each
1
+ // GENERATED by twin-standard create --index: the handler map, by operationId, from the families' files (each
2
2
  // handler named as its operation). Do not edit; add a handler to its family's file and generate again.
3
3
  import type { Handler } from '@volter/world-core';
4
4
  import * as l from './l.ts';
@@ -10,8 +10,14 @@ calls GET /css2?family=Noto+Sans+SC:wght@<weight>&text=<text>, both from a serve
10
10
  without a browser User-Agent, and read the truetype src URL. next/font/google's build (Rallly's and
11
11
  Cal.diy's `next build`) calls GET /css2?family=Inter:wght@100..900&display=swap with a Chrome User-Agent and
12
12
  reads each woff2 src URL of its unicode-range faces.
13
+ Twenty's front end (twentyhq/twenty 323e664, packages/twenty-front/index.html:33,37) links
14
+ GET /css2?family=Inter:wght@400;500;600&display=swap and GET /css2?family=DM+Mono:wght@400;500;600&display=swap
15
+ from the browser, which loads the woff2 faces its text needs.
16
+ A representation is published for a browser class (src/semantics/shared.ts browserClass): Google serves any
17
+ browser, choosing WOFF 2.0 and unicode-range subsets by the browser its User-Agent names, and the classes are
18
+ the agents Google answered the same bytes (vendor/browser-classes.json).
13
19
  The supplied representations retain actual vendor CSS. Requests without a
14
- published representation answer a refusal, never an invented font format.
20
+ representation published for their class answer a refusal, never an invented font format.
15
21
  text/display/effect on /css are outside this client's demand.
16
22
 
17
23
  SHA-256 `openapi.json`: bf7b9a3b70c3a75712fb784e22bfe07c0008dd55e1aa93b31cba8da26a64fb60
@@ -1,5 +1,5 @@
1
1
  import type { HandlerContext } from '@volter/world-core';
2
- import { CATALOG, CSS, cssKey, htmlError } from './shared.ts';
2
+ import { browserClass, CATALOG, CSS, cssKey, htmlError } from './shared.ts';
3
3
 
4
4
  // source: spec:getStylesheet "The representation is selected for the requesting browser."
5
5
  export async function getStylesheet(ctx: HandlerContext): Promise<Response> {
@@ -8,11 +8,13 @@ export async function getStylesheet(ctx: HandlerContext): Promise<Response> {
8
8
  if (!family || [...query.keys()].some(k => !['family','subset'].includes(k)))
9
9
  return htmlError(400, 'Bad font request');
10
10
  const generation = ctx.row(CATALOG, 'published')?.fingerprint;
11
- const key = cssKey(ctx, family, subset, ctx.call.request.headers.get('user-agent') ?? '');
11
+ // the representation published for the browser class the agent belongs to (shared.ts browserClass)
12
+ const userAgent = ctx.call.request.headers.get('user-agent') ?? '';
13
+ const key = cssKey(ctx, family, subset, userAgent);
12
14
  const row = generation === undefined ? undefined : ctx.row(CSS, String(generation) + ':' + key);
13
15
  // Where the documentation stops: no supplied representation is a named
14
16
  // refusal, not an invented conversion or another browser's font format.
15
- if (!row) return htmlError(400, 'Font family or browser representation is not published');
17
+ if (!row) return htmlError(400, 'Font family or browser representation is not published (' + browserClass(userAgent) + ')');
16
18
  const body = await ctx.blobs.get(String(row.blob));
17
19
  if (!body) return htmlError(404, 'Font stylesheet not found');
18
20
  return new Response(Uint8Array.from(body).buffer, { headers: { 'content-type': 'text/css; charset=utf-8', 'content-length': String(body.length), 'vary': 'User-Agent' } });
@@ -1,5 +1,5 @@
1
1
  import type { HandlerContext } from '@volter/world-core';
2
- import { CATALOG, CSS, css2Key, css2Query, htmlError } from './shared.ts';
2
+ import { browserClass, CATALOG, CSS, css2Key, css2Query, htmlError } from './shared.ts';
3
3
 
4
4
  // source: spec:getStylesheet2 "To request multiple families, specify the family= param for each family."
5
5
  export async function getStylesheet2(ctx: HandlerContext): Promise<Response> {
@@ -7,13 +7,14 @@ export async function getStylesheet2(ctx: HandlerContext): Promise<Response> {
7
7
  if (!pairs) return htmlError(400, 'Bad font request');
8
8
  const generation = ctx.row(CATALOG, 'published')?.fingerprint;
9
9
  const userAgent = ctx.call.request.headers.get('user-agent') ?? '';
10
- const sheet = (agent: string) => generation === undefined ? undefined : ctx.row(CSS, String(generation) + ':' + css2Key(ctx, pairs, agent));
11
- // Where the evidence stops: Google answered the same truetype stylesheet to no User-Agent, "node" and "undici"
12
- // (vendor/inter.json). A request whose agent is not a browser's ("Mozilla/...") and has no representation of its
13
- // own reads the one published for no agent; a browser without its own representation is refused, never sent
14
- // another browser's format.
15
- const row = sheet(userAgent) ?? (userAgent.startsWith('Mozilla/') ? undefined : sheet(''));
16
- if (!row) return htmlError(400, 'Font family or browser representation is not published');
10
+ // The representation is the one published for the browser class the agent belongs to (shared.ts browserClass): a
11
+ // request with no browser's agent ("node", "undici", none) reads the truetype class, as Google answered the same CSS
12
+ // to all three (vendor/inter.json).
13
+ // source: spec:getStylesheet2 "The representation is selected for the requesting browser."
14
+ const row = generation === undefined ? undefined : ctx.row(CSS, String(generation) + ':' + css2Key(ctx, pairs, userAgent));
15
+ // Where the documentation stops: a class with no published representation is a named refusal, never another
16
+ // class's font format.
17
+ if (!row) return htmlError(400, 'Font family or browser representation is not published (' + browserClass(userAgent) + ')');
17
18
  const body = await ctx.blobs.get(String(row.blob));
18
19
  if (!body) return htmlError(404, 'Font stylesheet not found');
19
20
  return new Response(Uint8Array.from(body).buffer, { headers: { 'content-type': 'text/css; charset=utf-8', 'content-length': String(body.length), 'access-control-allow-origin': '*' } });
@@ -1,4 +1,4 @@
1
- // GENERATED by scripts/create-pack.ts --index: the handler map, by operationId, from the families' files (each
1
+ // GENERATED by twin-standard create --index: the handler map, by operationId, from the families' files (each
2
2
  // handler named as its operation). Do not edit; add a handler to its family's file and generate again.
3
3
  import type { Handler } from '@volter/world-core';
4
4
  import * as css from './css.ts';
@@ -1,4 +1,4 @@
1
- import { FONT, CATALOG, CSS, FILE, KEY, object, assetKey, cssKey, css2Key, css2Query, googleError } from "./shared.js";
1
+ import { FONT, CATALOG, CSS, FILE, KEY, object, assetKey, browserClass, cssKey, css2Key, css2Query, googleError } from "./shared.js";
2
2
  // source: https://developers.google.com/fonts/docs/developer_api
3
3
  export async function appCredentials(ctx) {
4
4
  // An app's key is a standard API key, made on a Google Cloud project's Credentials page and associating each request
@@ -82,9 +82,10 @@ export async function publishCatalog(ctx) {
82
82
  if (!font || !font.variants.includes(variant) ||
83
83
  sheet.subset.split(',').some(s => !font.subsets.includes(s)))
84
84
  throw new Error('Stylesheet request must name a published font, variant and subset');
85
+ // a stylesheet is one browser class's representation (shared.ts browserClass): its user agent is that class's sample
85
86
  const key = cssKey(ctx, sheet.family, sheet.subset, sheet.userAgent);
86
87
  if (representations.has(key))
87
- throw new Error('Duplicate stylesheet request');
88
+ throw new Error('Duplicate stylesheet request for browser class ' + browserClass(sheet.userAgent));
88
89
  representations.add(key);
89
90
  const urls = [...sheet.css.matchAll(/url\((https?:\/\/[^)]+)\)/g)].map(m => m[1]);
90
91
  if (urls.length === 0 || urls.some(url => !decoded.has(assetKey(url))))
@@ -96,7 +97,7 @@ export async function publishCatalog(ctx) {
96
97
  throw new Error('Invalid CSS2 stylesheet representation');
97
98
  const key = css2Key(ctx, pairs, sheet.userAgent);
98
99
  if (representations.has(key))
99
- throw new Error('Duplicate stylesheet request');
100
+ throw new Error('Duplicate stylesheet request for browser class ' + browserClass(sheet.userAgent));
100
101
  representations.add(key);
101
102
  const urls = [...sheet.css.matchAll(/url\((https?:\/\/[^)]+)\)/g)].map(m => m[1]);
102
103
  if (urls.length === 0 || urls.some(url => !decoded.has(assetKey(url))))
@@ -129,13 +130,13 @@ export async function publishCatalog(ctx) {
129
130
  const key = cssKey(ctx, sheet.family, sheet.subset, sheet.userAgent);
130
131
  const blob = 'css-' + ctx.crypto.digest('sha256', sheet.css);
131
132
  await ctx.blobs.put(blob, new TextEncoder().encode(sheet.css));
132
- await ctx.record(CSS, { family: sheet.family, subset: sheet.subset, userAgent: sheet.userAgent, blob }, fingerprint + ':' + key);
133
+ await ctx.record(CSS, { family: sheet.family, subset: sheet.subset, userAgent: sheet.userAgent, browserClass: browserClass(sheet.userAgent), blob }, fingerprint + ':' + key);
133
134
  }
134
135
  for (const sheet of sheets2) {
135
136
  const key = css2Key(ctx, css2Query(new URLSearchParams(sheet.query)), sheet.userAgent);
136
137
  const blob = 'css-' + ctx.crypto.digest('sha256', sheet.css);
137
138
  await ctx.blobs.put(blob, new TextEncoder().encode(sheet.css));
138
- await ctx.record(CSS, { query: sheet.query, userAgent: sheet.userAgent, blob }, fingerprint + ':' + key);
139
+ await ctx.record(CSS, { query: sheet.query, userAgent: sheet.userAgent, browserClass: browserClass(sheet.userAgent), blob }, fingerprint + ':' + key);
139
140
  }
140
141
  await ctx.record(CATALOG, { families: [...names], fingerprint }, 'published');
141
142
  return Response.json({ families: [...names] }, { status: 201 });
@@ -10,8 +10,14 @@ calls GET /css2?family=Noto+Sans+SC:wght@<weight>&text=<text>, both from a serve
10
10
  without a browser User-Agent, and read the truetype src URL. next/font/google's build (Rallly's and
11
11
  Cal.diy's `next build`) calls GET /css2?family=Inter:wght@100..900&display=swap with a Chrome User-Agent and
12
12
  reads each woff2 src URL of its unicode-range faces.
13
+ Twenty's front end (twentyhq/twenty 323e664, packages/twenty-front/index.html:33,37) links
14
+ GET /css2?family=Inter:wght@400;500;600&display=swap and GET /css2?family=DM+Mono:wght@400;500;600&display=swap
15
+ from the browser, which loads the woff2 faces its text needs.
16
+ A representation is published for a browser class (src/semantics/shared.ts browserClass): Google serves any
17
+ browser, choosing WOFF 2.0 and unicode-range subsets by the browser its User-Agent names, and the classes are
18
+ the agents Google answered the same bytes (vendor/browser-classes.json).
13
19
  The supplied representations retain actual vendor CSS. Requests without a
14
- published representation answer a refusal, never an invented font format.
20
+ representation published for their class answer a refusal, never an invented font format.
15
21
  text/display/effect on /css are outside this client's demand.
16
22
 
17
23
  SHA-256 `openapi.json`: bf7b9a3b70c3a75712fb784e22bfe07c0008dd55e1aa93b31cba8da26a64fb60
@@ -1,4 +1,4 @@
1
- import { CATALOG, CSS, cssKey, htmlError } from "./shared.js";
1
+ import { browserClass, CATALOG, CSS, cssKey, htmlError } from "./shared.js";
2
2
  // source: spec:getStylesheet "The representation is selected for the requesting browser."
3
3
  export async function getStylesheet(ctx) {
4
4
  const query = new URL(ctx.call.request.url).searchParams;
@@ -6,12 +6,14 @@ export async function getStylesheet(ctx) {
6
6
  if (!family || [...query.keys()].some(k => !['family', 'subset'].includes(k)))
7
7
  return htmlError(400, 'Bad font request');
8
8
  const generation = ctx.row(CATALOG, 'published')?.fingerprint;
9
- const key = cssKey(ctx, family, subset, ctx.call.request.headers.get('user-agent') ?? '');
9
+ // the representation published for the browser class the agent belongs to (shared.ts browserClass)
10
+ const userAgent = ctx.call.request.headers.get('user-agent') ?? '';
11
+ const key = cssKey(ctx, family, subset, userAgent);
10
12
  const row = generation === undefined ? undefined : ctx.row(CSS, String(generation) + ':' + key);
11
13
  // Where the documentation stops: no supplied representation is a named
12
14
  // refusal, not an invented conversion or another browser's font format.
13
15
  if (!row)
14
- return htmlError(400, 'Font family or browser representation is not published');
16
+ return htmlError(400, 'Font family or browser representation is not published (' + browserClass(userAgent) + ')');
15
17
  const body = await ctx.blobs.get(String(row.blob));
16
18
  if (!body)
17
19
  return htmlError(404, 'Font stylesheet not found');
@@ -1,4 +1,4 @@
1
- import { CATALOG, CSS, css2Key, css2Query, htmlError } from "./shared.js";
1
+ import { browserClass, CATALOG, CSS, css2Key, css2Query, htmlError } from "./shared.js";
2
2
  // source: spec:getStylesheet2 "To request multiple families, specify the family= param for each family."
3
3
  export async function getStylesheet2(ctx) {
4
4
  const pairs = css2Query(new URL(ctx.call.request.url).searchParams);
@@ -6,14 +6,15 @@ export async function getStylesheet2(ctx) {
6
6
  return htmlError(400, 'Bad font request');
7
7
  const generation = ctx.row(CATALOG, 'published')?.fingerprint;
8
8
  const userAgent = ctx.call.request.headers.get('user-agent') ?? '';
9
- const sheet = (agent) => generation === undefined ? undefined : ctx.row(CSS, String(generation) + ':' + css2Key(ctx, pairs, agent));
10
- // Where the evidence stops: Google answered the same truetype stylesheet to no User-Agent, "node" and "undici"
11
- // (vendor/inter.json). A request whose agent is not a browser's ("Mozilla/...") and has no representation of its
12
- // own reads the one published for no agent; a browser without its own representation is refused, never sent
13
- // another browser's format.
14
- const row = sheet(userAgent) ?? (userAgent.startsWith('Mozilla/') ? undefined : sheet(''));
9
+ // The representation is the one published for the browser class the agent belongs to (shared.ts browserClass): a
10
+ // request with no browser's agent ("node", "undici", none) reads the truetype class, as Google answered the same CSS
11
+ // to all three (vendor/inter.json).
12
+ // source: spec:getStylesheet2 "The representation is selected for the requesting browser."
13
+ const row = generation === undefined ? undefined : ctx.row(CSS, String(generation) + ':' + css2Key(ctx, pairs, userAgent));
14
+ // Where the documentation stops: a class with no published representation is a named refusal, never another
15
+ // class's font format.
15
16
  if (!row)
16
- return htmlError(400, 'Font family or browser representation is not published');
17
+ return htmlError(400, 'Font family or browser representation is not published (' + browserClass(userAgent) + ')');
17
18
  const body = await ctx.blobs.get(String(row.blob));
18
19
  if (!body)
19
20
  return htmlError(404, 'Font stylesheet not found');
@@ -13,14 +13,14 @@
13
13
  "lane": "css",
14
14
  "mechanism": "handler",
15
15
  "demand": "All five pinned config.ts UAs",
16
- "why": "Use exact published CSS per request/UA, with the real font-family/style/weight/src consumed by fetchCSS; first-use downloads every returned src. Unsupported representations answer a refusal."
16
+ "why": "Use the exact published CSS per request and browser class (src/semantics/shared.ts browserClass; each of the five pinned config.ts UAs is one class's sample), with the real font-family/style/weight/src consumed by fetchCSS; first-use downloads every returned src. A class with no published representation answers a refusal."
17
17
  },
18
18
  {
19
19
  "operation": "getStylesheet2",
20
20
  "lane": "css",
21
21
  "mechanism": "handler",
22
- "demand": "Dub's Inter weights and Rallly's CJK text subsets, both from a server; Rallly's and Cal.diy's next/font/google build of Inter's variable weights, with next/font's browser User-Agent",
23
- "why": "Use the exact published CSS per ordered CSS2 query and User-Agent; a non-browser agent without its own representation reads the one published for no agent, as Google answered the same CSS to none, node and undici. Unpublished families, text subsets and browser representations answer a refusal; text= and display= given twice, or another parameter, are a bad request."
22
+ "demand": "Dub's Inter weights and Rallly's CJK text subsets, both from a server; Rallly's and Cal.diy's next/font/google build of Inter's variable weights, with next/font's browser User-Agent; Twenty's front end's Inter and DM Mono stylesheets, from a Chromium browser",
23
+ "why": "Use the exact published CSS per ordered CSS2 query and browser class (src/semantics/shared.ts browserClass, the classes of Google's answers in vendor/browser-classes.json): Google serves any browser, choosing WOFF 2.0 and unicode-range by the browser, and a non-browser agent is the truetype class, as Google answered the same CSS to none, node and undici. A class without a published representation, and unpublished families and text subsets, answer a refusal; text= and display= given twice, or another parameter, are a bad request."
24
24
  },
25
25
  {
26
26
  "operation": "getFontFile",
@@ -95,6 +95,28 @@
95
95
  "evidence": "the same build"
96
96
  }
97
97
  ]
98
+ },
99
+ {
100
+ "name": "twentyhq/twenty",
101
+ "commit": "323e66433ee5b0878f43bc6c54abe4b1ac9be64b",
102
+ "client": "the front end in a browser (Playwright 1.63's Chromium 153 headless shell in the bench task twenty-20877), its own User-Agent",
103
+ "backend": [
104
+ {
105
+ "call": "GET fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap",
106
+ "operation": "getStylesheet2",
107
+ "evidence": "packages/twenty-front/index.html:33 (a stylesheet link, until 3aeb2b0d self-hosts the fonts)"
108
+ },
109
+ {
110
+ "call": "GET fonts.googleapis.com/css2?family=DM+Mono:wght@400;500;600&display=swap",
111
+ "operation": "getStylesheet2",
112
+ "evidence": "packages/twenty-front/index.html:37"
113
+ },
114
+ {
115
+ "call": "GET fonts.gstatic.com/s/{inter,dmmono}/... woff2, the faces the page's text needs",
116
+ "operation": "getFontFile",
117
+ "evidence": "the browser loads each unicode-range face its text uses"
118
+ }
119
+ ]
98
120
  }
99
121
  ],
100
122
  "notDemanded": "OAuth, font submission/publishing UI, effects and advanced catalog capabilities are outside these client paths."
@@ -11,7 +11,7 @@ export const manifest = {
11
11
  protocol: '3', transport: 'rest', archetype: 'crud', bin: 'world-googlefonts',
12
12
  resources: ['webfont', '_api_key', '_font_catalog', '_stylesheet', '_font_file'],
13
13
  specSource: 'api/spec/SOURCE.md: unchanged Google Discovery; css/spec/SOURCE.md and assets/spec/SOURCE.md: Google documentation and retained font responses',
14
- description: 'Google Fonts catalog, exact published CSS representations and genuine font bytes; a World-issued query API key. Seed data is the attributed Antic reference catalog and the CSS2 weights 500-700 of Inter, not the complete live Google catalog.',
14
+ description: 'Google Fonts catalog, exact published CSS representations and genuine font bytes; a World-issued query API key. Seed data is the attributed Antic reference catalog, the CSS2 weights 500-700 of Inter, the variable weights of Inter and the Inter and DM Mono stylesheets Twenty links, not the complete live Google catalog.',
15
15
  // next/font/google fetches the font's stylesheet and files from Google at an app's build (twin-world architecture,
16
16
  // Selection: a module that reaches the vendor by itself is evidence, as an SDK is)
17
17
  adoption: { sdks: [], envStems: ['GOOGLE_FONTS'], modules: ['next/font/google'] },