@grimoire-rs/indexer 0.3.3 → 0.4.1
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/README.md +220 -9
- package/dist/ci.d.ts +6 -1
- package/dist/ci.d.ts.map +1 -1
- package/dist/ci.js +32 -1
- package/dist/ci.js.map +1 -1
- package/dist/cli/build.d.ts.map +1 -1
- package/dist/cli/build.js +3 -1
- package/dist/cli/build.js.map +1 -1
- package/dist/cli/ci.d.ts.map +1 -1
- package/dist/cli/ci.js +5 -1
- package/dist/cli/ci.js.map +1 -1
- package/dist/cli/enrich.d.ts +1 -0
- package/dist/cli/enrich.d.ts.map +1 -1
- package/dist/cli/enrich.js +38 -0
- package/dist/cli/enrich.js.map +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +17 -3
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +9 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/ratings.d.ts +3 -0
- package/dist/cli/ratings.d.ts.map +1 -0
- package/dist/cli/ratings.js +160 -0
- package/dist/cli/ratings.js.map +1 -0
- package/dist/config.d.ts +19 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +47 -1
- package/dist/config.js.map +1 -1
- package/dist/data/index.d.ts.map +1 -1
- package/dist/data/index.js +13 -0
- package/dist/data/index.js.map +1 -1
- package/dist/enrich/checkpoint.d.ts +53 -0
- package/dist/enrich/checkpoint.d.ts.map +1 -0
- package/dist/enrich/checkpoint.js +296 -0
- package/dist/enrich/checkpoint.js.map +1 -0
- package/dist/enrich/index.d.ts +14 -0
- package/dist/enrich/index.d.ts.map +1 -1
- package/dist/enrich/index.js +77 -4
- package/dist/enrich/index.js.map +1 -1
- package/dist/ratings/budget.d.ts +16 -0
- package/dist/ratings/budget.d.ts.map +1 -0
- package/dist/ratings/budget.js +7 -0
- package/dist/ratings/budget.js.map +1 -0
- package/dist/ratings/config.d.ts +56 -0
- package/dist/ratings/config.d.ts.map +1 -0
- package/dist/ratings/config.js +86 -0
- package/dist/ratings/config.js.map +1 -0
- package/dist/ratings/marker.d.ts +105 -0
- package/dist/ratings/marker.d.ts.map +1 -0
- package/dist/ratings/marker.js +141 -0
- package/dist/ratings/marker.js.map +1 -0
- package/dist/ratings/paging.d.ts +16 -0
- package/dist/ratings/paging.d.ts.map +1 -0
- package/dist/ratings/paging.js +36 -0
- package/dist/ratings/paging.js.map +1 -0
- package/dist/ratings/provider.d.ts +100 -0
- package/dist/ratings/provider.d.ts.map +1 -0
- package/dist/ratings/provider.js +203 -0
- package/dist/ratings/provider.js.map +1 -0
- package/dist/ratings/provider_github.d.ts +3 -0
- package/dist/ratings/provider_github.d.ts.map +1 -0
- package/dist/ratings/provider_github.js +135 -0
- package/dist/ratings/provider_github.js.map +1 -0
- package/dist/ratings/provider_gitlab.d.ts +3 -0
- package/dist/ratings/provider_gitlab.d.ts.map +1 -0
- package/dist/ratings/provider_gitlab.js +153 -0
- package/dist/ratings/provider_gitlab.js.map +1 -0
- package/dist/ratings/provider_memory.d.ts +28 -0
- package/dist/ratings/provider_memory.d.ts.map +1 -0
- package/dist/ratings/provider_memory.js +49 -0
- package/dist/ratings/provider_memory.js.map +1 -0
- package/dist/ratings/reconcile.d.ts +47 -0
- package/dist/ratings/reconcile.d.ts.map +1 -0
- package/dist/ratings/reconcile.js +133 -0
- package/dist/ratings/reconcile.js.map +1 -0
- package/dist/ratings/seed.d.ts +60 -0
- package/dist/ratings/seed.d.ts.map +1 -0
- package/dist/ratings/seed.js +132 -0
- package/dist/ratings/seed.js.map +1 -0
- package/dist/renderer/astro/components/Catalog.d.ts +2 -0
- package/dist/renderer/astro/components/Catalog.js +65 -16
- package/dist/renderer/astro/components/Catalog.tsx +119 -26
- package/dist/renderer/astro/components/CommandField.astro +1 -0
- package/dist/renderer/astro/components/VersionMenu.astro +31 -23
- package/dist/renderer/astro/layouts/Base.astro +218 -263
- package/dist/renderer/astro/lib/catalog.d.ts +25 -0
- package/dist/renderer/astro/lib/catalog.js +46 -0
- package/dist/renderer/astro/lib/catalog.ts +49 -0
- package/dist/renderer/astro/pages/p/[...slug].astro +238 -85
- package/dist/renderer/astro/styles/tokens.css +157 -0
- package/dist/renderer/index.d.ts.map +1 -1
- package/dist/renderer/index.js +101 -2
- package/dist/renderer/index.js.map +1 -1
- package/dist/renderer/types.d.ts +41 -0
- package/dist/renderer/types.d.ts.map +1 -1
- package/dist/validate/adapters/http.d.ts +29 -1
- package/dist/validate/adapters/http.d.ts.map +1 -1
- package/dist/validate/adapters/http.js +17 -2
- package/dist/validate/adapters/http.js.map +1 -1
- package/package.json +1 -1
- package/templates/ci/github-enrich.yml +9 -1
- package/templates/ci/github-pages.yml +11 -5
- package/templates/ci/github-ratings-seed.yml +88 -0
- package/templates/ci/github-ratings.yml +51 -0
- package/templates/ci/gitlab-ci.yml +3 -3
- package/templates/ci/gitlab-enrich.sh +10 -1
- package/templates/ci/gitlab-ratings-seed.sh +83 -0
- package/templates/ci/gitlab-ratings.yml +37 -0
- package/templates/gitignore +8 -0
|
@@ -2,7 +2,22 @@
|
|
|
2
2
|
// Frozen public URL: /p/<namespace>/<name>/. grim resolves against it, the
|
|
3
3
|
// VS Code deep link points at it, and search engines index it — the route
|
|
4
4
|
// shape is a contract, not an implementation detail.
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
BookOpen,
|
|
7
|
+
Bug,
|
|
8
|
+
ChevronRight,
|
|
9
|
+
FolderRoot,
|
|
10
|
+
Globe,
|
|
11
|
+
History,
|
|
12
|
+
House,
|
|
13
|
+
Image,
|
|
14
|
+
ImageOff,
|
|
15
|
+
Mail,
|
|
16
|
+
MessageCircle,
|
|
17
|
+
Scale,
|
|
18
|
+
ShieldAlert,
|
|
19
|
+
User,
|
|
20
|
+
} from "lucide-preact";
|
|
6
21
|
import Base from "../../layouts/Base.astro";
|
|
7
22
|
import VersionMenu from "../../components/VersionMenu.astro";
|
|
8
23
|
import CommandField from "../../components/CommandField.astro";
|
|
@@ -19,7 +34,10 @@ import { withBase } from "../../lib/base";
|
|
|
19
34
|
import { SHIKI_THEMES } from "../../lib/code";
|
|
20
35
|
import {
|
|
21
36
|
compareVersions,
|
|
37
|
+
externalUrl,
|
|
38
|
+
lastUpdated,
|
|
22
39
|
resolveMemberRef,
|
|
40
|
+
timeAgo,
|
|
23
41
|
versionCascade,
|
|
24
42
|
vscodeUrl,
|
|
25
43
|
type CatalogPackage,
|
|
@@ -110,11 +128,45 @@ const scopeChoices = [
|
|
|
110
128
|
{ name: "Global", command: `grim add --global ${pkg.ref}`, Icon: Globe },
|
|
111
129
|
{ name: "Project", command: addCommand, Icon: FolderRoot },
|
|
112
130
|
];
|
|
131
|
+
|
|
132
|
+
// Every outbound string on this page was handed to the index by a registry
|
|
133
|
+
// it does not control, so each one goes through the scheme allowlist before
|
|
134
|
+
// it becomes an href — the repository link included, which predates the rest
|
|
135
|
+
// of them and took the same string unchecked.
|
|
136
|
+
const repository = externalUrl(pkg.repository);
|
|
137
|
+
const homepage = externalUrl(pkg.url);
|
|
138
|
+
const documentation = externalUrl(pkg.documentation);
|
|
139
|
+
|
|
140
|
+
// Who publishes this, as one line under the summary. `vendor` is derived
|
|
141
|
+
// from the repository namespace when the publisher set none, so it is often
|
|
142
|
+
// the same string as `authors` — a set, not a join, keeps it from being
|
|
143
|
+
// printed twice.
|
|
144
|
+
const byline = [...new Set([pkg.authors, pkg.vendor].filter(Boolean))].join(" · ");
|
|
145
|
+
|
|
146
|
+
// "Get help" belongs to the *repository*, not this version: it is read off
|
|
147
|
+
// the description companion, so a maintainer moves a link without any
|
|
148
|
+
// artifact digest moving. Built here and rendered only when a channel is
|
|
149
|
+
// actually set — most repositories publish none, and a block of four dead
|
|
150
|
+
// rows is worse than no block.
|
|
151
|
+
const supportChannels = [
|
|
152
|
+
{ label: "Issue tracker", href: externalUrl(pkg.support?.issues), Icon: Bug },
|
|
153
|
+
{ label: "Chat", href: externalUrl(pkg.support?.chat), Icon: MessageCircle },
|
|
154
|
+
{ label: "Contact", href: externalUrl(pkg.support?.contact), Icon: Mail },
|
|
155
|
+
{ label: "Report a vulnerability", href: externalUrl(pkg.support?.security), Icon: ShieldAlert },
|
|
156
|
+
].filter((channel): channel is { label: string; href: string; Icon: typeof Bug } =>
|
|
157
|
+
channel.href !== null,
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
// A commit SHA is not something to read, it is something to check against a
|
|
161
|
+
// checkout. It rides as the tooltip on the date it explains rather than
|
|
162
|
+
// taking a row of its own and putting 40 hex characters in the rail.
|
|
163
|
+
const updated = lastUpdated(pkg);
|
|
164
|
+
const updatedTitle = pkg.revision ? `${updated} · revision ${pkg.revision}` : updated;
|
|
113
165
|
---
|
|
114
166
|
|
|
115
167
|
<Base title={`${title} — ${config.brand}`} description={description} image={pkg.logo}>
|
|
116
168
|
<div class="detail">
|
|
117
|
-
<header class="detail-head">
|
|
169
|
+
<header class="detail-head" data-slot="detail-header">
|
|
118
170
|
{
|
|
119
171
|
pkg.logo ? (
|
|
120
172
|
// The placeholder ships in the markup and the image fades in over
|
|
@@ -130,7 +182,7 @@ const scopeChoices = [
|
|
|
130
182
|
<img src={withBase(pkg.logo)} alt="" />
|
|
131
183
|
</span>
|
|
132
184
|
) : (
|
|
133
|
-
<div class="tile letter" style={`background: var(--kind-${pkg.kind}, var(--muted))`}>
|
|
185
|
+
<div class="tile letter" style={`background: var(--grim-color-kind-${pkg.kind}, var(--grim-color-muted))`}>
|
|
134
186
|
{pkg.name[0]?.toUpperCase()}
|
|
135
187
|
</div>
|
|
136
188
|
)
|
|
@@ -138,14 +190,19 @@ const scopeChoices = [
|
|
|
138
190
|
<div class="detail-head-text">
|
|
139
191
|
<h1>
|
|
140
192
|
{pkg.name} <span class={`badge kind-${pkg.kind}`}>{pkg.kind}</span>
|
|
193
|
+
{/* Skills only — every other kind reports null, and grim's own
|
|
194
|
+
surfaces show it beside the kind for the same reason: it
|
|
195
|
+
qualifies what the thing is, not what it says about itself. */}
|
|
196
|
+
{pkg.compatibility && <span class="badge compat">{pkg.compatibility}</span>}
|
|
141
197
|
</h1>
|
|
142
198
|
{description && <p class="summary">{description}</p>}
|
|
199
|
+
{byline && <p class="byline">by {byline}</p>}
|
|
143
200
|
</div>
|
|
144
201
|
</header>
|
|
145
202
|
|
|
146
203
|
{
|
|
147
204
|
pkg.deprecated && (
|
|
148
|
-
<p class="deprecated-banner">
|
|
205
|
+
<p class="deprecated-banner" data-slot="deprecated-banner">
|
|
149
206
|
⚠️ deprecated{pkg.replacedBy ? ` — replaced by ${pkg.replacedBy}` : ""}
|
|
150
207
|
</p>
|
|
151
208
|
)
|
|
@@ -172,7 +229,7 @@ const scopeChoices = [
|
|
|
172
229
|
}
|
|
173
230
|
</div>
|
|
174
231
|
|
|
175
|
-
<div class="detail-body">
|
|
232
|
+
<div class="detail-body" data-slot="detail-body">
|
|
176
233
|
<main class="detail-main">
|
|
177
234
|
{/* Radio tabs, not a scripted tablist: the ribbon works on a page
|
|
178
235
|
whose JS never ran, and a radio group already has the keyboard
|
|
@@ -267,7 +324,7 @@ const scopeChoices = [
|
|
|
267
324
|
{openTab === null && <p class="panel-empty">No content available.</p>}
|
|
268
325
|
</main>
|
|
269
326
|
|
|
270
|
-
<aside class="detail-rail">
|
|
327
|
+
<aside class="detail-rail" data-slot="detail-rail">
|
|
271
328
|
{tags.length > 0 && (
|
|
272
329
|
<section>
|
|
273
330
|
<h2>Versions</h2>
|
|
@@ -304,19 +361,45 @@ const scopeChoices = [
|
|
|
304
361
|
<dd>{pkg.license}</dd>
|
|
305
362
|
</>
|
|
306
363
|
)}
|
|
307
|
-
{
|
|
364
|
+
{repository && (
|
|
308
365
|
<>
|
|
309
366
|
<dt>
|
|
310
367
|
<BrandMark path={repoMark} size={15} />
|
|
311
368
|
Repository
|
|
312
369
|
</dt>
|
|
313
370
|
<dd>
|
|
314
|
-
<a href={
|
|
371
|
+
<a href={repository} target="_blank" rel="noopener noreferrer">
|
|
315
372
|
source
|
|
316
373
|
</a>
|
|
317
374
|
</dd>
|
|
318
375
|
</>
|
|
319
376
|
)}
|
|
377
|
+
{homepage && (
|
|
378
|
+
<>
|
|
379
|
+
<dt>
|
|
380
|
+
<House size={15} aria-hidden="true" />
|
|
381
|
+
Homepage
|
|
382
|
+
</dt>
|
|
383
|
+
<dd>
|
|
384
|
+
<a href={homepage} target="_blank" rel="noopener noreferrer">
|
|
385
|
+
website
|
|
386
|
+
</a>
|
|
387
|
+
</dd>
|
|
388
|
+
</>
|
|
389
|
+
)}
|
|
390
|
+
{documentation && (
|
|
391
|
+
<>
|
|
392
|
+
<dt>
|
|
393
|
+
<BookOpen size={15} aria-hidden="true" />
|
|
394
|
+
Docs
|
|
395
|
+
</dt>
|
|
396
|
+
<dd>
|
|
397
|
+
<a href={documentation} target="_blank" rel="noopener noreferrer">
|
|
398
|
+
documentation
|
|
399
|
+
</a>
|
|
400
|
+
</dd>
|
|
401
|
+
</>
|
|
402
|
+
)}
|
|
320
403
|
{pkg.owner?.github && (
|
|
321
404
|
<>
|
|
322
405
|
<dt>
|
|
@@ -334,6 +417,19 @@ const scopeChoices = [
|
|
|
334
417
|
</dd>
|
|
335
418
|
</>
|
|
336
419
|
)}
|
|
420
|
+
{updated && (
|
|
421
|
+
<>
|
|
422
|
+
<dt>
|
|
423
|
+
<History size={15} aria-hidden="true" />
|
|
424
|
+
Updated
|
|
425
|
+
</dt>
|
|
426
|
+
<dd>
|
|
427
|
+
<time datetime={updated} title={updatedTitle}>
|
|
428
|
+
{timeAgo(updated) || updated}
|
|
429
|
+
</time>
|
|
430
|
+
</dd>
|
|
431
|
+
</>
|
|
432
|
+
)}
|
|
337
433
|
</dl>
|
|
338
434
|
{pkg.keywords && pkg.keywords.length > 0 && (
|
|
339
435
|
<ul class="keywords">
|
|
@@ -352,6 +448,22 @@ const scopeChoices = [
|
|
|
352
448
|
</ul>
|
|
353
449
|
)}
|
|
354
450
|
</section>
|
|
451
|
+
|
|
452
|
+
{supportChannels.length > 0 && (
|
|
453
|
+
<section class="support">
|
|
454
|
+
<h2>Get help</h2>
|
|
455
|
+
<ul>
|
|
456
|
+
{supportChannels.map(({ label, href, Icon }) => (
|
|
457
|
+
<li>
|
|
458
|
+
<Icon size={15} aria-hidden="true" />
|
|
459
|
+
<a href={href} target="_blank" rel="noopener noreferrer">
|
|
460
|
+
{label}
|
|
461
|
+
</a>
|
|
462
|
+
</li>
|
|
463
|
+
))}
|
|
464
|
+
</ul>
|
|
465
|
+
</section>
|
|
466
|
+
)}
|
|
355
467
|
</aside>
|
|
356
468
|
</div>
|
|
357
469
|
</div>
|
|
@@ -397,33 +509,39 @@ const scopeChoices = [
|
|
|
397
509
|
</script>
|
|
398
510
|
|
|
399
511
|
<style>
|
|
512
|
+
@layer grimoire {
|
|
513
|
+
/* Layered so a user CSS file (unlayered) outranks these rules. Astro
|
|
514
|
+
scopes a component style to `.foo[data-astro-cid-…]` — specificity
|
|
515
|
+
(0,2,0) — which beats a consumer's `.foo` in EITHER source order, so
|
|
516
|
+
source order alone does not make this overridable. Not reindented:
|
|
517
|
+
the wrapper stays a two-line diff. */
|
|
400
518
|
.detail {
|
|
401
519
|
display: flex;
|
|
402
520
|
flex-direction: column;
|
|
403
|
-
gap:
|
|
521
|
+
gap: var(--grim-space-7);
|
|
404
522
|
}
|
|
405
523
|
.detail-head {
|
|
406
524
|
display: flex;
|
|
407
525
|
align-items: center;
|
|
408
|
-
gap:
|
|
409
|
-
background: var(--card);
|
|
410
|
-
border:
|
|
411
|
-
border-radius:
|
|
412
|
-
padding:
|
|
526
|
+
gap: var(--grim-space-6);
|
|
527
|
+
background: var(--grim-color-card);
|
|
528
|
+
border: var(--grim-border-width) solid var(--grim-color-border);
|
|
529
|
+
border-radius: var(--grim-radius-xl);
|
|
530
|
+
padding: var(--grim-space-6) var(--grim-space-7);
|
|
413
531
|
}
|
|
414
532
|
.tile {
|
|
415
533
|
flex-shrink: 0;
|
|
416
534
|
width: 3.5rem;
|
|
417
535
|
height: 3.5rem;
|
|
418
|
-
border-radius:
|
|
536
|
+
border-radius: var(--grim-radius-xl);
|
|
419
537
|
object-fit: cover;
|
|
420
538
|
}
|
|
421
539
|
.tile.letter {
|
|
422
540
|
display: flex;
|
|
423
541
|
align-items: center;
|
|
424
542
|
justify-content: center;
|
|
425
|
-
color: var(--on-accent);
|
|
426
|
-
font-size:
|
|
543
|
+
color: var(--grim-color-on-accent);
|
|
544
|
+
font-size: var(--grim-text-xl);
|
|
427
545
|
font-weight: 700;
|
|
428
546
|
font-family: ui-monospace, "SFMono-Regular", monospace;
|
|
429
547
|
}
|
|
@@ -431,27 +549,58 @@ const scopeChoices = [
|
|
|
431
549
|
margin: 0;
|
|
432
550
|
display: flex;
|
|
433
551
|
align-items: center;
|
|
434
|
-
gap:
|
|
435
|
-
font-size:
|
|
552
|
+
gap: var(--grim-space-4);
|
|
553
|
+
font-size: var(--grim-text-xl);
|
|
436
554
|
font-family: ui-monospace, "SFMono-Regular", monospace;
|
|
437
555
|
}
|
|
438
556
|
.summary {
|
|
439
|
-
margin:
|
|
440
|
-
color: var(--muted);
|
|
557
|
+
margin: var(--grim-space-2) 0 0;
|
|
558
|
+
color: var(--grim-color-muted);
|
|
559
|
+
}
|
|
560
|
+
.byline {
|
|
561
|
+
margin: var(--grim-space-3) 0 0;
|
|
562
|
+
color: var(--grim-color-muted);
|
|
563
|
+
font-size: var(--grim-text-sm);
|
|
564
|
+
}
|
|
565
|
+
/* The kind badge names a closed set of five and shouts accordingly. A
|
|
566
|
+
compatibility hint is a free string off the registry — upper-casing it
|
|
567
|
+
would misspell whatever the publisher actually wrote. */
|
|
568
|
+
.badge.compat {
|
|
569
|
+
text-transform: none;
|
|
570
|
+
letter-spacing: normal;
|
|
571
|
+
font-family: ui-monospace, "SFMono-Regular", monospace;
|
|
572
|
+
}
|
|
573
|
+
.support ul {
|
|
574
|
+
list-style: none;
|
|
575
|
+
margin: 0;
|
|
576
|
+
padding: 0;
|
|
577
|
+
display: flex;
|
|
578
|
+
flex-direction: column;
|
|
579
|
+
gap: var(--grim-space-4);
|
|
580
|
+
}
|
|
581
|
+
.support li {
|
|
582
|
+
display: flex;
|
|
583
|
+
align-items: center;
|
|
584
|
+
gap: var(--grim-space-3);
|
|
585
|
+
font-size: var(--grim-text-md);
|
|
586
|
+
}
|
|
587
|
+
.support li :global(svg) {
|
|
588
|
+
flex-shrink: 0;
|
|
589
|
+
color: var(--grim-color-muted);
|
|
441
590
|
}
|
|
442
591
|
.deprecated-banner {
|
|
443
592
|
margin: 0;
|
|
444
|
-
background: var(--banner-bg);
|
|
445
|
-
color: var(--banner-fg);
|
|
446
|
-
border:
|
|
447
|
-
border-radius:
|
|
448
|
-
padding:
|
|
593
|
+
background: var(--grim-color-banner-bg);
|
|
594
|
+
color: var(--grim-color-banner-fg);
|
|
595
|
+
border: var(--grim-border-width) solid var(--grim-color-banner-border);
|
|
596
|
+
border-radius: var(--grim-radius-lg);
|
|
597
|
+
padding: var(--grim-space-4) var(--grim-space-6);
|
|
449
598
|
font-weight: 600;
|
|
450
599
|
}
|
|
451
600
|
.detail-body {
|
|
452
601
|
display: grid;
|
|
453
602
|
grid-template-columns: 1fr 18rem;
|
|
454
|
-
gap:
|
|
603
|
+
gap: var(--grim-space-8);
|
|
455
604
|
align-items: start;
|
|
456
605
|
}
|
|
457
606
|
@media (max-width: 55rem) {
|
|
@@ -461,10 +610,10 @@ const scopeChoices = [
|
|
|
461
610
|
}
|
|
462
611
|
.detail-main {
|
|
463
612
|
min-width: 0;
|
|
464
|
-
background: var(--card);
|
|
465
|
-
border:
|
|
466
|
-
border-radius:
|
|
467
|
-
padding:
|
|
613
|
+
background: var(--grim-color-card);
|
|
614
|
+
border: var(--grim-border-width) solid var(--grim-color-border);
|
|
615
|
+
border-radius: var(--grim-radius-xl);
|
|
616
|
+
padding: var(--grim-space-7) var(--grim-space-7);
|
|
468
617
|
}
|
|
469
618
|
/* Markdown opens with its own heading, whose margin lands on top of the
|
|
470
619
|
panel padding and reads as a hole. Every panel sets its own top edge. */
|
|
@@ -481,23 +630,26 @@ const scopeChoices = [
|
|
|
481
630
|
panel's own top edge rather than a line floating in the content. */
|
|
482
631
|
.ribbon {
|
|
483
632
|
display: flex;
|
|
484
|
-
gap:
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
633
|
+
gap: var(--grim-space-7);
|
|
634
|
+
/* The negation of `.detail-main`'s own padding, written as that token so
|
|
635
|
+
the two cannot drift apart into a bleed that no longer reaches the edge. */
|
|
636
|
+
margin: calc(-1 * var(--grim-space-7)) calc(-1 * var(--grim-space-7))
|
|
637
|
+
var(--grim-space-7);
|
|
638
|
+
padding: 0 var(--grim-space-7);
|
|
639
|
+
border-bottom: var(--grim-border-width) solid var(--grim-color-border);
|
|
488
640
|
}
|
|
489
641
|
.ribbon label {
|
|
490
|
-
padding:
|
|
491
|
-
margin-bottom: -
|
|
642
|
+
padding: var(--grim-space-5) 0;
|
|
643
|
+
margin-bottom: calc(-1 * var(--grim-border-width)); /* the active underline sits on the panel rule */
|
|
492
644
|
border-bottom: 2px solid transparent;
|
|
493
|
-
font-size:
|
|
645
|
+
font-size: var(--grim-text-sm);
|
|
494
646
|
text-transform: uppercase;
|
|
495
647
|
letter-spacing: 0.04em;
|
|
496
|
-
color: var(--muted);
|
|
648
|
+
color: var(--grim-color-muted);
|
|
497
649
|
cursor: pointer;
|
|
498
650
|
}
|
|
499
651
|
.ribbon label:hover {
|
|
500
|
-
color: var(--fg);
|
|
652
|
+
color: var(--grim-color-fg);
|
|
501
653
|
}
|
|
502
654
|
/* Nothing behind it. Still shown, so the ribbon is the same shape on every
|
|
503
655
|
package page, but visibly not a thing to click. */
|
|
@@ -510,7 +662,7 @@ const scopeChoices = [
|
|
|
510
662
|
#panel-readme:disabled ~ .ribbon label[for="panel-readme"]:hover,
|
|
511
663
|
#panel-contents:disabled ~ .ribbon label[for="panel-contents"]:hover,
|
|
512
664
|
#panel-changelog:disabled ~ .ribbon label[for="panel-changelog"]:hover {
|
|
513
|
-
color: var(--muted);
|
|
665
|
+
color: var(--grim-color-muted);
|
|
514
666
|
}
|
|
515
667
|
/* Every tab empty: say it once, in the middle. */
|
|
516
668
|
.panel-empty {
|
|
@@ -518,7 +670,7 @@ const scopeChoices = [
|
|
|
518
670
|
place-items: center;
|
|
519
671
|
min-height: 11rem;
|
|
520
672
|
margin: 0;
|
|
521
|
-
color: var(--muted);
|
|
673
|
+
color: var(--grim-color-muted);
|
|
522
674
|
}
|
|
523
675
|
.tab-panel {
|
|
524
676
|
display: none;
|
|
@@ -531,16 +683,16 @@ const scopeChoices = [
|
|
|
531
683
|
#panel-readme:checked ~ .ribbon label[for="panel-readme"],
|
|
532
684
|
#panel-contents:checked ~ .ribbon label[for="panel-contents"],
|
|
533
685
|
#panel-changelog:checked ~ .ribbon label[for="panel-changelog"] {
|
|
534
|
-
color: var(--fg);
|
|
535
|
-
border-bottom-color: var(--accent);
|
|
686
|
+
color: var(--grim-color-fg);
|
|
687
|
+
border-bottom-color: var(--grim-color-accent);
|
|
536
688
|
}
|
|
537
689
|
/* The input carries the focus, the label shows it. */
|
|
538
690
|
#panel-readme:focus-visible ~ .ribbon label[for="panel-readme"],
|
|
539
691
|
#panel-contents:focus-visible ~ .ribbon label[for="panel-contents"],
|
|
540
692
|
#panel-changelog:focus-visible ~ .ribbon label[for="panel-changelog"] {
|
|
541
|
-
outline: 2px solid var(--accent);
|
|
693
|
+
outline: 2px solid var(--grim-color-accent);
|
|
542
694
|
outline-offset: 2px;
|
|
543
|
-
border-radius:
|
|
695
|
+
border-radius: var(--grim-radius-sm);
|
|
544
696
|
}
|
|
545
697
|
|
|
546
698
|
/* A bundle's member list: what it installs, one row each. A grid, not a
|
|
@@ -553,7 +705,7 @@ const scopeChoices = [
|
|
|
553
705
|
padding: 0;
|
|
554
706
|
display: grid;
|
|
555
707
|
grid-template-columns: auto auto 1fr;
|
|
556
|
-
gap:
|
|
708
|
+
gap: var(--grim-space-4) var(--grim-space-5);
|
|
557
709
|
align-items: center;
|
|
558
710
|
}
|
|
559
711
|
.members li {
|
|
@@ -568,8 +720,8 @@ const scopeChoices = [
|
|
|
568
720
|
justify-self: start;
|
|
569
721
|
}
|
|
570
722
|
.members code {
|
|
571
|
-
color: var(--muted);
|
|
572
|
-
font-size:
|
|
723
|
+
color: var(--grim-color-muted);
|
|
724
|
+
font-size: var(--grim-text-sm);
|
|
573
725
|
overflow-wrap: anywhere;
|
|
574
726
|
}
|
|
575
727
|
/* Narrow: three columns of a long ref do not fit, so each member becomes
|
|
@@ -586,32 +738,32 @@ const scopeChoices = [
|
|
|
586
738
|
.detail-rail {
|
|
587
739
|
display: flex;
|
|
588
740
|
flex-direction: column;
|
|
589
|
-
gap:
|
|
741
|
+
gap: var(--grim-space-7);
|
|
590
742
|
}
|
|
591
743
|
.detail-rail section {
|
|
592
|
-
background: var(--card);
|
|
593
|
-
border:
|
|
594
|
-
border-radius:
|
|
595
|
-
padding:
|
|
744
|
+
background: var(--grim-color-card);
|
|
745
|
+
border: var(--grim-border-width) solid var(--grim-color-border);
|
|
746
|
+
border-radius: var(--grim-radius-xl);
|
|
747
|
+
padding: var(--grim-space-6);
|
|
596
748
|
}
|
|
597
749
|
/* Panel label. The main panel's ribbon labels match this by hand — they
|
|
598
750
|
are <label>s, not headings, so they cannot join the selector. */
|
|
599
751
|
.detail-rail h2 {
|
|
600
|
-
margin: 0 0
|
|
601
|
-
font-size:
|
|
752
|
+
margin: 0 0 var(--grim-space-4);
|
|
753
|
+
font-size: var(--grim-text-sm);
|
|
602
754
|
text-transform: uppercase;
|
|
603
755
|
letter-spacing: 0.04em;
|
|
604
|
-
color: var(--muted);
|
|
756
|
+
color: var(--grim-color-muted);
|
|
605
757
|
}
|
|
606
758
|
/* Loose badges, both for the cascade and the older tags — VersionMenu owns
|
|
607
759
|
the pill itself, this only lays them out. */
|
|
608
760
|
.cascade {
|
|
609
761
|
display: flex;
|
|
610
762
|
flex-wrap: wrap;
|
|
611
|
-
gap:
|
|
763
|
+
gap: var(--grim-space-2);
|
|
612
764
|
}
|
|
613
765
|
.older {
|
|
614
|
-
margin-top:
|
|
766
|
+
margin-top: var(--grim-space-5);
|
|
615
767
|
}
|
|
616
768
|
/* The UA marker is a glyph that flips between two characters with no
|
|
617
769
|
in-between; a real chevron can turn. `list-style` kills it everywhere
|
|
@@ -621,22 +773,22 @@ const scopeChoices = [
|
|
|
621
773
|
.older > summary {
|
|
622
774
|
display: flex;
|
|
623
775
|
align-items: center;
|
|
624
|
-
gap:
|
|
776
|
+
gap: var(--grim-space-3);
|
|
625
777
|
list-style: none;
|
|
626
|
-
padding-block:
|
|
778
|
+
padding-block: var(--grim-space-1);
|
|
627
779
|
cursor: pointer;
|
|
628
|
-
font-size:
|
|
629
|
-
color: var(--muted);
|
|
780
|
+
font-size: var(--grim-text-sm);
|
|
781
|
+
color: var(--grim-color-muted);
|
|
630
782
|
}
|
|
631
783
|
.older > summary::-webkit-details-marker {
|
|
632
784
|
display: none;
|
|
633
785
|
}
|
|
634
786
|
.older > summary:hover {
|
|
635
|
-
color: var(--fg);
|
|
787
|
+
color: var(--grim-color-fg);
|
|
636
788
|
}
|
|
637
789
|
.older > summary :global(svg) {
|
|
638
790
|
flex-shrink: 0;
|
|
639
|
-
transition: transform
|
|
791
|
+
transition: transform var(--grim-duration-base) ease;
|
|
640
792
|
}
|
|
641
793
|
.older[open] > summary :global(svg) {
|
|
642
794
|
transform: rotate(90deg);
|
|
@@ -647,7 +799,7 @@ const scopeChoices = [
|
|
|
647
799
|
}
|
|
648
800
|
}
|
|
649
801
|
.older[open] > summary {
|
|
650
|
-
margin-bottom:
|
|
802
|
+
margin-bottom: var(--grim-space-4);
|
|
651
803
|
}
|
|
652
804
|
dl {
|
|
653
805
|
margin: 0;
|
|
@@ -657,14 +809,14 @@ const scopeChoices = [
|
|
|
657
809
|
`stretch` sits each at the top of its own box, so the size difference
|
|
658
810
|
reads as two lines that never quite line up. */
|
|
659
811
|
align-items: center;
|
|
660
|
-
gap:
|
|
812
|
+
gap: var(--grim-space-4) var(--grim-space-5);
|
|
661
813
|
}
|
|
662
814
|
dt {
|
|
663
815
|
display: flex;
|
|
664
816
|
align-items: center;
|
|
665
|
-
gap:
|
|
666
|
-
color: var(--muted);
|
|
667
|
-
font-size:
|
|
817
|
+
gap: var(--grim-space-3);
|
|
818
|
+
color: var(--grim-color-muted);
|
|
819
|
+
font-size: var(--grim-text-sm);
|
|
668
820
|
}
|
|
669
821
|
/* Every icon is the same box, so the label text lands on one x without an
|
|
670
822
|
icon column of its own. */
|
|
@@ -673,15 +825,15 @@ const scopeChoices = [
|
|
|
673
825
|
}
|
|
674
826
|
dd {
|
|
675
827
|
margin: 0;
|
|
676
|
-
font-size:
|
|
828
|
+
font-size: var(--grim-text-md);
|
|
677
829
|
}
|
|
678
830
|
.keywords {
|
|
679
831
|
list-style: none;
|
|
680
|
-
margin:
|
|
832
|
+
margin: var(--grim-space-5) 0 0;
|
|
681
833
|
padding: 0;
|
|
682
834
|
display: flex;
|
|
683
835
|
flex-wrap: wrap;
|
|
684
|
-
gap:
|
|
836
|
+
gap: var(--grim-space-3);
|
|
685
837
|
}
|
|
686
838
|
/* The chip is the link, not a box around it — otherwise the padding is
|
|
687
839
|
dead space the pointer falls through. Bordered and hovering to accent
|
|
@@ -690,27 +842,28 @@ const scopeChoices = [
|
|
|
690
842
|
that answers differently reads as a different kind of thing. */
|
|
691
843
|
.keywords a {
|
|
692
844
|
display: inline-block;
|
|
693
|
-
border:
|
|
694
|
-
border-radius:
|
|
695
|
-
background: var(--chip-bg);
|
|
696
|
-
padding:
|
|
697
|
-
font-size:
|
|
698
|
-
color: var(--muted);
|
|
845
|
+
border: var(--grim-border-width) solid var(--grim-color-border);
|
|
846
|
+
border-radius: var(--grim-radius-pill);
|
|
847
|
+
background: var(--grim-color-chip-bg);
|
|
848
|
+
padding: var(--grim-space-1) var(--grim-space-4);
|
|
849
|
+
font-size: var(--grim-text-xs);
|
|
850
|
+
color: var(--grim-color-muted);
|
|
699
851
|
text-decoration: none;
|
|
700
852
|
transition:
|
|
701
|
-
color
|
|
702
|
-
border-color
|
|
703
|
-
background-color
|
|
853
|
+
color var(--grim-duration-fast) ease,
|
|
854
|
+
border-color var(--grim-duration-fast) ease,
|
|
855
|
+
background-color var(--grim-duration-fast) ease;
|
|
704
856
|
}
|
|
705
857
|
.keywords a:hover,
|
|
706
858
|
.keywords a:focus-visible {
|
|
707
|
-
color: var(--accent);
|
|
708
|
-
border-color: var(--accent);
|
|
709
|
-
background: var(--accent-soft);
|
|
859
|
+
color: var(--grim-color-accent);
|
|
860
|
+
border-color: var(--grim-color-accent);
|
|
861
|
+
background: var(--grim-color-accent-soft);
|
|
710
862
|
}
|
|
711
863
|
@media (prefers-reduced-motion: reduce) {
|
|
712
864
|
.keywords a {
|
|
713
865
|
transition: none;
|
|
714
866
|
}
|
|
715
867
|
}
|
|
868
|
+
}
|
|
716
869
|
</style>
|