@orbytes/astrolab 0.3.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/LICENSE +37 -0
- package/README.md +410 -0
- package/bin/lab-cull.mjs +401 -0
- package/bin/pin-gallery.mjs +121 -0
- package/defaults.mjs +120 -0
- package/dist/core/astro-integration.js +130 -0
- package/dist/core/index.js +6 -0
- package/dist/core/lib-paths.js +29 -0
- package/dist/core/options.js +173 -0
- package/dist/core/utils/get-exports.js +52 -0
- package/dist/core/utils/invariant.js +12 -0
- package/dist/core/utils/kebab-case.js +15 -0
- package/dist/core/utils/path-builder.js +22 -0
- package/dist/core/utils/path.js +53 -0
- package/dist/core/virtual-module/get-story-modules.js +60 -0
- package/dist/core/virtual-module/story-modules.js +8 -0
- package/dist/core/virtual-module/virtual-module-ids.js +22 -0
- package/dist/core/virtual-module/virtual-routes.js +83 -0
- package/dist/core/virtual-module/vite-plugin.js +98 -0
- package/docs/PIN-CONTRACT.md +263 -0
- package/docs/PIN.md +429 -0
- package/index.d.ts +279 -0
- package/index.mjs +347 -0
- package/package.json +93 -0
- package/src/Empty.astro +4 -0
- package/src/Home.astro +298 -0
- package/src/LabHead.astro +1102 -0
- package/src/core/LICENSE-astrobook +166 -0
- package/src/core/astro-integration.ts +166 -0
- package/src/core/client.ts +89 -0
- package/src/core/index.ts +7 -0
- package/src/core/lib/components/empty.astro +1 -0
- package/src/core/lib/components/head.astro +1 -0
- package/src/core/lib/components/home.astro +8 -0
- package/src/core/lib/components/with-decorators.astro +22 -0
- package/src/core/lib/pages/app.astro +19 -0
- package/src/core/lib/pages/preview.astro +17 -0
- package/src/core/lib/pages/story.astro +16 -0
- package/src/core/lib-paths.ts +72 -0
- package/src/core/options.ts +262 -0
- package/src/core/utils/get-exports.ts +59 -0
- package/src/core/utils/invariant.ts +13 -0
- package/src/core/utils/kebab-case.ts +30 -0
- package/src/core/utils/path-builder.ts +45 -0
- package/src/core/utils/path.ts +80 -0
- package/src/core/virtual-module/get-story-modules.ts +110 -0
- package/src/core/virtual-module/story-modules.ts +9 -0
- package/src/core/virtual-module/virtual-module-ids.ts +17 -0
- package/src/core/virtual-module/virtual-routes.ts +130 -0
- package/src/core/virtual-module/vite-plugin.ts +125 -0
- package/src/pin/board.mjs +1521 -0
- package/src/pin/index.mjs +666 -0
- package/src/pin/shot.mjs +427 -0
- package/src/pin/source-stamp.mjs +159 -0
- package/src/pin/tickets.mjs +697 -0
- package/src/pin/toolbar.js +3181 -0
- package/src/shell/Browse.astro +371 -0
- package/src/shell/CardGrid.astro +297 -0
- package/src/shell/Viewport.astro +1330 -0
- package/src/shell/index.json.ts +12 -0
- package/src/shell/lab-index.ts +344 -0
- package/src/shell/lab-params.ts +245 -0
- package/src/shell/live-files.mjs +164 -0
- package/src/shell/marks.mjs +136 -0
- package/src/types/index.ts +6 -0
- package/src/types/types.ts +239 -0
- package/src/types/virtual.d.ts +29 -0
- package/src/ui/components/app.astro +13 -0
- package/src/ui/components/build-path.ts +13 -0
- package/src/ui/components/build-tree.ts +108 -0
- package/src/ui/components/collapse-duration.ts +28 -0
- package/src/ui/components/compress-terms.ts +10 -0
- package/src/ui/components/dashboard-layout.astro +39 -0
- package/src/ui/components/home.astro +65 -0
- package/src/ui/components/layout.astro +110 -0
- package/src/ui/components/preview-layout.astro +109 -0
- package/src/ui/components/sidebar-button-fullscreen.astro +38 -0
- package/src/ui/components/sidebar-button-search.astro +23 -0
- package/src/ui/components/sidebar-button-theme.astro +9 -0
- package/src/ui/components/sidebar-button.astro +24 -0
- package/src/ui/components/sidebar-resize-handle.astro +74 -0
- package/src/ui/components/sidebar-search-panel.astro +41 -0
- package/src/ui/components/sidebar-search-script.ts +103 -0
- package/src/ui/components/sidebar-title.astro +17 -0
- package/src/ui/components/sidebar-tree-node.astro +143 -0
- package/src/ui/components/sidebar-tree.astro +84 -0
- package/src/ui/components/sidebar.astro +29 -0
- package/src/ui/components/theme-message.ts +26 -0
- package/src/ui/components/theme-script.astro +71 -0
- package/src/ui/components/theme-toggle.astro +63 -0
- package/src/ui/components/theme.ts +32 -0
- package/src/ui/index.ts +4 -0
- package/src/ui/lab.css +549 -0
- package/virtual.d.ts +42 -0
package/package.json
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@orbytes/astrolab",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "The orbytes component lab and pin board — an Astrobook shell for Astro sites (live/used-by pills, a viewport configurator, responsive and cull marks, a parameters panel) plus a dev-only click-to-ticket feedback board at /pin.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"astro",
|
|
8
|
+
"astro-integration",
|
|
9
|
+
"component-lab",
|
|
10
|
+
"dev-toolbar",
|
|
11
|
+
"feedback",
|
|
12
|
+
"orbytes"
|
|
13
|
+
],
|
|
14
|
+
"author": "William Teig <william@orbytes.io>",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=22.12.0"
|
|
18
|
+
},
|
|
19
|
+
"workspaces": [
|
|
20
|
+
"testbeds/*"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build:core": "node scripts/build-core.mjs",
|
|
24
|
+
"prepare": "npm run build:core",
|
|
25
|
+
"prepack": "npm run build:core",
|
|
26
|
+
"dev": "npm --workspace testbed-orbytes-v2 run dev",
|
|
27
|
+
"build": "npm --workspace testbed-orbytes-v2 run build",
|
|
28
|
+
"preview": "npm --workspace testbed-orbytes-v2 run preview",
|
|
29
|
+
"build:staging": "npm --workspace testbed-orbytes-v2 run build:staging",
|
|
30
|
+
"check:isolation": "npm --workspace testbed-orbytes-v2 run check:isolation",
|
|
31
|
+
"verify": "npm --workspace testbed-orbytes-v2 run verify"
|
|
32
|
+
},
|
|
33
|
+
"bin": {
|
|
34
|
+
"orbytes-lab-cull": "bin/lab-cull.mjs",
|
|
35
|
+
"orbytes-pin-gallery": "bin/pin-gallery.mjs"
|
|
36
|
+
},
|
|
37
|
+
"main": "./index.mjs",
|
|
38
|
+
"types": "./index.d.ts",
|
|
39
|
+
"exports": {
|
|
40
|
+
".": {
|
|
41
|
+
"types": "./index.d.ts",
|
|
42
|
+
"default": "./index.mjs"
|
|
43
|
+
},
|
|
44
|
+
"./params": "./src/shell/lab-params.ts",
|
|
45
|
+
"./head": "./src/LabHead.astro",
|
|
46
|
+
"./home": "./src/Home.astro",
|
|
47
|
+
"./defaults": "./defaults.mjs",
|
|
48
|
+
"./pin": "./src/pin/index.mjs",
|
|
49
|
+
"./pin/board": "./src/pin/board.mjs",
|
|
50
|
+
"./pin/tickets": "./src/pin/tickets.mjs",
|
|
51
|
+
"./pin/source-stamp": "./src/pin/source-stamp.mjs",
|
|
52
|
+
"./pin/shot": "./src/pin/shot.mjs",
|
|
53
|
+
"./pin/toolbar": "./src/pin/toolbar.js",
|
|
54
|
+
"./shell/*": "./src/shell/*",
|
|
55
|
+
"./core": "./src/core/index.ts",
|
|
56
|
+
"./core/client": "./src/core/client.ts",
|
|
57
|
+
"./core/components/*": "./src/core/lib/components/*",
|
|
58
|
+
"./core/pages/*": "./src/core/lib/pages/*",
|
|
59
|
+
"./ui/*": "./src/ui/*",
|
|
60
|
+
"./package.json": "./package.json"
|
|
61
|
+
},
|
|
62
|
+
"files": [
|
|
63
|
+
"README.md",
|
|
64
|
+
"bin",
|
|
65
|
+
"defaults.mjs",
|
|
66
|
+
"dist",
|
|
67
|
+
"docs",
|
|
68
|
+
"index.d.ts",
|
|
69
|
+
"index.mjs",
|
|
70
|
+
"src",
|
|
71
|
+
"virtual.d.ts"
|
|
72
|
+
],
|
|
73
|
+
"dependencies": {
|
|
74
|
+
"@sveltejs/acorn-typescript": "^1.0.12",
|
|
75
|
+
"acorn": "^8.18.0",
|
|
76
|
+
"fdir": "^6.5.0",
|
|
77
|
+
"slash": "^5.1.0",
|
|
78
|
+
"yoctocolors": "^2.2.0"
|
|
79
|
+
},
|
|
80
|
+
"peerDependencies": {
|
|
81
|
+
"astro": ">=7",
|
|
82
|
+
"playwright": ">=1.50.0"
|
|
83
|
+
},
|
|
84
|
+
"peerDependenciesMeta": {
|
|
85
|
+
"playwright": {
|
|
86
|
+
"optional": true
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"devDependencies": {
|
|
90
|
+
"esbuild": "^0.28.2",
|
|
91
|
+
"playwright": "^1.63.0"
|
|
92
|
+
}
|
|
93
|
+
}
|
package/src/Empty.astro
ADDED
package/src/Home.astro
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
---
|
|
2
|
+
// Lab home — Astrobook's `home` component, given to it by the integration (../index.mjs).
|
|
3
|
+
// Replaces the stock splash with the lab index: a row of tier cards (each opening its folder page
|
|
4
|
+
// at <subpath>/browse/<tier>), then every story as a live thumbnail card grouped by tier, each
|
|
5
|
+
// card carrying its derived pill — live slot, used-by, or nothing.
|
|
6
|
+
//
|
|
7
|
+
// Everything drawn here comes from ./shell/lab-index.ts, which reads Astrobook's own story list
|
|
8
|
+
// (so ids and URLs never drift from what it routes) and derives "live" from what the pages under
|
|
9
|
+
// src/pages/ actually mount. The cards themselves are ./shell/CardGrid.astro, shared with the
|
|
10
|
+
// folder pages.
|
|
11
|
+
import { execSync } from "node:child_process";
|
|
12
|
+
import labConfig from "virtual:orbytes-lab/config.mjs";
|
|
13
|
+
import CardGrid from "./shell/CardGrid.astro";
|
|
14
|
+
import {
|
|
15
|
+
buildLabIndex,
|
|
16
|
+
labBase,
|
|
17
|
+
liveCountOf,
|
|
18
|
+
sortTiers,
|
|
19
|
+
STAGING_URL,
|
|
20
|
+
tierLabel,
|
|
21
|
+
} from "./shell/lab-index";
|
|
22
|
+
|
|
23
|
+
const index = buildLabIndex();
|
|
24
|
+
const tiers = sortTiers([...new Set(index.items.map((item) => item.tier))]).map((tier) => {
|
|
25
|
+
const items = index.items.filter((item) => item.tier === tier);
|
|
26
|
+
return {
|
|
27
|
+
tier,
|
|
28
|
+
label: tierLabel(tier),
|
|
29
|
+
href: tier ? `${labBase}/browse/${tier}` : `${labBase}/browse`,
|
|
30
|
+
count: items.length,
|
|
31
|
+
live: liveCountOf(items),
|
|
32
|
+
items,
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Local branches → per-branch preview builds, when the consumer configured a URL template.
|
|
37
|
+
// `previewUrlTemplate` is a string with a {branch} placeholder rather than a function because the
|
|
38
|
+
// config crosses a virtual module and has to stay JSON-serialisable. No template, no branch list:
|
|
39
|
+
// a host that does not build branches has nothing to link to.
|
|
40
|
+
const previewTemplate = labConfig.previewUrlTemplate;
|
|
41
|
+
let branches: string[] = [];
|
|
42
|
+
if (previewTemplate) {
|
|
43
|
+
try {
|
|
44
|
+
branches = execSync('git branch --format="%(refname:short)"', { encoding: "utf8" })
|
|
45
|
+
.split("\n")
|
|
46
|
+
.map((line) => line.trim())
|
|
47
|
+
.filter(Boolean);
|
|
48
|
+
} catch {
|
|
49
|
+
branches = [];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const previewAlias = (branch: string) =>
|
|
53
|
+
(previewTemplate ?? "").replace(
|
|
54
|
+
/\{branch\}/g,
|
|
55
|
+
branch
|
|
56
|
+
.toLowerCase()
|
|
57
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
58
|
+
.replace(/^-+|-+$/g, ""),
|
|
59
|
+
);
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
<div class="lab-home lab-chrome">
|
|
63
|
+
<header class="lab-home__header">
|
|
64
|
+
<p class="lab-home__eyebrow">// component lab</p>
|
|
65
|
+
<h1 class="lab-home__title">{labConfig.title}</h1>
|
|
66
|
+
<p class="lab-home__intro">
|
|
67
|
+
Every section, component and exploration in the build, rendered live. Cards open the story
|
|
68
|
+
in the dashboard; thumbnails are the bare renders themselves, scaled down. A white pill means
|
|
69
|
+
a page mounts that component right now, and names the page when it is not the home page. On
|
|
70
|
+
section versions a second pill says whether that version has been made responsive; tick it in
|
|
71
|
+
the sidebar. Where a deployed lab is configured, each card also links to the same story
|
|
72
|
+
there — the real minified build, which this dev server is not — and, locally, to the
|
|
73
|
+
component in VS Code.
|
|
74
|
+
</p>
|
|
75
|
+
{
|
|
76
|
+
STAGING_URL && (
|
|
77
|
+
<a class="lab-home__staging" href={STAGING_URL} target="_blank" rel="noopener">
|
|
78
|
+
Staging site
|
|
79
|
+
<span aria-hidden="true"> ↗</span>
|
|
80
|
+
</a>
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
</header>
|
|
84
|
+
|
|
85
|
+
<section class="lab-home__tiers">
|
|
86
|
+
{
|
|
87
|
+
tiers.map((tier) => (
|
|
88
|
+
<a class="tier-card" href={tier.href}>
|
|
89
|
+
<span class="tier-card__eyebrow">// {tier.tier || "root"}</span>
|
|
90
|
+
<span class="tier-card__name">{tier.label}</span>
|
|
91
|
+
<span class="tier-card__meta">
|
|
92
|
+
<span>
|
|
93
|
+
{tier.count} stor{tier.count === 1 ? "y" : "ies"}
|
|
94
|
+
</span>
|
|
95
|
+
{tier.live > 0 && <span class="tier-card__live">{tier.live} live</span>}
|
|
96
|
+
</span>
|
|
97
|
+
</a>
|
|
98
|
+
))
|
|
99
|
+
}
|
|
100
|
+
</section>
|
|
101
|
+
|
|
102
|
+
{
|
|
103
|
+
branches.length > 0 && (
|
|
104
|
+
<section class="lab-home__branches">
|
|
105
|
+
<h2 class="lab-home__group-title">Branches</h2>
|
|
106
|
+
<ul>
|
|
107
|
+
{branches.map((branch) => (
|
|
108
|
+
<li>
|
|
109
|
+
<code>{branch}</code>
|
|
110
|
+
<a href={previewAlias(branch)} target="_blank" rel="noopener">
|
|
111
|
+
branch preview
|
|
112
|
+
</a>
|
|
113
|
+
</li>
|
|
114
|
+
))}
|
|
115
|
+
</ul>
|
|
116
|
+
</section>
|
|
117
|
+
)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
{
|
|
121
|
+
tiers.map((tier) => (
|
|
122
|
+
<section class="lab-home__group">
|
|
123
|
+
<h2 class="lab-home__group-title">
|
|
124
|
+
<a href={tier.href}>{tier.label}</a>
|
|
125
|
+
</h2>
|
|
126
|
+
<CardGrid items={tier.items} />
|
|
127
|
+
</section>
|
|
128
|
+
))
|
|
129
|
+
}
|
|
130
|
+
</div>
|
|
131
|
+
|
|
132
|
+
<style>
|
|
133
|
+
.lab-home {
|
|
134
|
+
background-color: var(--lab-color-bg);
|
|
135
|
+
color: var(--lab-color-text);
|
|
136
|
+
font-family: var(--lab-font-body);
|
|
137
|
+
min-height: 100%;
|
|
138
|
+
padding: 3em 2.5em 5em;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.lab-home__eyebrow {
|
|
142
|
+
font-family: var(--lab-font-mono);
|
|
143
|
+
font-weight: 500;
|
|
144
|
+
color: var(--lab-color-text-muted);
|
|
145
|
+
margin-bottom: 0.75em;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.lab-home__title {
|
|
149
|
+
font-family: var(--lab-font-heading);
|
|
150
|
+
color: var(--lab-color-text-strong);
|
|
151
|
+
font-size: 2.25em;
|
|
152
|
+
font-weight: 500;
|
|
153
|
+
letter-spacing: -0.5px;
|
|
154
|
+
margin-bottom: 0.4em;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.lab-home__intro {
|
|
158
|
+
max-width: 42em;
|
|
159
|
+
color: var(--lab-color-text-faint);
|
|
160
|
+
line-height: 1.55;
|
|
161
|
+
margin-bottom: 1.5em;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.lab-home__staging {
|
|
165
|
+
display: inline-block;
|
|
166
|
+
font-family: var(--lab-font-mono);
|
|
167
|
+
font-weight: 500;
|
|
168
|
+
color: var(--lab-color-text-strong);
|
|
169
|
+
text-decoration: none;
|
|
170
|
+
border: 1px solid var(--lab-color-border);
|
|
171
|
+
border-left: 1px solid var(--lab-color-text-strong);
|
|
172
|
+
padding: 0.75em 1.25em;
|
|
173
|
+
transition: background-color var(--lab-transition), color var(--lab-transition);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.lab-home__staging:hover,
|
|
177
|
+
.lab-home__staging:focus-visible {
|
|
178
|
+
background-color: var(--lab-color-text-strong);
|
|
179
|
+
color: var(--lab-color-accent-text);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.lab-home__tiers {
|
|
183
|
+
display: grid;
|
|
184
|
+
grid-template-columns: repeat(auto-fit, minmax(14em, 1fr));
|
|
185
|
+
gap: 1em;
|
|
186
|
+
margin-top: 2.5em;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.tier-card {
|
|
190
|
+
display: flex;
|
|
191
|
+
flex-direction: column;
|
|
192
|
+
gap: 0.5em;
|
|
193
|
+
text-decoration: none;
|
|
194
|
+
border: 1px solid var(--lab-color-border);
|
|
195
|
+
background-color: var(--lab-color-surface);
|
|
196
|
+
padding: 1.25em 1.5em;
|
|
197
|
+
transition: border-color var(--lab-transition);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.tier-card:hover,
|
|
201
|
+
.tier-card:focus-visible {
|
|
202
|
+
border-color: var(--lab-color-border-strong);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.tier-card__eyebrow {
|
|
206
|
+
font-family: var(--lab-font-mono);
|
|
207
|
+
font-weight: 500;
|
|
208
|
+
font-size: 0.75em;
|
|
209
|
+
color: var(--lab-color-text-faint);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.tier-card__name {
|
|
213
|
+
font-family: var(--lab-font-heading);
|
|
214
|
+
font-size: 1.4em;
|
|
215
|
+
font-weight: 500;
|
|
216
|
+
color: var(--lab-color-text-strong);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.tier-card__meta {
|
|
220
|
+
display: flex;
|
|
221
|
+
align-items: baseline;
|
|
222
|
+
justify-content: space-between;
|
|
223
|
+
gap: 1em;
|
|
224
|
+
font-family: var(--lab-font-mono);
|
|
225
|
+
font-size: 0.8em;
|
|
226
|
+
color: var(--lab-color-text-faint);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.tier-card__live {
|
|
230
|
+
font-weight: 500;
|
|
231
|
+
line-height: 1;
|
|
232
|
+
padding: 0.45em 0.85em;
|
|
233
|
+
border-radius: var(--lab-radius-pill);
|
|
234
|
+
background-color: var(--lab-color-accent);
|
|
235
|
+
color: var(--lab-color-accent-text);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.lab-home__branches {
|
|
239
|
+
margin-top: 2.5em;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.lab-home__branches ul {
|
|
243
|
+
list-style: none;
|
|
244
|
+
padding: 0;
|
|
245
|
+
margin: 0;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.lab-home__branches li {
|
|
249
|
+
display: flex;
|
|
250
|
+
align-items: baseline;
|
|
251
|
+
gap: 1em;
|
|
252
|
+
padding: 0.5em 0;
|
|
253
|
+
border-bottom: 1px solid var(--lab-color-border);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.lab-home__branches code {
|
|
257
|
+
font-family: var(--lab-font-mono);
|
|
258
|
+
color: var(--lab-color-text-strong);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
.lab-home__branches a {
|
|
262
|
+
font-family: var(--lab-font-mono);
|
|
263
|
+
font-size: 0.85em;
|
|
264
|
+
color: var(--lab-color-text-faint);
|
|
265
|
+
text-decoration: none;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.lab-home__branches a:hover,
|
|
269
|
+
.lab-home__branches a:focus-visible {
|
|
270
|
+
color: var(--lab-color-text-strong);
|
|
271
|
+
text-decoration: underline;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.lab-home__group {
|
|
275
|
+
margin-top: 3em;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.lab-home__group-title {
|
|
279
|
+
font-family: var(--lab-font-mono);
|
|
280
|
+
font-weight: 500;
|
|
281
|
+
font-size: 1em;
|
|
282
|
+
color: var(--lab-color-text-muted);
|
|
283
|
+
margin-bottom: 1em;
|
|
284
|
+
padding-bottom: 0.5em;
|
|
285
|
+
border-bottom: 1px solid var(--lab-color-border);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
.lab-home__group-title a {
|
|
289
|
+
color: inherit;
|
|
290
|
+
text-decoration: none;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.lab-home__group-title a:hover,
|
|
294
|
+
.lab-home__group-title a:focus-visible {
|
|
295
|
+
color: var(--lab-color-text-strong);
|
|
296
|
+
text-decoration: underline;
|
|
297
|
+
}
|
|
298
|
+
</style>
|