stack-site-builder 1.10.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 +21 -0
- package/README.md +45 -0
- package/dev/local-samples-client.js +284 -0
- package/dev/local-samples.mjs +594 -0
- package/index.d.ts +12 -0
- package/index.mjs +124 -0
- package/markdown.mjs +394 -0
- package/package.json +52 -0
- package/src/components/ArrowUpRight.astro +24 -0
- package/src/components/ArticleCard.astro +56 -0
- package/src/components/ArticleDetail.astro +100 -0
- package/src/components/ArticleLink.astro +45 -0
- package/src/components/BackToTop.astro +47 -0
- package/src/components/BlogIndex.astro +137 -0
- package/src/components/Breadcrumb.astro +37 -0
- package/src/components/CategoryIndex.astro +115 -0
- package/src/components/ChevronDown.astro +23 -0
- package/src/components/CodeSamples.astro +141 -0
- package/src/components/CollapsibleGrid.astro +50 -0
- package/src/components/ConceptCard.astro +59 -0
- package/src/components/ConceptDetail.astro +102 -0
- package/src/components/ConceptIndex.astro +143 -0
- package/src/components/ConceptLink.astro +43 -0
- package/src/components/ConceptTools.astro +49 -0
- package/src/components/DeckView.astro +772 -0
- package/src/components/DetailTabs.astro +219 -0
- package/src/components/FilterControls.astro +407 -0
- package/src/components/Glossary.astro +264 -0
- package/src/components/Home.astro +90 -0
- package/src/components/LanguageSwitcher.astro +86 -0
- package/src/components/ListControls.astro +182 -0
- package/src/components/MermaidLoader.astro +96 -0
- package/src/components/PricingSection.astro +100 -0
- package/src/components/ProjectFileList.astro +68 -0
- package/src/components/ProjectFileTree.astro +95 -0
- package/src/components/ProjectRelatedTools.astro +70 -0
- package/src/components/ProjectViewer.astro +431 -0
- package/src/components/RelatedArticles.astro +52 -0
- package/src/components/RelatedConcepts.astro +60 -0
- package/src/components/RelatedTools.astro +55 -0
- package/src/components/SampleIndex.astro +464 -0
- package/src/components/SamplePage.astro +95 -0
- package/src/components/SampleProject.astro +56 -0
- package/src/components/Slide.astro +36 -0
- package/src/components/SlidesIndex.astro +60 -0
- package/src/components/StackCard.astro +183 -0
- package/src/components/StackDetail.astro +507 -0
- package/src/components/StarIcon.astro +21 -0
- package/src/components/TagIndex.astro +51 -0
- package/src/components/ThemeToggle.astro +106 -0
- package/src/components/Toc.astro +39 -0
- package/src/components/TocRail.astro +74 -0
- package/src/components/ToolAvatar.astro +133 -0
- package/src/components/ToolMeta.astro +95 -0
- package/src/components/VendorIndex.astro +51 -0
- package/src/content.ts +228 -0
- package/src/i18n/ui.ts +337 -0
- package/src/layouts/BaseLayout.astro +287 -0
- package/src/lib/articles.ts +27 -0
- package/src/lib/assets.ts +19 -0
- package/src/lib/category-tree.ts +64 -0
- package/src/lib/concepts.ts +35 -0
- package/src/lib/dates.ts +21 -0
- package/src/lib/facets.ts +57 -0
- package/src/lib/github.ts +186 -0
- package/src/lib/inline-md.ts +30 -0
- package/src/lib/pricing.ts +22 -0
- package/src/lib/project.ts +309 -0
- package/src/lib/samples.ts +88 -0
- package/src/lib/slides.ts +25 -0
- package/src/lib/stacks.ts +129 -0
- package/src/lib/toc-rail-client.ts +79 -0
- package/src/pages/article/[...id].astro +24 -0
- package/src/pages/article/category/[id].astro +17 -0
- package/src/pages/article/index.astro +12 -0
- package/src/pages/categories/[id].astro +25 -0
- package/src/pages/concept/[...id].astro +24 -0
- package/src/pages/concept/category/[id].astro +17 -0
- package/src/pages/concept/index.astro +12 -0
- package/src/pages/glossary.astro +12 -0
- package/src/pages/index.astro +9 -0
- package/src/pages/ko/article/[...id].astro +24 -0
- package/src/pages/ko/article/category/[id].astro +17 -0
- package/src/pages/ko/article/index.astro +12 -0
- package/src/pages/ko/categories/[id].astro +24 -0
- package/src/pages/ko/concept/[...id].astro +24 -0
- package/src/pages/ko/concept/category/[id].astro +17 -0
- package/src/pages/ko/concept/index.astro +12 -0
- package/src/pages/ko/glossary.astro +12 -0
- package/src/pages/ko/index.astro +9 -0
- package/src/pages/ko/sample/[folder].astro +16 -0
- package/src/pages/ko/sample/index.astro +12 -0
- package/src/pages/ko/slides/[deck].astro +14 -0
- package/src/pages/ko/slides/index.astro +12 -0
- package/src/pages/ko/stack/[...id].astro +51 -0
- package/src/pages/ko/tags/[tag].astro +18 -0
- package/src/pages/ko/vendors/[vendor].astro +18 -0
- package/src/pages/sample/[folder].astro +16 -0
- package/src/pages/sample/index.astro +12 -0
- package/src/pages/slides/[deck].astro +14 -0
- package/src/pages/slides/index.astro +12 -0
- package/src/pages/stack/[...id].astro +51 -0
- package/src/pages/tags/[tag].astro +18 -0
- package/src/pages/vendors/[vendor].astro +18 -0
- package/src/styles/global.css +2350 -0
|
@@ -0,0 +1,2350 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
|
|
3
|
+
/* This stylesheet ships inside the stack-site-builder package. Tailwind
|
|
4
|
+
only auto-scans the consuming site's own sources, so point it at the
|
|
5
|
+
theme's sources too — relative to this file, i.e. packages/stack-site-builder/src. */
|
|
6
|
+
@source "../";
|
|
7
|
+
|
|
8
|
+
/* MaruBuri (Naver) — a Korean serif that also covers Latin. Used for the
|
|
9
|
+
concept/article reading body (a Medium-style serif column). Remote woff2,
|
|
10
|
+
font-display: swap so text shows immediately in the fallback serif. */
|
|
11
|
+
@font-face {
|
|
12
|
+
font-family: 'MaruBuri';
|
|
13
|
+
src: url(https://hangeul.pstatic.net/hangeul_static/webfont/MaruBuri/MaruBuri-ExtraLight.woff2) format('woff2');
|
|
14
|
+
font-weight: 200;
|
|
15
|
+
font-display: swap;
|
|
16
|
+
}
|
|
17
|
+
@font-face {
|
|
18
|
+
font-family: 'MaruBuri';
|
|
19
|
+
src: url(https://hangeul.pstatic.net/hangeul_static/webfont/MaruBuri/MaruBuri-Light.woff2) format('woff2');
|
|
20
|
+
font-weight: 300;
|
|
21
|
+
font-display: swap;
|
|
22
|
+
}
|
|
23
|
+
@font-face {
|
|
24
|
+
font-family: 'MaruBuri';
|
|
25
|
+
src: url(https://hangeul.pstatic.net/hangeul_static/webfont/MaruBuri/MaruBuri-Regular.woff2) format('woff2');
|
|
26
|
+
font-weight: 400;
|
|
27
|
+
font-display: swap;
|
|
28
|
+
}
|
|
29
|
+
@font-face {
|
|
30
|
+
font-family: 'MaruBuri';
|
|
31
|
+
src: url(https://hangeul.pstatic.net/hangeul_static/webfont/MaruBuri/MaruBuri-SemiBold.woff2) format('woff2');
|
|
32
|
+
font-weight: 600;
|
|
33
|
+
font-display: swap;
|
|
34
|
+
}
|
|
35
|
+
@font-face {
|
|
36
|
+
font-family: 'MaruBuri';
|
|
37
|
+
src: url(https://hangeul.pstatic.net/hangeul_static/webfont/MaruBuri/MaruBuri-Bold.woff2) format('woff2');
|
|
38
|
+
font-weight: 700;
|
|
39
|
+
font-display: swap;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Pretendard — the site's default gothic (sans) for Korean + Latin. */
|
|
43
|
+
@font-face {
|
|
44
|
+
font-family: 'Pretendard';
|
|
45
|
+
src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/pretendard@1.0/Pretendard-Thin.woff2') format('woff2');
|
|
46
|
+
font-weight: 100;
|
|
47
|
+
font-display: swap;
|
|
48
|
+
}
|
|
49
|
+
@font-face {
|
|
50
|
+
font-family: 'Pretendard';
|
|
51
|
+
src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/pretendard@1.0/Pretendard-ExtraLight.woff2') format('woff2');
|
|
52
|
+
font-weight: 200;
|
|
53
|
+
font-display: swap;
|
|
54
|
+
}
|
|
55
|
+
@font-face {
|
|
56
|
+
font-family: 'Pretendard';
|
|
57
|
+
src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/pretendard@1.0/Pretendard-Light.woff2') format('woff2');
|
|
58
|
+
font-weight: 300;
|
|
59
|
+
font-display: swap;
|
|
60
|
+
}
|
|
61
|
+
@font-face {
|
|
62
|
+
font-family: 'Pretendard';
|
|
63
|
+
src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/pretendard@1.0/Pretendard-Regular.woff2') format('woff2');
|
|
64
|
+
font-weight: 400;
|
|
65
|
+
font-display: swap;
|
|
66
|
+
}
|
|
67
|
+
@font-face {
|
|
68
|
+
font-family: 'Pretendard';
|
|
69
|
+
src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/pretendard@1.0/Pretendard-Medium.woff2') format('woff2');
|
|
70
|
+
font-weight: 500;
|
|
71
|
+
font-display: swap;
|
|
72
|
+
}
|
|
73
|
+
@font-face {
|
|
74
|
+
font-family: 'Pretendard';
|
|
75
|
+
src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/pretendard@1.0/Pretendard-SemiBold.woff2') format('woff2');
|
|
76
|
+
font-weight: 600;
|
|
77
|
+
font-display: swap;
|
|
78
|
+
}
|
|
79
|
+
@font-face {
|
|
80
|
+
font-family: 'Pretendard';
|
|
81
|
+
src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/pretendard@1.0/Pretendard-Bold.woff2') format('woff2');
|
|
82
|
+
font-weight: 700;
|
|
83
|
+
font-display: swap;
|
|
84
|
+
}
|
|
85
|
+
@font-face {
|
|
86
|
+
font-family: 'Pretendard';
|
|
87
|
+
src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/pretendard@1.0/Pretendard-ExtraBold.woff2') format('woff2');
|
|
88
|
+
font-weight: 800;
|
|
89
|
+
font-display: swap;
|
|
90
|
+
}
|
|
91
|
+
@font-face {
|
|
92
|
+
font-family: 'Pretendard';
|
|
93
|
+
src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/pretendard@1.0/Pretendard-Black.woff2') format('woff2');
|
|
94
|
+
font-weight: 900;
|
|
95
|
+
font-display: swap;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* Light is the default; `data-theme="dark"` (set by the inline script in
|
|
99
|
+
BaseLayout) switches to dark. The @media block covers no-JS users whose
|
|
100
|
+
system prefers dark before any explicit choice is stored. */
|
|
101
|
+
:root {
|
|
102
|
+
color-scheme: light;
|
|
103
|
+
--aas-bg: #fafafa;
|
|
104
|
+
--aas-panel: #fdfdfd;
|
|
105
|
+
--aas-border: #f4f4f4;
|
|
106
|
+
--aas-text: #2b2b31;
|
|
107
|
+
--aas-muted: #76767e;
|
|
108
|
+
--aas-accent: #5f63c4;
|
|
109
|
+
--aas-shadow: 0 8px 24px -10px rgb(20 20 40 / 0.22);
|
|
110
|
+
/* Interactive-surface tint (hover/active). Text-derived so it has real
|
|
111
|
+
contrast on any background even when --aas-panel is near-white. Defined
|
|
112
|
+
once; the var(--aas-text) inside resolves per theme. */
|
|
113
|
+
--aas-tint: color-mix(in srgb, var(--aas-text) 7%, transparent);
|
|
114
|
+
/* Default gothic (sans) stack — Pretendard first, system fallbacks after.
|
|
115
|
+
Applied site-wide via the `body` rule below; the concept/article reading
|
|
116
|
+
body opts into MaruBuri serif. */
|
|
117
|
+
--aas-sans: 'Pretendard', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
|
|
118
|
+
/* Mermaid cluster ("zone") highlight colours. `defaultzone` is the accent
|
|
119
|
+
nudged toward teal (a calm blue); `aaszone` is a warm amber that stands out
|
|
120
|
+
as the emphasized region (e.g. the harness we're describing). */
|
|
121
|
+
--aas-diagram-zone: color-mix(in srgb, var(--aas-accent) 65%, #2dd4bf);
|
|
122
|
+
--aas-diagram-zone-warm: #f59e0b;
|
|
123
|
+
/* Diagram role colours: the model, the evaluator/checker, the tracing store,
|
|
124
|
+
and the reference it checks against (a source DB or an execution env). */
|
|
125
|
+
--aas-role-model: #3b82f6;
|
|
126
|
+
--aas-role-eval: #22c55e;
|
|
127
|
+
--aas-role-trace: #f59e0b;
|
|
128
|
+
--aas-role-source: #14b8a6;
|
|
129
|
+
--aas-role-tool: #8b5cf6;
|
|
130
|
+
--aas-role-guard: #f43f5e;
|
|
131
|
+
/* "You are here" highlight — orange, used to spotlight one node when a
|
|
132
|
+
section walks through a single piece of a larger diagram. */
|
|
133
|
+
--aas-role-focus: #f97316;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
:root[data-theme="dark"] {
|
|
137
|
+
color-scheme: dark;
|
|
138
|
+
--aas-bg: #0c0d11;
|
|
139
|
+
--aas-panel: #1a1b21;
|
|
140
|
+
--aas-border: #25262e;
|
|
141
|
+
--aas-text: #e2e3e8;
|
|
142
|
+
--aas-muted: #989aa4;
|
|
143
|
+
--aas-accent: #9398f0;
|
|
144
|
+
--aas-shadow: 0 8px 24px -8px rgb(0 0 0 / 0.6);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
@media (prefers-color-scheme: dark) {
|
|
148
|
+
:root:not([data-theme]) {
|
|
149
|
+
color-scheme: dark;
|
|
150
|
+
--aas-bg: #0c0d11;
|
|
151
|
+
--aas-panel: #1a1b21;
|
|
152
|
+
--aas-border: #25262e;
|
|
153
|
+
--aas-text: #e2e3e8;
|
|
154
|
+
--aas-muted: #989aa4;
|
|
155
|
+
--aas-accent: #9398f0;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
html {
|
|
160
|
+
/* No global smooth scroll: it makes the browser animate scroll *restoration*
|
|
161
|
+
on back/forward, which is disorienting when returning to the list. The
|
|
162
|
+
deliberate smooth scrolls (back-to-top, file selector) pass behavior:
|
|
163
|
+
'smooth' explicitly in JS, so they still animate. */
|
|
164
|
+
background: var(--aas-bg);
|
|
165
|
+
color: var(--aas-text);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/* Neutral chip surface — a subtle tint that reads on any background (page or
|
|
169
|
+
the panel-colored cards), so no outline is needed. */
|
|
170
|
+
.aas-chip {
|
|
171
|
+
background: color-mix(in srgb, var(--aas-text) 5%, transparent);
|
|
172
|
+
color: var(--aas-muted);
|
|
173
|
+
}
|
|
174
|
+
/* Deprecated / maintenance-only badge — amber warning surface. */
|
|
175
|
+
.aas-deprecated {
|
|
176
|
+
background: color-mix(in srgb, #d97706 16%, transparent);
|
|
177
|
+
color: #b45309;
|
|
178
|
+
}
|
|
179
|
+
:root[data-theme='dark'] .aas-deprecated {
|
|
180
|
+
color: #fbbf24;
|
|
181
|
+
}
|
|
182
|
+
/* "No updates in 1+ year" — same amber warning weight as deprecated. */
|
|
183
|
+
.aas-stale {
|
|
184
|
+
background: color-mix(in srgb, #d97706 16%, transparent);
|
|
185
|
+
color: #b45309;
|
|
186
|
+
}
|
|
187
|
+
:root[data-theme='dark'] .aas-stale {
|
|
188
|
+
color: #fbbf24;
|
|
189
|
+
}
|
|
190
|
+
/* "No updates in 6+ months" — a milder, lower-contrast caution (softer yellow). */
|
|
191
|
+
.aas-aging {
|
|
192
|
+
background: color-mix(in srgb, #ca8a04 12%, transparent);
|
|
193
|
+
color: #a16207;
|
|
194
|
+
}
|
|
195
|
+
:root[data-theme='dark'] .aas-aging {
|
|
196
|
+
color: #facc15;
|
|
197
|
+
}
|
|
198
|
+
/* Pricing chip: a soft accent-tinted surface with a faint accent outline. */
|
|
199
|
+
.aas-pricing {
|
|
200
|
+
background: color-mix(in srgb, var(--aas-accent) 13%, transparent);
|
|
201
|
+
color: var(--aas-accent);
|
|
202
|
+
}
|
|
203
|
+
/* "Completely free" pricing chip — a positive green to stand out from paid tiers. */
|
|
204
|
+
.aas-free {
|
|
205
|
+
background: color-mix(in srgb, #16a34a 15%, transparent);
|
|
206
|
+
color: #15803d;
|
|
207
|
+
}
|
|
208
|
+
:root[data-theme='dark'] .aas-free {
|
|
209
|
+
color: #4ade80;
|
|
210
|
+
}
|
|
211
|
+
/* Theme-aware logos: show only the variant matching the active theme
|
|
212
|
+
(ToolAvatar emits both when a logoDark is set). */
|
|
213
|
+
.aas-logo-dark {
|
|
214
|
+
display: none;
|
|
215
|
+
}
|
|
216
|
+
:root[data-theme='dark'] .aas-logo-light {
|
|
217
|
+
display: none;
|
|
218
|
+
}
|
|
219
|
+
:root[data-theme='dark'] .aas-logo-dark {
|
|
220
|
+
display: revert;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/* Subtle "lift + shadow" on hover for cards and button-like elements. Gated to
|
|
224
|
+
devices with real hover, so the effect never "sticks" after a tap on touch. */
|
|
225
|
+
.aas-lift {
|
|
226
|
+
transition:
|
|
227
|
+
transform 0.16s ease,
|
|
228
|
+
box-shadow 0.16s ease,
|
|
229
|
+
border-color 0.16s ease;
|
|
230
|
+
}
|
|
231
|
+
@media (hover: hover) {
|
|
232
|
+
.aas-lift:hover {
|
|
233
|
+
transform: translateY(-2px);
|
|
234
|
+
box-shadow: var(--aas-shadow);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
@media (hover: hover) and (prefers-reduced-motion: reduce) {
|
|
238
|
+
.aas-lift:hover {
|
|
239
|
+
transform: none;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/* Floating "back to top" button: only below the TOC-rail breakpoint (the rail
|
|
244
|
+
handles navigation on wide screens), and only once scrolled down a bit
|
|
245
|
+
(`data-visible`, toggled in BackToTop.astro). */
|
|
246
|
+
.aas-totop {
|
|
247
|
+
display: none;
|
|
248
|
+
}
|
|
249
|
+
@media (max-width: 1199.98px) {
|
|
250
|
+
.aas-totop[data-visible] {
|
|
251
|
+
display: flex;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/* Right-rail TOC: an in-flow sticky column beside the content, shown once the
|
|
256
|
+
viewport is wide enough to hold both (≥1200px). Below that it hides and the
|
|
257
|
+
content spans the full column. A flex column so a long TOC scrolls internally
|
|
258
|
+
while the back-to-top button stays pinned at the bottom. */
|
|
259
|
+
.aas-toc-rail {
|
|
260
|
+
display: none;
|
|
261
|
+
}
|
|
262
|
+
@media (min-width: 1200px) {
|
|
263
|
+
.aas-toc-rail {
|
|
264
|
+
display: flex;
|
|
265
|
+
flex-direction: column;
|
|
266
|
+
/* Sit on the LEFT of the content (source order stays content-first for a11y;
|
|
267
|
+
order pulls the rail visually ahead). */
|
|
268
|
+
order: -1;
|
|
269
|
+
position: sticky;
|
|
270
|
+
top: 7rem;
|
|
271
|
+
align-self: flex-start;
|
|
272
|
+
flex: none;
|
|
273
|
+
width: 13rem;
|
|
274
|
+
max-height: calc(100vh - 9rem);
|
|
275
|
+
}
|
|
276
|
+
/* Embedded article sample: at the TOC-rail breakpoint the rail already lists
|
|
277
|
+
the files + related tools, so drop the in-body sidebar and let the code pane
|
|
278
|
+
span full width. Below 1200px (no rail) the inline sidebar stays. */
|
|
279
|
+
.aas-embed-proj {
|
|
280
|
+
display: block;
|
|
281
|
+
}
|
|
282
|
+
.aas-embed-sidebar {
|
|
283
|
+
display: none;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
.aas-toc-scroll {
|
|
287
|
+
min-height: 0; /* allow this flex child to shrink so it can scroll */
|
|
288
|
+
overflow-y: auto;
|
|
289
|
+
}
|
|
290
|
+
.aas-toc-rail a[aria-current='true'] {
|
|
291
|
+
background: var(--aas-tint);
|
|
292
|
+
color: var(--aas-text);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/* "Back to top" pinned at the bottom of the TOC rail (surface row, no divider). */
|
|
296
|
+
/* Pinned foot of the TOC rail: back-to-top on the left, collapse/expand-all on
|
|
297
|
+
the right. */
|
|
298
|
+
.aas-toc-foot {
|
|
299
|
+
flex-shrink: 0;
|
|
300
|
+
margin-top: 0.5rem;
|
|
301
|
+
display: flex;
|
|
302
|
+
align-items: center;
|
|
303
|
+
justify-content: space-between;
|
|
304
|
+
gap: 0.5rem;
|
|
305
|
+
}
|
|
306
|
+
.aas-toc-top {
|
|
307
|
+
padding: 0.4rem 0.625rem;
|
|
308
|
+
border-radius: 0.375rem;
|
|
309
|
+
text-align: left;
|
|
310
|
+
font-size: 0.8rem;
|
|
311
|
+
color: var(--aas-muted);
|
|
312
|
+
background: none;
|
|
313
|
+
cursor: pointer;
|
|
314
|
+
transition:
|
|
315
|
+
color 0.15s,
|
|
316
|
+
background-color 0.15s;
|
|
317
|
+
}
|
|
318
|
+
.aas-toc-allbtn {
|
|
319
|
+
flex-shrink: 0;
|
|
320
|
+
padding: 0.4rem 0.5rem;
|
|
321
|
+
border-radius: 0.375rem;
|
|
322
|
+
font-size: 0.72rem;
|
|
323
|
+
color: var(--aas-muted);
|
|
324
|
+
background: none;
|
|
325
|
+
cursor: pointer;
|
|
326
|
+
transition:
|
|
327
|
+
color 0.15s,
|
|
328
|
+
background-color 0.15s;
|
|
329
|
+
}
|
|
330
|
+
.aas-toc-top:hover,
|
|
331
|
+
.aas-toc-allbtn:hover {
|
|
332
|
+
background: var(--aas-tint);
|
|
333
|
+
color: var(--aas-text);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/* Medium-style reading body: a larger MaruBuri serif column for the concept,
|
|
337
|
+
article, and stack prose (anything tagged .aas-reading). Headings stay sans
|
|
338
|
+
for contrast, inline tool cards stay sans, and code stays monospace — only
|
|
339
|
+
the running text becomes serif. Concept/article/stack share the same width
|
|
340
|
+
and the .aas-toc-rail TOC, so there is no separate doc layout. */
|
|
341
|
+
.aas-reading.aas-reading {
|
|
342
|
+
font-family: 'MaruBuri', ui-serif, Georgia, serif;
|
|
343
|
+
font-size: 1.2rem;
|
|
344
|
+
line-height: 1.85;
|
|
345
|
+
}
|
|
346
|
+
.aas-reading.aas-reading :where(p, ul, ol, blockquote, td, th) {
|
|
347
|
+
line-height: 1.85;
|
|
348
|
+
}
|
|
349
|
+
.aas-reading.aas-reading :where(h2) {
|
|
350
|
+
font-size: 1.7rem;
|
|
351
|
+
}
|
|
352
|
+
.aas-reading.aas-reading :where(h3) {
|
|
353
|
+
font-size: 1.35rem;
|
|
354
|
+
}
|
|
355
|
+
.aas-reading.aas-reading :where(h1, h2, h3, h4, h5, h6),
|
|
356
|
+
.aas-reading.aas-reading :where(table),
|
|
357
|
+
.aas-reading.aas-reading a.aas-lift,
|
|
358
|
+
.aas-reading.aas-reading .aas-sample-picker {
|
|
359
|
+
font-family: var(--aas-sans);
|
|
360
|
+
}
|
|
361
|
+
.aas-reading.aas-reading :where(code, pre, kbd, samp) {
|
|
362
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
363
|
+
}
|
|
364
|
+
/* Korean line breaking: wrap at word (eojeol) boundaries — i.e. at spaces —
|
|
365
|
+
instead of between arbitrary characters, so a word like "처음부터" never
|
|
366
|
+
splits mid-word across two lines. `word-break` inherits, so setting it on the
|
|
367
|
+
reading column and the description covers all their descendants. Scoped to
|
|
368
|
+
Korean pages via <html lang="ko">; Latin scripts already wrap on spaces. */
|
|
369
|
+
html[lang='ko'] .aas-reading,
|
|
370
|
+
html[lang='ko'] .aas-md,
|
|
371
|
+
html[lang='ko'] h1 {
|
|
372
|
+
word-break: keep-all;
|
|
373
|
+
}
|
|
374
|
+
/* Doc tables: a touch larger, centered (shrink-to-content), roomier cells, and
|
|
375
|
+
a full-row hover highlight. `fit-content` + `margin-inline: auto` centers the
|
|
376
|
+
table block while `max-width`/overflow (from the base .prose rule) keep it
|
|
377
|
+
scrollable if it ever outgrows the column. */
|
|
378
|
+
.aas-reading.aas-reading :where(table) {
|
|
379
|
+
display: table;
|
|
380
|
+
width: fit-content;
|
|
381
|
+
max-width: 100%;
|
|
382
|
+
margin-inline: auto;
|
|
383
|
+
font-size: 1.05rem;
|
|
384
|
+
/* Rounded outer corners need separated borders + clipping (border-collapse
|
|
385
|
+
can't round). The table draws the outer frame; cells draw the inner grid. */
|
|
386
|
+
border-collapse: separate;
|
|
387
|
+
border-spacing: 0;
|
|
388
|
+
border: 1px solid var(--aas-border);
|
|
389
|
+
border-radius: 0.75rem;
|
|
390
|
+
overflow: hidden;
|
|
391
|
+
}
|
|
392
|
+
.aas-reading.aas-reading :where(th, td) {
|
|
393
|
+
padding: 0.7rem 1.25rem;
|
|
394
|
+
border: 0;
|
|
395
|
+
border-right: 1px solid var(--aas-border);
|
|
396
|
+
border-bottom: 1px solid var(--aas-border);
|
|
397
|
+
}
|
|
398
|
+
.aas-reading.aas-reading :where(tr > :last-child) {
|
|
399
|
+
border-right: 0;
|
|
400
|
+
}
|
|
401
|
+
.aas-reading.aas-reading :where(tr:last-child > *) {
|
|
402
|
+
border-bottom: 0;
|
|
403
|
+
}
|
|
404
|
+
.aas-reading.aas-reading :where(tbody tr) {
|
|
405
|
+
transition: background-color 0.15s;
|
|
406
|
+
}
|
|
407
|
+
.aas-reading.aas-reading tbody tr:hover {
|
|
408
|
+
background: var(--aas-tint);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/* "#" copy-link anchor prepended to headings (h2/h3). Faint by default, fully
|
|
412
|
+
shown on hover/focus. `a.aas-anchor` outranks `.prose :where(a)` so it keeps
|
|
413
|
+
no underline / muted color. Click copies the section URL (see BaseLayout). */
|
|
414
|
+
a.aas-anchor {
|
|
415
|
+
position: relative;
|
|
416
|
+
margin-right: 0.4rem;
|
|
417
|
+
font-weight: 400;
|
|
418
|
+
color: var(--aas-muted);
|
|
419
|
+
text-decoration: none;
|
|
420
|
+
opacity: 0.25;
|
|
421
|
+
transition:
|
|
422
|
+
opacity 0.15s,
|
|
423
|
+
color 0.15s;
|
|
424
|
+
}
|
|
425
|
+
/* The "#" count mirrors the heading depth: h2 → #, h3 → ##, h4 → ###. */
|
|
426
|
+
:where(h2) > a.aas-anchor::before {
|
|
427
|
+
content: '#';
|
|
428
|
+
}
|
|
429
|
+
:where(h3) > a.aas-anchor::before {
|
|
430
|
+
content: '##';
|
|
431
|
+
}
|
|
432
|
+
:where(h4) > a.aas-anchor::before {
|
|
433
|
+
content: '###';
|
|
434
|
+
}
|
|
435
|
+
:where(h2, h3, h4):hover > a.aas-anchor,
|
|
436
|
+
a.aas-anchor:hover,
|
|
437
|
+
a.aas-anchor:focus {
|
|
438
|
+
opacity: 1;
|
|
439
|
+
color: var(--aas-accent);
|
|
440
|
+
}
|
|
441
|
+
a.aas-anchor.copied {
|
|
442
|
+
opacity: 1;
|
|
443
|
+
}
|
|
444
|
+
a.aas-anchor.copied::after {
|
|
445
|
+
content: 'Copied';
|
|
446
|
+
position: absolute;
|
|
447
|
+
bottom: 100%;
|
|
448
|
+
left: 0;
|
|
449
|
+
margin-bottom: 0.3rem;
|
|
450
|
+
padding: 0.05rem 0.4rem;
|
|
451
|
+
white-space: nowrap;
|
|
452
|
+
font-size: 0.7rem;
|
|
453
|
+
font-weight: 400;
|
|
454
|
+
color: var(--aas-accent);
|
|
455
|
+
border: 1px solid var(--aas-border);
|
|
456
|
+
border-radius: 0.3rem;
|
|
457
|
+
background: var(--aas-panel);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
body {
|
|
461
|
+
font-family: var(--aas-sans);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/* Tailwind v4 no longer sets a pointer cursor on buttons; restore it (and for
|
|
465
|
+
<summary>, used by the custom dropdowns). */
|
|
466
|
+
button:not(:disabled),
|
|
467
|
+
summary {
|
|
468
|
+
cursor: pointer;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/* Make the `hidden` attribute win over display:flex/grid (used by the homepage
|
|
472
|
+
search/filter to hide cards and sections). */
|
|
473
|
+
[hidden] {
|
|
474
|
+
display: none !important;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/* Generic <details> dropdown used by the homepage filter/sort controls. */
|
|
478
|
+
.aas-dd {
|
|
479
|
+
position: relative;
|
|
480
|
+
}
|
|
481
|
+
.aas-dd > summary {
|
|
482
|
+
list-style: none;
|
|
483
|
+
}
|
|
484
|
+
.aas-dd > summary::-webkit-details-marker {
|
|
485
|
+
display: none;
|
|
486
|
+
}
|
|
487
|
+
.aas-dd [data-sort][aria-current='true'] [data-check] {
|
|
488
|
+
opacity: 1;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/* Custom checkbox (filter facets). */
|
|
492
|
+
.aas-check {
|
|
493
|
+
appearance: none;
|
|
494
|
+
-webkit-appearance: none;
|
|
495
|
+
position: relative;
|
|
496
|
+
width: 1.1rem;
|
|
497
|
+
height: 1.1rem;
|
|
498
|
+
flex-shrink: 0;
|
|
499
|
+
border: 1.5px solid var(--aas-border);
|
|
500
|
+
border-radius: 0.35rem;
|
|
501
|
+
background: var(--aas-panel);
|
|
502
|
+
cursor: pointer;
|
|
503
|
+
transition:
|
|
504
|
+
background-color 0.12s,
|
|
505
|
+
border-color 0.12s;
|
|
506
|
+
}
|
|
507
|
+
.aas-check:hover {
|
|
508
|
+
border-color: var(--aas-accent);
|
|
509
|
+
}
|
|
510
|
+
.aas-check:checked {
|
|
511
|
+
background: var(--aas-accent);
|
|
512
|
+
border-color: var(--aas-accent);
|
|
513
|
+
}
|
|
514
|
+
.aas-check::after {
|
|
515
|
+
content: '';
|
|
516
|
+
position: absolute;
|
|
517
|
+
left: 0.34rem;
|
|
518
|
+
top: 0.14rem;
|
|
519
|
+
width: 0.3rem;
|
|
520
|
+
height: 0.55rem;
|
|
521
|
+
border: solid #fff;
|
|
522
|
+
border-width: 0 2px 2px 0;
|
|
523
|
+
transform: rotate(45deg) scale(0);
|
|
524
|
+
transition: transform 0.12s;
|
|
525
|
+
}
|
|
526
|
+
.aas-check:checked::after {
|
|
527
|
+
transform: rotate(45deg) scale(1);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/* Readable defaults for rendered Markdown bodies. */
|
|
531
|
+
.prose :where(h1) {
|
|
532
|
+
font-size: 1.6rem;
|
|
533
|
+
font-weight: 700;
|
|
534
|
+
margin: 1.5rem 0 0.75rem;
|
|
535
|
+
scroll-margin-top: 1.5rem;
|
|
536
|
+
}
|
|
537
|
+
.prose :where(h1):first-child {
|
|
538
|
+
margin-top: 0;
|
|
539
|
+
}
|
|
540
|
+
.prose :where(h2) {
|
|
541
|
+
font-size: 1.5rem;
|
|
542
|
+
font-weight: 700;
|
|
543
|
+
margin: 2rem 0 0.75rem;
|
|
544
|
+
scroll-margin-top: 1.5rem; /* so TOC anchor jumps don't clip the heading */
|
|
545
|
+
}
|
|
546
|
+
.prose :where(h3) {
|
|
547
|
+
font-size: 1.2rem;
|
|
548
|
+
font-weight: 600;
|
|
549
|
+
margin: 1.5rem 0 0.5rem;
|
|
550
|
+
scroll-margin-top: 1.5rem;
|
|
551
|
+
}
|
|
552
|
+
.prose :where(h4) {
|
|
553
|
+
font-size: 1.05rem;
|
|
554
|
+
font-weight: 600;
|
|
555
|
+
margin: 1.5rem 0 0.5rem;
|
|
556
|
+
scroll-margin-top: 1.5rem;
|
|
557
|
+
}
|
|
558
|
+
.prose :where(p, ul, ol) {
|
|
559
|
+
margin: 0.75rem 0;
|
|
560
|
+
line-height: 1.7;
|
|
561
|
+
color: var(--aas-text);
|
|
562
|
+
}
|
|
563
|
+
.prose :where(ul) {
|
|
564
|
+
list-style: disc;
|
|
565
|
+
padding-left: 1.25rem;
|
|
566
|
+
}
|
|
567
|
+
.prose :where(ol) {
|
|
568
|
+
list-style: decimal;
|
|
569
|
+
padding-left: 1.25rem;
|
|
570
|
+
}
|
|
571
|
+
.prose :where(a) {
|
|
572
|
+
color: var(--aas-accent);
|
|
573
|
+
text-decoration: none;
|
|
574
|
+
}
|
|
575
|
+
.prose :where(a):hover {
|
|
576
|
+
text-decoration: underline;
|
|
577
|
+
}
|
|
578
|
+
/* Inline code chips in running prose. Chips inside card-style UI links
|
|
579
|
+
(a.aas-lift — e.g. the project viewer's GitHub button) style themselves
|
|
580
|
+
with utilities and must not pick this up. */
|
|
581
|
+
.prose :where(code):not(pre code, .aas-lift code) {
|
|
582
|
+
background: var(--aas-panel);
|
|
583
|
+
border: 1px solid var(--aas-border);
|
|
584
|
+
border-radius: 0.3rem;
|
|
585
|
+
padding: 0.1rem 0.35rem;
|
|
586
|
+
font-size: 0.85em;
|
|
587
|
+
}
|
|
588
|
+
/* Tiny inline Markdown (`code`/bold/italic) rendered into description fields
|
|
589
|
+
shown outside .prose — detail headers, cards, and related-item links. */
|
|
590
|
+
.aas-md code {
|
|
591
|
+
font-family: var(--aas-mono, ui-monospace, monospace);
|
|
592
|
+
background: var(--aas-panel);
|
|
593
|
+
border: 1px solid var(--aas-border);
|
|
594
|
+
border-radius: 0.3rem;
|
|
595
|
+
padding: 0.05rem 0.3rem;
|
|
596
|
+
font-size: 0.85em;
|
|
597
|
+
}
|
|
598
|
+
/* Code blocks — but not Mermaid diagrams, which carry their own background. */
|
|
599
|
+
.prose :where(pre:not(.mermaid)) {
|
|
600
|
+
background: #0e1117 !important;
|
|
601
|
+
border: 1px solid var(--aas-border);
|
|
602
|
+
border-radius: 0.6rem;
|
|
603
|
+
padding: 1rem 1.1rem;
|
|
604
|
+
overflow-x: auto;
|
|
605
|
+
margin: 1rem 0;
|
|
606
|
+
}
|
|
607
|
+
/* Hybrid wrapping: soft-wrap shell commands and example output (which are
|
|
608
|
+
prose-like and run long on mobile) while leaving real source code blocks
|
|
609
|
+
horizontally scrollable so their indentation/alignment stays intact. The
|
|
610
|
+
data-lang attribute is set by src/lib/project.ts when rendering READMEs. */
|
|
611
|
+
.prose :where(pre[data-lang='bash'], pre[data-lang='sh'], pre[data-lang='shell'], pre[data-lang='console'], pre[data-lang='text']) {
|
|
612
|
+
white-space: pre-wrap;
|
|
613
|
+
overflow-wrap: anywhere;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/* Copy-to-clipboard button mounted on code blocks (see BaseLayout script).
|
|
617
|
+
The host is a non-scrolling wrapper so the button stays pinned top-right
|
|
618
|
+
instead of scrolling away with long code. */
|
|
619
|
+
.aas-copyhost {
|
|
620
|
+
position: relative;
|
|
621
|
+
}
|
|
622
|
+
.aas-copy-btn {
|
|
623
|
+
position: absolute;
|
|
624
|
+
top: 0.5rem;
|
|
625
|
+
right: 0.5rem;
|
|
626
|
+
z-index: 2;
|
|
627
|
+
display: inline-flex;
|
|
628
|
+
align-items: center;
|
|
629
|
+
justify-content: center;
|
|
630
|
+
width: 1.9rem;
|
|
631
|
+
height: 1.9rem;
|
|
632
|
+
padding: 0;
|
|
633
|
+
border: 1px solid var(--aas-border);
|
|
634
|
+
border-radius: 0.4rem;
|
|
635
|
+
background: color-mix(in srgb, var(--aas-panel) 80%, transparent);
|
|
636
|
+
color: var(--aas-muted);
|
|
637
|
+
cursor: pointer;
|
|
638
|
+
opacity: 0;
|
|
639
|
+
transition:
|
|
640
|
+
opacity 0.15s ease,
|
|
641
|
+
color 0.15s ease,
|
|
642
|
+
border-color 0.15s ease;
|
|
643
|
+
}
|
|
644
|
+
.aas-copyhost:hover .aas-copy-btn,
|
|
645
|
+
.aas-copy-btn:focus-visible {
|
|
646
|
+
opacity: 1;
|
|
647
|
+
}
|
|
648
|
+
/* Touch devices have no hover — keep the button discoverable. */
|
|
649
|
+
@media (hover: none) {
|
|
650
|
+
.aas-copy-btn {
|
|
651
|
+
opacity: 0.65;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
.aas-copy-btn:hover {
|
|
655
|
+
color: var(--aas-text);
|
|
656
|
+
border-color: var(--aas-text);
|
|
657
|
+
}
|
|
658
|
+
.aas-copy-btn.copied {
|
|
659
|
+
color: #16a34a;
|
|
660
|
+
border-color: #16a34a;
|
|
661
|
+
opacity: 1;
|
|
662
|
+
}
|
|
663
|
+
.aas-copy-btn svg {
|
|
664
|
+
width: 0.95rem;
|
|
665
|
+
height: 0.95rem;
|
|
666
|
+
}
|
|
667
|
+
.aas-copy-btn .aas-ico-check {
|
|
668
|
+
display: none;
|
|
669
|
+
}
|
|
670
|
+
.aas-copy-btn.copied .aas-ico-copy {
|
|
671
|
+
display: none;
|
|
672
|
+
}
|
|
673
|
+
.aas-copy-btn.copied .aas-ico-check {
|
|
674
|
+
display: inline;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/* Mermaid diagram container. The styled wrapper is a div we own, so the
|
|
678
|
+
border/radius survive Mermaid replacing the inner <pre> with an <svg>. */
|
|
679
|
+
.aas-diagram {
|
|
680
|
+
margin: 1rem 0;
|
|
681
|
+
padding: 1rem;
|
|
682
|
+
background: transparent;
|
|
683
|
+
border: 1px solid var(--aas-border);
|
|
684
|
+
border-radius: 0.6rem;
|
|
685
|
+
overflow: hidden;
|
|
686
|
+
}
|
|
687
|
+
.aas-diagram .mermaid {
|
|
688
|
+
margin: 0;
|
|
689
|
+
background: transparent;
|
|
690
|
+
text-align: center;
|
|
691
|
+
line-height: 0; /* avoid extra space from the raw source before render */
|
|
692
|
+
}
|
|
693
|
+
/* Mermaid renders a block <svg>; center it horizontally. */
|
|
694
|
+
.aas-diagram .mermaid svg {
|
|
695
|
+
display: block;
|
|
696
|
+
margin-inline: auto;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/* Mermaid theme: rounded corners + soft pastel fills, derived from the site
|
|
700
|
+
accent so it adapts to light/dark. `!important` overrides Mermaid's own
|
|
701
|
+
id-scoped <style> block. Applies wherever a diagram renders (prose + samples). */
|
|
702
|
+
.mermaid g.node rect,
|
|
703
|
+
.mermaid g.node polygon {
|
|
704
|
+
rx: 12px;
|
|
705
|
+
ry: 12px;
|
|
706
|
+
}
|
|
707
|
+
.mermaid g.node rect,
|
|
708
|
+
.mermaid g.node polygon,
|
|
709
|
+
.mermaid g.node path {
|
|
710
|
+
fill: color-mix(in srgb, var(--aas-accent) 9%, var(--aas-panel)) !important;
|
|
711
|
+
stroke: color-mix(in srgb, var(--aas-accent) 45%, transparent) !important;
|
|
712
|
+
stroke-width: 1.5px !important;
|
|
713
|
+
}
|
|
714
|
+
/* Role-coloured nodes — opt in per diagram with `class <node> role…`. The model,
|
|
715
|
+
the evaluator/checker, and the tracing store each read as a distinct colour. */
|
|
716
|
+
.mermaid g.node.roleModel :is(rect, polygon, path) {
|
|
717
|
+
fill: color-mix(in srgb, var(--aas-role-model) 14%, var(--aas-panel)) !important;
|
|
718
|
+
stroke: color-mix(in srgb, var(--aas-role-model) 55%, transparent) !important;
|
|
719
|
+
}
|
|
720
|
+
.mermaid g.node.roleEval :is(rect, polygon, path) {
|
|
721
|
+
fill: color-mix(in srgb, var(--aas-role-eval) 15%, var(--aas-panel)) !important;
|
|
722
|
+
stroke: color-mix(in srgb, var(--aas-role-eval) 55%, transparent) !important;
|
|
723
|
+
}
|
|
724
|
+
.mermaid g.node.roleTrace :is(rect, polygon, path) {
|
|
725
|
+
fill: color-mix(in srgb, var(--aas-role-trace) 15%, var(--aas-panel)) !important;
|
|
726
|
+
stroke: color-mix(in srgb, var(--aas-role-trace) 55%, transparent) !important;
|
|
727
|
+
}
|
|
728
|
+
.mermaid g.node.roleSource :is(rect, polygon, path) {
|
|
729
|
+
fill: color-mix(in srgb, var(--aas-role-source) 15%, var(--aas-panel)) !important;
|
|
730
|
+
stroke: color-mix(in srgb, var(--aas-role-source) 55%, transparent) !important;
|
|
731
|
+
}
|
|
732
|
+
.mermaid g.node.roleTool :is(rect, polygon, path) {
|
|
733
|
+
fill: color-mix(in srgb, var(--aas-role-tool) 14%, var(--aas-panel)) !important;
|
|
734
|
+
stroke: color-mix(in srgb, var(--aas-role-tool) 55%, transparent) !important;
|
|
735
|
+
}
|
|
736
|
+
.mermaid g.node.roleGuard :is(rect, polygon, path) {
|
|
737
|
+
fill: color-mix(in srgb, var(--aas-role-guard) 14%, var(--aas-panel)) !important;
|
|
738
|
+
stroke: color-mix(in srgb, var(--aas-role-guard) 55%, transparent) !important;
|
|
739
|
+
}
|
|
740
|
+
/* Spotlight (orange) — stronger fill/stroke than the role tints so the node the
|
|
741
|
+
surrounding prose is explaining pops out. Declared last so it wins over a
|
|
742
|
+
node's ordinary role class. */
|
|
743
|
+
.mermaid g.node.roleFocus :is(rect, polygon, path) {
|
|
744
|
+
fill: color-mix(in srgb, var(--aas-role-focus) 22%, var(--aas-panel)) !important;
|
|
745
|
+
stroke: color-mix(in srgb, var(--aas-role-focus) 75%, transparent) !important;
|
|
746
|
+
stroke-width: 1.5px !important;
|
|
747
|
+
}
|
|
748
|
+
.mermaid g.cluster rect {
|
|
749
|
+
rx: 18px;
|
|
750
|
+
ry: 18px;
|
|
751
|
+
/* Default zone colour — a calm blue for any cluster (overrides Mermaid's
|
|
752
|
+
transparent clusterBkg). A subgraph opts into another zone per-diagram via
|
|
753
|
+
`class <id> <zone>`. */
|
|
754
|
+
fill: color-mix(in srgb, var(--aas-diagram-zone) 13%, transparent) !important;
|
|
755
|
+
stroke: color-mix(in srgb, var(--aas-diagram-zone) 42%, transparent) !important;
|
|
756
|
+
stroke-width: 1.5px !important;
|
|
757
|
+
}
|
|
758
|
+
/* Emphasized region — warm amber. Opt in with `class <id> aaszone` (e.g. the
|
|
759
|
+
harness we're describing). */
|
|
760
|
+
.mermaid g.cluster.aaszone rect {
|
|
761
|
+
fill: color-mix(in srgb, var(--aas-diagram-zone-warm) 14%, transparent) !important;
|
|
762
|
+
stroke: color-mix(in srgb, var(--aas-diagram-zone-warm) 48%, transparent) !important;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
|
|
766
|
+
/* Markdown tables — without these, columns collapse together. */
|
|
767
|
+
.prose :where(table) {
|
|
768
|
+
width: 100%;
|
|
769
|
+
border-collapse: collapse;
|
|
770
|
+
margin: 1.25rem 0;
|
|
771
|
+
font-size: 0.92rem;
|
|
772
|
+
display: block;
|
|
773
|
+
overflow-x: auto;
|
|
774
|
+
}
|
|
775
|
+
.prose :where(th, td) {
|
|
776
|
+
border: 1px solid var(--aas-border);
|
|
777
|
+
padding: 0.55rem 0.85rem;
|
|
778
|
+
text-align: left;
|
|
779
|
+
vertical-align: top;
|
|
780
|
+
}
|
|
781
|
+
.prose :where(thead th) {
|
|
782
|
+
background: var(--aas-panel);
|
|
783
|
+
font-weight: 600;
|
|
784
|
+
}
|
|
785
|
+
.prose :where(tbody tr:nth-child(even)) {
|
|
786
|
+
background: color-mix(in srgb, var(--aas-panel) 45%, transparent);
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
/* ── Listing density: gallery (compact mini-cards) ───────────────────────────
|
|
790
|
+
Toggled by [data-view='gallery'] on <html> (persisted in localStorage). A
|
|
791
|
+
denser grid plus a stripped-down card — logo, name, stars, pricing, and a
|
|
792
|
+
short clamped description; the meta row and keyword tags are hidden. */
|
|
793
|
+
:root[data-view='gallery'] [data-grid] {
|
|
794
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
795
|
+
gap: 0.6rem;
|
|
796
|
+
}
|
|
797
|
+
@media (min-width: 640px) {
|
|
798
|
+
:root[data-view='gallery'] [data-grid] {
|
|
799
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
@media (min-width: 1024px) {
|
|
803
|
+
:root[data-view='gallery'] [data-grid] {
|
|
804
|
+
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
/* A taller, refined portrait tile: an enlarged, blurred copy of the logo as an
|
|
808
|
+
ambient backdrop behind the header, then a short description and the stars +
|
|
809
|
+
open-source chip below. */
|
|
810
|
+
:root[data-view='gallery'] [data-tool] {
|
|
811
|
+
flex-direction: column;
|
|
812
|
+
gap: 0;
|
|
813
|
+
padding: 1rem;
|
|
814
|
+
/* radius / overflow / isolation come from the base card (rounded-3xl). */
|
|
815
|
+
}
|
|
816
|
+
:root[data-view='gallery'] [data-card-head] {
|
|
817
|
+
flex-direction: column;
|
|
818
|
+
align-items: flex-start;
|
|
819
|
+
gap: 0.6rem;
|
|
820
|
+
}
|
|
821
|
+
/* Give the name wrapper the full tile width so the h3's `truncate` can ellipsize
|
|
822
|
+
a long title instead of overflowing the card. */
|
|
823
|
+
:root[data-view='gallery'] [data-card-head] > div {
|
|
824
|
+
width: 100%;
|
|
825
|
+
}
|
|
826
|
+
:root[data-view='gallery'] [data-card-head] h3 {
|
|
827
|
+
font-size: 1.0625rem;
|
|
828
|
+
font-weight: 700;
|
|
829
|
+
/* Up to two lines, ellipsised beyond (overrides the single-line truncate).
|
|
830
|
+
The title takes its natural height; the description fills what's left. */
|
|
831
|
+
white-space: normal;
|
|
832
|
+
display: -webkit-box;
|
|
833
|
+
-webkit-line-clamp: 2;
|
|
834
|
+
line-clamp: 2;
|
|
835
|
+
-webkit-box-orient: vertical;
|
|
836
|
+
overflow: hidden;
|
|
837
|
+
line-height: 1.3;
|
|
838
|
+
}
|
|
839
|
+
:root[data-view='gallery'] [data-card-meta],
|
|
840
|
+
:root[data-view='gallery'] [data-card-tags] {
|
|
841
|
+
display: none;
|
|
842
|
+
}
|
|
843
|
+
:root[data-view='gallery'] [data-card-desc] {
|
|
844
|
+
margin-top: 0.55rem;
|
|
845
|
+
/* Up to 3 lines, ellipsised; reserve 3 lines via `lh` so every card is the
|
|
846
|
+
same height. Using `lh` (not a fixed rem) keeps it correct if the font or
|
|
847
|
+
line-height changes — line-clamp always truncates at a line boundary. */
|
|
848
|
+
display: -webkit-box;
|
|
849
|
+
-webkit-line-clamp: 3;
|
|
850
|
+
line-clamp: 3;
|
|
851
|
+
-webkit-box-orient: vertical;
|
|
852
|
+
overflow: hidden;
|
|
853
|
+
font-size: 0.78rem;
|
|
854
|
+
line-height: 1.2rem;
|
|
855
|
+
min-height: 3lh;
|
|
856
|
+
/* Fade via colour, not opacity — opacity would create a stacking context and
|
|
857
|
+
lift the description above the card's full-card link overlay. */
|
|
858
|
+
color: color-mix(in srgb, var(--aas-muted) 78%, transparent);
|
|
859
|
+
}
|
|
860
|
+
/* Footer: stars + open-source chip, just spaced below the content. The chips
|
|
861
|
+
drop their borders for a soft, tinted-pill look in this view. */
|
|
862
|
+
:root[data-view='gallery'] [data-card-foot] {
|
|
863
|
+
flex-direction: row;
|
|
864
|
+
align-items: center;
|
|
865
|
+
margin-top: 0.85rem;
|
|
866
|
+
}
|
|
867
|
+
:root[data-view='gallery'] [data-card-foot] > span {
|
|
868
|
+
border-color: transparent;
|
|
869
|
+
background: color-mix(in srgb, var(--aas-text) 2%, transparent);
|
|
870
|
+
}
|
|
871
|
+
/* The open-source chip becomes an icon, pinned to the right edge; its text label
|
|
872
|
+
(which wraps awkwardly in a narrow tile) is swapped out. */
|
|
873
|
+
.aas-oss-icon {
|
|
874
|
+
display: none;
|
|
875
|
+
}
|
|
876
|
+
:root[data-view='gallery'] [data-card-foot] [data-pricing-tag='open-source'] {
|
|
877
|
+
margin-left: auto;
|
|
878
|
+
display: inline-flex;
|
|
879
|
+
align-items: center;
|
|
880
|
+
}
|
|
881
|
+
:root[data-view='gallery'] [data-card-foot] [data-pricing-tag='open-source'] [data-chip-label] {
|
|
882
|
+
display: none;
|
|
883
|
+
}
|
|
884
|
+
:root[data-view='gallery'] [data-card-foot] [data-pricing-tag='open-source'] .aas-oss-icon {
|
|
885
|
+
display: block;
|
|
886
|
+
color: var(--aas-text); /* match the star glyph, not the accent */
|
|
887
|
+
}
|
|
888
|
+
/* The blurred-logo backdrop. Shown on every card, kept at z-index:-1 (behind the
|
|
889
|
+
static content) so the name's full-card link overlay still covers it — a click
|
|
890
|
+
anywhere on the card navigates. Subtle by default; a touch stronger and taller
|
|
891
|
+
in the gallery view. */
|
|
892
|
+
.aas-gallery-bg {
|
|
893
|
+
position: absolute;
|
|
894
|
+
inset: 0 0 auto 0;
|
|
895
|
+
height: 50%;
|
|
896
|
+
z-index: -1;
|
|
897
|
+
background-position: center 35%;
|
|
898
|
+
background-repeat: no-repeat;
|
|
899
|
+
background-size: cover;
|
|
900
|
+
filter: blur(24px) saturate(1.2);
|
|
901
|
+
transform: scale(1.6);
|
|
902
|
+
opacity: 0.09;
|
|
903
|
+
pointer-events: none;
|
|
904
|
+
-webkit-mask-image: linear-gradient(to bottom, #000 45%, transparent);
|
|
905
|
+
mask-image: linear-gradient(to bottom, #000 45%, transparent);
|
|
906
|
+
animation: aas-bg-drift 22s ease-in-out infinite;
|
|
907
|
+
}
|
|
908
|
+
:root[data-view='gallery'] .aas-gallery-bg {
|
|
909
|
+
height: 60%;
|
|
910
|
+
opacity: 0.15;
|
|
911
|
+
filter: blur(22px) saturate(1.25);
|
|
912
|
+
-webkit-mask-image: linear-gradient(to bottom, #000 50%, transparent);
|
|
913
|
+
mask-image: linear-gradient(to bottom, #000 50%, transparent);
|
|
914
|
+
}
|
|
915
|
+
/* A gentle, slow drift so the backdrop feels alive without distracting. */
|
|
916
|
+
@keyframes aas-bg-drift {
|
|
917
|
+
0%,
|
|
918
|
+
100% {
|
|
919
|
+
transform: scale(1.55) translate(-1.5%, -1%);
|
|
920
|
+
}
|
|
921
|
+
50% {
|
|
922
|
+
transform: scale(1.72) translate(1.5%, 1%);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
/* Stagger neighbouring cards so they don't all drift in lockstep. */
|
|
926
|
+
:root[data-view='gallery'] [data-tool]:nth-child(3n + 2) .aas-gallery-bg {
|
|
927
|
+
animation-delay: -7s;
|
|
928
|
+
}
|
|
929
|
+
:root[data-view='gallery'] [data-tool]:nth-child(3n + 3) .aas-gallery-bg {
|
|
930
|
+
animation-delay: -14s;
|
|
931
|
+
}
|
|
932
|
+
@media (prefers-reduced-motion: reduce) {
|
|
933
|
+
:root[data-view='gallery'] .aas-gallery-bg {
|
|
934
|
+
animation: none;
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
/* Density toggle buttons (standard / gallery). */
|
|
939
|
+
.aas-viewbtn:hover {
|
|
940
|
+
color: var(--aas-text);
|
|
941
|
+
}
|
|
942
|
+
.aas-viewbtn[aria-current='true'] {
|
|
943
|
+
background: var(--aas-tint);
|
|
944
|
+
color: var(--aas-text);
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
/* Gallery: among the pricing chips, keep only the open-source badge. */
|
|
948
|
+
:root[data-view='gallery'] [data-tool] [data-pricing-tag]:not([data-pricing-tag='open-source']) {
|
|
949
|
+
display: none;
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
/* Markdown horizontal rules — a light hairline, not the heavy UA default. */
|
|
953
|
+
.prose :where(hr) {
|
|
954
|
+
border: 0;
|
|
955
|
+
border-top: 1px solid var(--aas-border);
|
|
956
|
+
margin: 1.75rem 0;
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
/* Collapsible <details> used in prose (e.g. "구체적인 예시" reveals). A soft
|
|
960
|
+
panel with a clickable summary; the disclosure marker stays. UI dropdowns
|
|
961
|
+
(.aas-vdd) and the file tree (.aas-tree-dir) — e.g. an article-embedded
|
|
962
|
+
project viewer — carry their own chrome and must not pick this up. */
|
|
963
|
+
.prose :where(details):not(:where(.aas-vdd, .aas-tree-dir)) {
|
|
964
|
+
margin: 0.9rem 0;
|
|
965
|
+
border: 1px solid var(--aas-border);
|
|
966
|
+
border-radius: 0.6rem;
|
|
967
|
+
background: var(--aas-panel);
|
|
968
|
+
padding: 0.1rem 0.95rem;
|
|
969
|
+
}
|
|
970
|
+
.prose :where(summary):not(:where(.aas-vdd, .aas-tree-dir) summary) {
|
|
971
|
+
cursor: pointer;
|
|
972
|
+
padding: 0.55rem 0;
|
|
973
|
+
font-weight: 600;
|
|
974
|
+
color: var(--aas-muted);
|
|
975
|
+
}
|
|
976
|
+
.prose :where(details[open]):not(:where(.aas-vdd, .aas-tree-dir)) {
|
|
977
|
+
padding-bottom: 0.55rem;
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
/* Card-style links rendered inside prose (e.g. a concept's inline <Tools/>
|
|
981
|
+
cards, the project viewer's GitHub button) must not pick up the prose link
|
|
982
|
+
accent color or the underline on hover. */
|
|
983
|
+
.prose a.aas-lift,
|
|
984
|
+
.prose a.aas-lift:hover {
|
|
985
|
+
color: var(--aas-text);
|
|
986
|
+
text-decoration: none;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
/* Collapsible card grids (related tools / related concepts): show the first 6
|
|
990
|
+
cards, hide the rest until the toggle adds [data-expanded]. Keep the 6-item
|
|
991
|
+
cutoff in sync with LIMIT in CollapsibleGrid.astro. */
|
|
992
|
+
[data-collapse-grid]:not([data-expanded]) [data-collapse-items] > *:nth-child(n + 7) {
|
|
993
|
+
display: none;
|
|
994
|
+
}
|
|
995
|
+
[data-collapse-toggle] {
|
|
996
|
+
cursor: pointer;
|
|
997
|
+
}
|
|
998
|
+
[data-collapse-toggle]:hover {
|
|
999
|
+
text-decoration: underline;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
/* Hero card backdrop on the tool detail page: a large, blurred copy of the logo
|
|
1003
|
+
as an ambient tint. Static and subtle (independent of the listing view
|
|
1004
|
+
toggle, unlike .aas-gallery-bg). Sits behind the card content (z-index:-1
|
|
1005
|
+
within the card's `isolate`). */
|
|
1006
|
+
.aas-hero-bg {
|
|
1007
|
+
position: absolute;
|
|
1008
|
+
inset: 0 0 auto 0;
|
|
1009
|
+
height: 60%;
|
|
1010
|
+
z-index: -1;
|
|
1011
|
+
background-position: center 28%;
|
|
1012
|
+
background-repeat: no-repeat;
|
|
1013
|
+
background-size: cover;
|
|
1014
|
+
filter: blur(44px) saturate(1.25);
|
|
1015
|
+
transform: scale(1.6);
|
|
1016
|
+
opacity: 0.1;
|
|
1017
|
+
pointer-events: none;
|
|
1018
|
+
-webkit-mask-image: linear-gradient(to bottom, #000 40%, transparent);
|
|
1019
|
+
mask-image: linear-gradient(to bottom, #000 40%, transparent);
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
/* Avoid a flash of unfiltered catalog: when arriving with a filter/sort in the
|
|
1023
|
+
URL, a pre-paint inline script sets [data-prefilter] on <html>; that hides the
|
|
1024
|
+
controls bar + result grids until FilterControls restores and applies the
|
|
1025
|
+
state, then removes the marker to reveal the final view in one paint. The
|
|
1026
|
+
marker is only ever set by JS, so no-JS users still see the content. */
|
|
1027
|
+
[data-prefilter] [data-controls],
|
|
1028
|
+
[data-prefilter] [data-section] {
|
|
1029
|
+
visibility: hidden;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
/* Tab bar and the sample/project viewer are UI chrome (file tree, selectors,
|
|
1033
|
+
buttons) — keep them gothic even when they sit inside the reading (serif)
|
|
1034
|
+
column. Setting font-family directly on these elements overrides the serif
|
|
1035
|
+
they'd otherwise inherit from the surrounding .aas-reading wrapper. */
|
|
1036
|
+
[role='tablist'],
|
|
1037
|
+
[data-projects] {
|
|
1038
|
+
font-family: var(--aas-sans);
|
|
1039
|
+
}
|
|
1040
|
+
/* …but the README *body* inside the viewer is running prose, not chrome, so in a
|
|
1041
|
+
reading column give it the same serif as the article body. Its headings and
|
|
1042
|
+
code keep the .aas-reading sans/mono rules — only the inherited gothic from
|
|
1043
|
+
[data-projects] is undone for this text. */
|
|
1044
|
+
.aas-reading [data-readme-body] {
|
|
1045
|
+
font-family: 'MaruBuri', ui-serif, Georgia, serif;
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
/* ==========================================================================
|
|
1049
|
+
Slides / decks
|
|
1050
|
+
Native presentation decks rendered at /slides/<name>/. A deck is a horizontal
|
|
1051
|
+
scroll-snap track of full-viewport <section.aas-slide> panels (one per
|
|
1052
|
+
<Slide> in the deck MDX). Content is plain MDX, so it reuses Shiki code
|
|
1053
|
+
highlighting, the Mermaid loader, and the site's --aas-* theme (light/dark).
|
|
1054
|
+
========================================================================== */
|
|
1055
|
+
.aas-deck-body {
|
|
1056
|
+
margin: 0;
|
|
1057
|
+
overflow: hidden;
|
|
1058
|
+
background: var(--aas-bg);
|
|
1059
|
+
color: var(--aas-text);
|
|
1060
|
+
font-family: var(--aas-sans);
|
|
1061
|
+
/* Content aspect ratio (width tracks ratio × height). Set via data-aspect. */
|
|
1062
|
+
--aas-ratio: 1.7778; /* 16:9 */
|
|
1063
|
+
}
|
|
1064
|
+
.aas-deck-body[data-aspect='16:10'] {
|
|
1065
|
+
--aas-ratio: 1.6;
|
|
1066
|
+
}
|
|
1067
|
+
.aas-deck-body[data-aspect='4:3'] {
|
|
1068
|
+
--aas-ratio: 1.3333;
|
|
1069
|
+
}
|
|
1070
|
+
.aas-deck-body[data-aspect='fill'] {
|
|
1071
|
+
--aas-ratio: 999;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
.aas-deck {
|
|
1075
|
+
position: fixed;
|
|
1076
|
+
inset: 0;
|
|
1077
|
+
display: flex;
|
|
1078
|
+
overflow-x: auto;
|
|
1079
|
+
overflow-y: hidden;
|
|
1080
|
+
scroll-snap-type: x mandatory;
|
|
1081
|
+
/* Programmatic slide changes are tweened in JS (DeckView), which sets
|
|
1082
|
+
scrollLeft directly; keep scroll-behavior auto so it isn't double-animated.
|
|
1083
|
+
The `transition` / reduced-motion signals are honored there too. */
|
|
1084
|
+
scroll-behavior: auto;
|
|
1085
|
+
scrollbar-width: none; /* the counter + progress bar are the position cue */
|
|
1086
|
+
}
|
|
1087
|
+
.aas-deck::-webkit-scrollbar {
|
|
1088
|
+
display: none;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
.aas-slide {
|
|
1092
|
+
position: relative; /* anchor the bottom-right source line */
|
|
1093
|
+
flex: 0 0 100%;
|
|
1094
|
+
width: 100vw;
|
|
1095
|
+
height: 100dvh;
|
|
1096
|
+
scroll-snap-align: center;
|
|
1097
|
+
scroll-snap-stop: always;
|
|
1098
|
+
display: flex;
|
|
1099
|
+
/* Pin content to the top so every slide's title sits at the same height (like
|
|
1100
|
+
real slides). Cover / center slides opt back into vertical centering. */
|
|
1101
|
+
align-items: flex-start;
|
|
1102
|
+
justify-content: center;
|
|
1103
|
+
padding: clamp(2.5rem, 8vh, 6rem) clamp(1.5rem, 4vw, 4rem);
|
|
1104
|
+
overflow-y: auto; /* a slide taller than the viewport scrolls internally */
|
|
1105
|
+
}
|
|
1106
|
+
.aas-slide.cover,
|
|
1107
|
+
.aas-slide.center,
|
|
1108
|
+
.aas-slide.quote {
|
|
1109
|
+
align-items: center;
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
.aas-slide-inner {
|
|
1113
|
+
width: 100%;
|
|
1114
|
+
/* Content width tracks the deck's aspect ratio (× height): 16:9/16:10/4:3 give
|
|
1115
|
+
a proportioned, wider column; 'fill' (--aas-ratio 999) uses the full width. */
|
|
1116
|
+
max-width: min(96rem, calc((100dvh - 11vh) * var(--aas-ratio, 1.7778)));
|
|
1117
|
+
margin: 0 auto;
|
|
1118
|
+
/* Wrap Korean/CJK at spaces (word boundaries), not mid-word. */
|
|
1119
|
+
word-break: keep-all;
|
|
1120
|
+
overflow-wrap: break-word;
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
/* Cover / closing slides: centered, roomier. Add class="cover" on the <Slide>. */
|
|
1124
|
+
.aas-slide.cover .aas-slide-inner,
|
|
1125
|
+
.aas-slide.center .aas-slide-inner {
|
|
1126
|
+
text-align: center;
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
/* --- Slide typography (styles the plain MDX inside a slide) --------------- */
|
|
1130
|
+
/* The site adds a "#" copy-link anchor to headings; it's noise in a deck. */
|
|
1131
|
+
.aas-slide-inner .aas-anchor {
|
|
1132
|
+
display: none;
|
|
1133
|
+
}
|
|
1134
|
+
.aas-slide-inner > :first-child {
|
|
1135
|
+
margin-top: 0;
|
|
1136
|
+
}
|
|
1137
|
+
.aas-slide-inner > :last-child {
|
|
1138
|
+
margin-bottom: 0;
|
|
1139
|
+
}
|
|
1140
|
+
.aas-slide-inner h1 {
|
|
1141
|
+
font-size: clamp(2rem, 5.5vw, 3.75rem);
|
|
1142
|
+
font-weight: 800;
|
|
1143
|
+
line-height: 1.1;
|
|
1144
|
+
letter-spacing: -0.02em;
|
|
1145
|
+
margin: 0 0 0.6em;
|
|
1146
|
+
}
|
|
1147
|
+
.aas-slide-inner h2 {
|
|
1148
|
+
font-size: clamp(1.9rem, 4.2vw, 3rem);
|
|
1149
|
+
font-weight: 700;
|
|
1150
|
+
line-height: 1.15;
|
|
1151
|
+
letter-spacing: -0.015em;
|
|
1152
|
+
margin: 0 0 0.7em;
|
|
1153
|
+
color: var(--aas-accent);
|
|
1154
|
+
}
|
|
1155
|
+
/* A slide's leading heading is its title — style ### / #### the same as ## when
|
|
1156
|
+
it opens the slide, so heading levels can express deck/TOC hierarchy without
|
|
1157
|
+
shrinking the on-slide title. (Nested ### inside :::cols keep their small size.) */
|
|
1158
|
+
.aas-slide-inner > h3:first-child,
|
|
1159
|
+
.aas-slide-inner > h4:first-child {
|
|
1160
|
+
font-size: clamp(1.9rem, 4.2vw, 3rem);
|
|
1161
|
+
font-weight: 700;
|
|
1162
|
+
line-height: 1.15;
|
|
1163
|
+
letter-spacing: -0.015em;
|
|
1164
|
+
margin: 0 0 0.7em;
|
|
1165
|
+
color: var(--aas-accent);
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
/* Subtitle (`::sub[…]`): a small, muted line tucked under the slide title. */
|
|
1169
|
+
.aas-slide-inner .aas-subtitle {
|
|
1170
|
+
margin: -0.3em 0 0.9em;
|
|
1171
|
+
font-size: clamp(1.1rem, 2vw, 1.55rem);
|
|
1172
|
+
font-weight: 400;
|
|
1173
|
+
line-height: 1.4;
|
|
1174
|
+
color: var(--aas-muted);
|
|
1175
|
+
}
|
|
1176
|
+
.aas-slide.cover .aas-subtitle,
|
|
1177
|
+
.aas-slide.center .aas-subtitle {
|
|
1178
|
+
margin-top: -0.2em;
|
|
1179
|
+
}
|
|
1180
|
+
.aas-slide-inner h3 {
|
|
1181
|
+
font-size: clamp(1.3rem, 2.5vw, 1.85rem);
|
|
1182
|
+
font-weight: 700;
|
|
1183
|
+
margin: 1.2em 0 0.4em;
|
|
1184
|
+
}
|
|
1185
|
+
.aas-slide-inner p,
|
|
1186
|
+
.aas-slide-inner li {
|
|
1187
|
+
font-size: clamp(1.2rem, 2vw, 1.65rem);
|
|
1188
|
+
line-height: 1.55;
|
|
1189
|
+
}
|
|
1190
|
+
.aas-slide-inner p {
|
|
1191
|
+
margin: 0 0 0.7em;
|
|
1192
|
+
color: var(--aas-text);
|
|
1193
|
+
}
|
|
1194
|
+
.aas-slide-inner strong {
|
|
1195
|
+
font-weight: 700;
|
|
1196
|
+
}
|
|
1197
|
+
.aas-slide-inner em {
|
|
1198
|
+
color: var(--aas-muted);
|
|
1199
|
+
font-style: normal;
|
|
1200
|
+
}
|
|
1201
|
+
/* Restore list markers (the site's CSS reset strips them). */
|
|
1202
|
+
.aas-slide-inner ul,
|
|
1203
|
+
.aas-slide-inner ol {
|
|
1204
|
+
margin: 0.4em 0 0.8em;
|
|
1205
|
+
padding-left: 1.5em;
|
|
1206
|
+
}
|
|
1207
|
+
.aas-slide-inner ul {
|
|
1208
|
+
list-style: disc;
|
|
1209
|
+
}
|
|
1210
|
+
.aas-slide-inner ul ul {
|
|
1211
|
+
list-style: circle;
|
|
1212
|
+
}
|
|
1213
|
+
.aas-slide-inner ol {
|
|
1214
|
+
list-style: decimal;
|
|
1215
|
+
}
|
|
1216
|
+
.aas-slide-inner ol ol {
|
|
1217
|
+
list-style: lower-alpha;
|
|
1218
|
+
}
|
|
1219
|
+
.aas-slide-inner li {
|
|
1220
|
+
margin: 0.35em 0;
|
|
1221
|
+
padding-left: 0.2em;
|
|
1222
|
+
}
|
|
1223
|
+
.aas-slide-inner li::marker {
|
|
1224
|
+
color: var(--aas-accent);
|
|
1225
|
+
}
|
|
1226
|
+
.aas-slide-inner a {
|
|
1227
|
+
color: var(--aas-accent);
|
|
1228
|
+
}
|
|
1229
|
+
.aas-slide-inner hr {
|
|
1230
|
+
border: none;
|
|
1231
|
+
border-top: 1px solid var(--aas-border);
|
|
1232
|
+
margin: 1.2em 0;
|
|
1233
|
+
}
|
|
1234
|
+
/* Cover title: bigger, muted subtitle */
|
|
1235
|
+
.aas-slide.cover h1 {
|
|
1236
|
+
font-size: clamp(2.5rem, 8vw, 5.5rem);
|
|
1237
|
+
}
|
|
1238
|
+
.aas-slide.cover p {
|
|
1239
|
+
font-size: clamp(1.1rem, 2.4vw, 1.7rem);
|
|
1240
|
+
color: var(--aas-muted);
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
/* Tables */
|
|
1244
|
+
.aas-slide-inner table {
|
|
1245
|
+
width: 100%;
|
|
1246
|
+
border-collapse: collapse;
|
|
1247
|
+
font-size: clamp(0.9rem, 1.5vw, 1.25rem);
|
|
1248
|
+
margin: 0.5em 0;
|
|
1249
|
+
}
|
|
1250
|
+
.aas-slide-inner th,
|
|
1251
|
+
.aas-slide-inner td {
|
|
1252
|
+
text-align: left;
|
|
1253
|
+
padding: 0.5em 0.9em;
|
|
1254
|
+
border-bottom: 1px solid var(--aas-border);
|
|
1255
|
+
vertical-align: top;
|
|
1256
|
+
}
|
|
1257
|
+
.aas-slide-inner th {
|
|
1258
|
+
font-weight: 700;
|
|
1259
|
+
color: var(--aas-muted);
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
/* Code (Shiki) + Mermaid inside slides */
|
|
1263
|
+
.aas-slide-inner pre {
|
|
1264
|
+
border-radius: 0.9rem;
|
|
1265
|
+
padding: 1.1em 1.3em;
|
|
1266
|
+
overflow: auto;
|
|
1267
|
+
font-size: clamp(0.95rem, 1.5vw, 1.3rem);
|
|
1268
|
+
max-height: 62vh;
|
|
1269
|
+
}
|
|
1270
|
+
/* Code in a proper monospace stack (a visual theme may override --aas-code-font). */
|
|
1271
|
+
.aas-slide-inner pre:not(.mermaid),
|
|
1272
|
+
.aas-slide-inner pre:not(.mermaid) code,
|
|
1273
|
+
.aas-slide-inner :not(pre) > code {
|
|
1274
|
+
font-family: var(
|
|
1275
|
+
--aas-code-font,
|
|
1276
|
+
ui-monospace,
|
|
1277
|
+
'SF Mono',
|
|
1278
|
+
'JetBrains Mono',
|
|
1279
|
+
'Cascadia Code',
|
|
1280
|
+
'Fira Code',
|
|
1281
|
+
Menlo,
|
|
1282
|
+
Consolas,
|
|
1283
|
+
monospace
|
|
1284
|
+
);
|
|
1285
|
+
}
|
|
1286
|
+
.aas-slide-inner :not(pre) > code {
|
|
1287
|
+
font-size: 0.9em;
|
|
1288
|
+
padding: 0.1em 0.35em;
|
|
1289
|
+
border-radius: 0.35rem;
|
|
1290
|
+
background: var(--aas-tint);
|
|
1291
|
+
}
|
|
1292
|
+
/* Language badge on code blocks (Shiki sets data-language). The code box is
|
|
1293
|
+
always dark, so a light, quiet label reads on any site theme. */
|
|
1294
|
+
.aas-slide-inner pre.astro-code {
|
|
1295
|
+
position: relative;
|
|
1296
|
+
}
|
|
1297
|
+
.aas-slide-inner pre.astro-code[data-language]::before {
|
|
1298
|
+
content: attr(data-language);
|
|
1299
|
+
position: absolute;
|
|
1300
|
+
top: 0;
|
|
1301
|
+
right: 0;
|
|
1302
|
+
padding: 0.3em 0.7em;
|
|
1303
|
+
font-family: var(--aas-code-font, ui-monospace, monospace);
|
|
1304
|
+
font-size: 0.72em;
|
|
1305
|
+
letter-spacing: 0.04em;
|
|
1306
|
+
text-transform: uppercase;
|
|
1307
|
+
color: rgba(255, 255, 255, 0.45);
|
|
1308
|
+
pointer-events: none;
|
|
1309
|
+
}
|
|
1310
|
+
.aas-slide-inner pre.mermaid {
|
|
1311
|
+
background: transparent;
|
|
1312
|
+
padding: 0;
|
|
1313
|
+
display: flex;
|
|
1314
|
+
justify-content: center;
|
|
1315
|
+
}
|
|
1316
|
+
.aas-slide-inner pre.mermaid svg {
|
|
1317
|
+
/* Mermaid ships each svg with width="100%" + an inline max-width equal to the
|
|
1318
|
+
diagram's natural width. Respect that (no !important) so it renders at its
|
|
1319
|
+
true size — capped to the container by width:100%, never blown up past its
|
|
1320
|
+
natural size. Forcing max-width here would upscale a small diagram (e.g. a
|
|
1321
|
+
narrow vertical flowchart) to fill the column and balloon the labels. */
|
|
1322
|
+
max-width: 100%;
|
|
1323
|
+
max-height: 52vh;
|
|
1324
|
+
height: auto;
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
/* Multi-column helper: <div class="cols"> in a slide splits into columns. */
|
|
1328
|
+
.aas-slide-inner .cols {
|
|
1329
|
+
display: grid;
|
|
1330
|
+
grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
|
|
1331
|
+
gap: clamp(1rem, 3vw, 2.5rem);
|
|
1332
|
+
text-align: left;
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
/* --- Images in slides ---------------------------------------------------- */
|
|
1336
|
+
/* Full-bleed background (<Slide bg={img}>): cover-fit image + a dark scrim so
|
|
1337
|
+
the centered text stays legible on any photo. */
|
|
1338
|
+
.aas-slide.has-bg {
|
|
1339
|
+
position: relative;
|
|
1340
|
+
background-size: cover;
|
|
1341
|
+
background-position: center;
|
|
1342
|
+
}
|
|
1343
|
+
.aas-slide.has-bg::before {
|
|
1344
|
+
content: '';
|
|
1345
|
+
position: absolute;
|
|
1346
|
+
inset: 0;
|
|
1347
|
+
background: rgba(0, 0, 0, 0.45);
|
|
1348
|
+
}
|
|
1349
|
+
.aas-slide.has-bg .aas-slide-inner {
|
|
1350
|
+
position: relative;
|
|
1351
|
+
z-index: 1;
|
|
1352
|
+
}
|
|
1353
|
+
.aas-slide.has-bg .aas-slide-inner,
|
|
1354
|
+
.aas-slide.has-bg h1,
|
|
1355
|
+
.aas-slide.has-bg h2,
|
|
1356
|
+
.aas-slide.has-bg h3,
|
|
1357
|
+
.aas-slide.has-bg p {
|
|
1358
|
+
color: #fff;
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
/* Media on top, text below. For an image, add class="aas-media-top"; a diagram
|
|
1362
|
+
or code block just stacks above the text on its own (no class needed). */
|
|
1363
|
+
.aas-slide-inner .aas-media-top {
|
|
1364
|
+
display: block;
|
|
1365
|
+
width: 100%;
|
|
1366
|
+
max-height: 55vh;
|
|
1367
|
+
object-fit: cover;
|
|
1368
|
+
border-radius: 0.9rem;
|
|
1369
|
+
margin: 0 0 1rem;
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
/* Media + text side by side. The media child can be an image, a diagram
|
|
1373
|
+
(`pre.mermaid`), or a code block (`pre`). Order the media and the text block
|
|
1374
|
+
as you want them to appear; pick the split ratio with a modifier class. */
|
|
1375
|
+
.aas-slide-inner .aas-split {
|
|
1376
|
+
display: grid;
|
|
1377
|
+
grid-template-columns: 1fr 1fr; /* r-50-50 (default) */
|
|
1378
|
+
gap: clamp(1rem, 3vw, 2.5rem);
|
|
1379
|
+
align-items: center;
|
|
1380
|
+
text-align: left;
|
|
1381
|
+
}
|
|
1382
|
+
/* Let code / diagrams shrink to their column instead of blowing the grid out
|
|
1383
|
+
(a <pre> with long lines otherwise refuses to go below its content width). */
|
|
1384
|
+
.aas-slide-inner .aas-split > * {
|
|
1385
|
+
min-width: 0;
|
|
1386
|
+
}
|
|
1387
|
+
.aas-slide-inner .aas-split.r-30-70 {
|
|
1388
|
+
grid-template-columns: 3fr 7fr;
|
|
1389
|
+
}
|
|
1390
|
+
.aas-slide-inner .aas-split.r-70-30 {
|
|
1391
|
+
grid-template-columns: 7fr 3fr;
|
|
1392
|
+
}
|
|
1393
|
+
/* Image media. */
|
|
1394
|
+
.aas-slide-inner .aas-split img {
|
|
1395
|
+
width: 100%;
|
|
1396
|
+
max-height: 46vh;
|
|
1397
|
+
object-fit: cover;
|
|
1398
|
+
border-radius: 0.9rem;
|
|
1399
|
+
}
|
|
1400
|
+
/* Code / diagram media: drop the outer margin and cap the height so the column
|
|
1401
|
+
stays inside the slide (code scrolls; the diagram scales down). */
|
|
1402
|
+
.aas-slide-inner .aas-split > pre {
|
|
1403
|
+
width: 100%;
|
|
1404
|
+
margin: 0;
|
|
1405
|
+
max-height: 56vh;
|
|
1406
|
+
}
|
|
1407
|
+
.aas-slide-inner .aas-split > pre:not(.mermaid) {
|
|
1408
|
+
font-size: clamp(0.85rem, 1.2vw, 1.15rem);
|
|
1409
|
+
}
|
|
1410
|
+
/* Text column of a split stays top-aligned (the media may center/stretch, but
|
|
1411
|
+
the prose reads from the top) — for image, diagram, and code splits alike. */
|
|
1412
|
+
.aas-slide-inner .aas-split > div:not(.aas-diagram) {
|
|
1413
|
+
align-self: start;
|
|
1414
|
+
}
|
|
1415
|
+
/* Media vertical alignment within the split (default: centered). Pair with
|
|
1416
|
+
`tall` (below) so top / center / bottom are measured against a full-height
|
|
1417
|
+
slide, not just the text column. Works for images, diagrams, and code.
|
|
1418
|
+
(Images get wrapped in .aas-zoomable-img at runtime, so target that too.) */
|
|
1419
|
+
.aas-slide-inner .aas-split.img-top > :is(img, .aas-zoomable-img, pre) {
|
|
1420
|
+
align-self: start;
|
|
1421
|
+
}
|
|
1422
|
+
.aas-slide-inner .aas-split.img-center > :is(img, .aas-zoomable-img, pre) {
|
|
1423
|
+
align-self: center;
|
|
1424
|
+
}
|
|
1425
|
+
.aas-slide-inner .aas-split.img-bottom > :is(img, .aas-zoomable-img, pre) {
|
|
1426
|
+
align-self: end;
|
|
1427
|
+
}
|
|
1428
|
+
/* Tall: the split fills the slide vertically, so image alignment is relative to
|
|
1429
|
+
a vertically-filled slide (this is what "center" means). */
|
|
1430
|
+
.aas-slide-inner .aas-split.tall {
|
|
1431
|
+
min-height: min(66vh, 42rem);
|
|
1432
|
+
}
|
|
1433
|
+
/* Fill mode: a tall image cropped to `cover`, filling the slide vertically.
|
|
1434
|
+
Add `fill` to the split. */
|
|
1435
|
+
.aas-slide-inner .aas-split.fill > :is(img, .aas-zoomable-img) {
|
|
1436
|
+
height: min(64vh, 42rem);
|
|
1437
|
+
max-height: min(64vh, 42rem);
|
|
1438
|
+
align-self: stretch;
|
|
1439
|
+
}
|
|
1440
|
+
.aas-slide-inner .aas-split.fill .aas-zoomable-img img {
|
|
1441
|
+
height: 100%;
|
|
1442
|
+
max-height: none;
|
|
1443
|
+
}
|
|
1444
|
+
.aas-slide-inner .aas-split > div > :first-child {
|
|
1445
|
+
margin-top: 0;
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
/* --- Code / diagram slides fill the slide vertically --------------------- */
|
|
1449
|
+
/* A diagram (wrapped in .aas-diagram) or code block (a bare <pre>) — in a split
|
|
1450
|
+
or stacked on its own — grows to fill the slide height instead of being
|
|
1451
|
+
stranded at the top. Diagrams center in the filled box; code stays pinned to
|
|
1452
|
+
the top. Images are untouched (they keep their own `tall` / `fill` above). */
|
|
1453
|
+
|
|
1454
|
+
/* 1) The slide body becomes a full-height column whenever it holds a diagram or
|
|
1455
|
+
code block (directly, or as one side of a split — but not an image split).
|
|
1456
|
+
A slide marked `compact` opts out: the media keeps its natural size (padded)
|
|
1457
|
+
and the text flows normally, leaving room for longer copy. */
|
|
1458
|
+
.aas-slide:not(.compact) .aas-slide-inner:has(> .aas-diagram),
|
|
1459
|
+
.aas-slide:not(.compact) .aas-slide-inner:has(> pre),
|
|
1460
|
+
.aas-slide:not(.compact) .aas-slide-inner:has(> .aas-split:not(.scroll) > .aas-diagram),
|
|
1461
|
+
.aas-slide:not(.compact) .aas-slide-inner:has(> .aas-split:not(.scroll) > pre) {
|
|
1462
|
+
display: flex;
|
|
1463
|
+
flex-direction: column;
|
|
1464
|
+
min-height: 100%;
|
|
1465
|
+
}
|
|
1466
|
+
/* 2) The media region (a standalone diagram/pre, or the split holding one) takes
|
|
1467
|
+
the leftover height; drop the height cap so flex-grow can actually fill. */
|
|
1468
|
+
.aas-slide:not(.compact) .aas-slide-inner > .aas-diagram,
|
|
1469
|
+
.aas-slide:not(.compact) .aas-slide-inner > pre,
|
|
1470
|
+
.aas-slide:not(.compact) .aas-slide-inner > .aas-split:not(.scroll):has(> .aas-diagram),
|
|
1471
|
+
.aas-slide:not(.compact) .aas-slide-inner > .aas-split:not(.scroll):has(> pre) {
|
|
1472
|
+
flex: 1 1 auto;
|
|
1473
|
+
min-height: 0;
|
|
1474
|
+
}
|
|
1475
|
+
.aas-slide:not(.compact) .aas-slide-inner > pre {
|
|
1476
|
+
max-height: none;
|
|
1477
|
+
}
|
|
1478
|
+
/* 3) In a split, the media cell stretches to the full height (the box fills);
|
|
1479
|
+
the text column stays vertically centered (.aas-split align-items: center). */
|
|
1480
|
+
.aas-slide:not(.compact) .aas-slide-inner > .aas-split:not(.scroll):has(> .aas-diagram) > .aas-diagram,
|
|
1481
|
+
.aas-slide:not(.compact) .aas-slide-inner > .aas-split:not(.scroll):has(> pre) > pre {
|
|
1482
|
+
align-self: stretch;
|
|
1483
|
+
height: 100%;
|
|
1484
|
+
}
|
|
1485
|
+
.aas-slide:not(.compact) .aas-slide-inner > .aas-split:not(.scroll):has(> pre) > pre {
|
|
1486
|
+
max-height: none;
|
|
1487
|
+
}
|
|
1488
|
+
/* 3a) Diagram: the bordered box becomes a centering column, so the rendered
|
|
1489
|
+
diagram sits in the vertical middle of the filled box. (The diagram keeps
|
|
1490
|
+
its natural size — see the svg rule, which no longer forces width:auto —
|
|
1491
|
+
so filling the box no longer balloons the labels.) */
|
|
1492
|
+
.aas-slide-inner .aas-diagram {
|
|
1493
|
+
display: flex;
|
|
1494
|
+
flex-direction: column;
|
|
1495
|
+
justify-content: center;
|
|
1496
|
+
}
|
|
1497
|
+
/* 3b) Code stays pinned to the top of its filled box — that's the default block
|
|
1498
|
+
flow of a tall <pre>, so nothing extra is needed. */
|
|
1499
|
+
|
|
1500
|
+
/* Scrollable diagram (`<div class="aas-split scroll">`): the diagram column is a
|
|
1501
|
+
fixed-height scroll box (opted out of the fill rules above) and the diagram
|
|
1502
|
+
fits the column width, so a tall/complex flowchart scrolls vertically next to
|
|
1503
|
+
its explanation instead of shrinking to fit. Click the diagram to enlarge. */
|
|
1504
|
+
.aas-slide-inner .aas-split.scroll > .aas-diagram {
|
|
1505
|
+
display: block;
|
|
1506
|
+
align-self: start;
|
|
1507
|
+
height: min(64vh, 34rem);
|
|
1508
|
+
overflow: auto;
|
|
1509
|
+
overscroll-behavior: contain;
|
|
1510
|
+
}
|
|
1511
|
+
/* The inner <pre.mermaid> otherwise caps itself at 62vh and scrolls on its own,
|
|
1512
|
+
creating a nested scroll box; unclamp it so .aas-diagram is the sole scroller. */
|
|
1513
|
+
.aas-slide-inner .aas-split.scroll > .aas-diagram .mermaid {
|
|
1514
|
+
display: block;
|
|
1515
|
+
max-height: none;
|
|
1516
|
+
overflow: visible;
|
|
1517
|
+
}
|
|
1518
|
+
.aas-slide-inner .aas-split.scroll > .aas-diagram svg {
|
|
1519
|
+
width: 100%;
|
|
1520
|
+
max-width: 100%;
|
|
1521
|
+
max-height: none;
|
|
1522
|
+
height: auto;
|
|
1523
|
+
}
|
|
1524
|
+
/* Code in a scroll split: a fixed-height scroll box (opted out of the fill
|
|
1525
|
+
rules), so a long listing scrolls next to its walkthrough steps. */
|
|
1526
|
+
.aas-slide-inner .aas-split.scroll > pre {
|
|
1527
|
+
align-self: start;
|
|
1528
|
+
height: min(60vh, 30rem);
|
|
1529
|
+
max-height: min(60vh, 30rem);
|
|
1530
|
+
overflow: auto;
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
/* Horizontally-scrolling diagram (`<Slide class="scroll-x">`, usually paired with
|
|
1534
|
+
`compact`): a wide flowchart keeps its natural width and the box scrolls
|
|
1535
|
+
sideways instead of squeezing every node to fit. */
|
|
1536
|
+
.aas-slide.scroll-x .aas-slide-inner .aas-diagram {
|
|
1537
|
+
display: block;
|
|
1538
|
+
overflow-x: auto;
|
|
1539
|
+
overflow-y: hidden;
|
|
1540
|
+
overscroll-behavior-x: contain;
|
|
1541
|
+
}
|
|
1542
|
+
.aas-slide.scroll-x .aas-slide-inner .aas-diagram .mermaid {
|
|
1543
|
+
display: block;
|
|
1544
|
+
max-height: none;
|
|
1545
|
+
overflow: visible;
|
|
1546
|
+
}
|
|
1547
|
+
.aas-slide.scroll-x .aas-slide-inner .aas-diagram svg {
|
|
1548
|
+
/* Mermaid keeps an inline `max-width: <natural>px`; a huge width is clamped by
|
|
1549
|
+
it to the diagram's natural width, so a wide flowchart overflows and scrolls
|
|
1550
|
+
(max-content mis-resolves to the container width here). */
|
|
1551
|
+
width: 99999px;
|
|
1552
|
+
max-height: none;
|
|
1553
|
+
height: auto;
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
/* Generic scroll box (`<div class="aas-scrollbox">`): a bounded, scrollable frame
|
|
1557
|
+
for any media — used for the image walkthrough, where a full-width image is
|
|
1558
|
+
taller than the box and scrolls vertically. */
|
|
1559
|
+
.aas-slide-inner .aas-scrollbox {
|
|
1560
|
+
max-height: min(46vh, 22rem);
|
|
1561
|
+
overflow: auto;
|
|
1562
|
+
overscroll-behavior: contain;
|
|
1563
|
+
border: 1px solid var(--aas-border);
|
|
1564
|
+
border-radius: 0.9rem;
|
|
1565
|
+
margin: 0.3rem 0 1rem;
|
|
1566
|
+
}
|
|
1567
|
+
.aas-slide-inner .aas-scrollbox img {
|
|
1568
|
+
display: block;
|
|
1569
|
+
width: 100%;
|
|
1570
|
+
height: auto;
|
|
1571
|
+
max-height: none;
|
|
1572
|
+
border-radius: 0.9rem;
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
/* Code walkthrough line highlight: the active step's rows get a full-width band
|
|
1576
|
+
(whole line, not just coloured text) and the others dim, so the eye lands on
|
|
1577
|
+
the lines being explained. The code box is always dark (github theme). */
|
|
1578
|
+
.aas-slide-inner pre.astro-code .line {
|
|
1579
|
+
transition:
|
|
1580
|
+
opacity 0.25s ease,
|
|
1581
|
+
background 0.2s ease;
|
|
1582
|
+
}
|
|
1583
|
+
.aas-slide-inner pre.astro-code .line.is-line-hl {
|
|
1584
|
+
display: inline-block;
|
|
1585
|
+
width: 100%;
|
|
1586
|
+
background: color-mix(in srgb, var(--aas-accent) 34%, transparent);
|
|
1587
|
+
box-shadow: inset 3px 0 0 var(--aas-accent);
|
|
1588
|
+
}
|
|
1589
|
+
.aas-slide-inner pre.astro-code.has-hl .line:not(.is-line-hl) {
|
|
1590
|
+
opacity: 0.4;
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1593
|
+
/* --- Per-slide source / citation (bottom-right, ≤2 lines) ---------------- */
|
|
1594
|
+
.aas-slide-source {
|
|
1595
|
+
position: absolute;
|
|
1596
|
+
right: clamp(1.5rem, 4vw, 4rem);
|
|
1597
|
+
bottom: clamp(0.9rem, 3vh, 2rem);
|
|
1598
|
+
max-width: min(46%, 30rem);
|
|
1599
|
+
margin: 0;
|
|
1600
|
+
text-align: right;
|
|
1601
|
+
font-size: clamp(0.68rem, 0.95vw, 0.82rem);
|
|
1602
|
+
line-height: 1.35;
|
|
1603
|
+
color: var(--aas-muted);
|
|
1604
|
+
opacity: 0.8;
|
|
1605
|
+
display: -webkit-box;
|
|
1606
|
+
-webkit-line-clamp: 2;
|
|
1607
|
+
-webkit-box-orient: vertical;
|
|
1608
|
+
overflow: hidden;
|
|
1609
|
+
pointer-events: none;
|
|
1610
|
+
}
|
|
1611
|
+
.aas-slide.has-bg .aas-slide-source {
|
|
1612
|
+
color: rgba(255, 255, 255, 0.82);
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
/* --- Zoom / lightbox: enlarge a diagram or image ------------------------- */
|
|
1616
|
+
/* The media becomes clickable; a small button sits in its top-right corner. */
|
|
1617
|
+
.aas-slide-inner .aas-zoomable {
|
|
1618
|
+
position: relative;
|
|
1619
|
+
cursor: zoom-in;
|
|
1620
|
+
}
|
|
1621
|
+
.aas-slide-inner .aas-zoomable-img {
|
|
1622
|
+
display: block;
|
|
1623
|
+
min-width: 0;
|
|
1624
|
+
}
|
|
1625
|
+
.aas-zoom-btn {
|
|
1626
|
+
position: absolute;
|
|
1627
|
+
top: 0.5rem;
|
|
1628
|
+
right: 0.5rem;
|
|
1629
|
+
z-index: 2;
|
|
1630
|
+
display: flex;
|
|
1631
|
+
align-items: center;
|
|
1632
|
+
justify-content: center;
|
|
1633
|
+
width: 2rem;
|
|
1634
|
+
height: 2rem;
|
|
1635
|
+
padding: 0;
|
|
1636
|
+
border: 1px solid var(--aas-border);
|
|
1637
|
+
border-radius: 0.55rem;
|
|
1638
|
+
background: color-mix(in srgb, var(--aas-panel) 82%, transparent);
|
|
1639
|
+
color: var(--aas-text);
|
|
1640
|
+
cursor: zoom-in;
|
|
1641
|
+
opacity: 0;
|
|
1642
|
+
transition: opacity 0.15s ease;
|
|
1643
|
+
}
|
|
1644
|
+
.aas-zoomable:hover .aas-zoom-btn,
|
|
1645
|
+
.aas-zoom-btn:focus-visible {
|
|
1646
|
+
opacity: 0.9;
|
|
1647
|
+
}
|
|
1648
|
+
.aas-zoom-btn:hover {
|
|
1649
|
+
opacity: 1;
|
|
1650
|
+
}
|
|
1651
|
+
/* The zoom button is a UI affordance — never in print/PDF. */
|
|
1652
|
+
@media print {
|
|
1653
|
+
.aas-zoom-btn {
|
|
1654
|
+
display: none;
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
/* Overlay. A dark scrim (regardless of site theme) so the enlarged media pops. */
|
|
1658
|
+
.aas-zoom {
|
|
1659
|
+
position: fixed;
|
|
1660
|
+
inset: 0;
|
|
1661
|
+
z-index: 50;
|
|
1662
|
+
display: flex;
|
|
1663
|
+
align-items: center;
|
|
1664
|
+
justify-content: center;
|
|
1665
|
+
padding: clamp(1.5rem, 5vh, 4rem);
|
|
1666
|
+
/* Match the deck: light backdrop in light mode, dark in dark mode (a diagram's
|
|
1667
|
+
pastel nodes read the same as they do on the slide). Opaque so the slide
|
|
1668
|
+
behind — its own diagram/text — doesn't ghost through under the enlarged one. */
|
|
1669
|
+
background: var(--aas-bg);
|
|
1670
|
+
opacity: 0;
|
|
1671
|
+
transition: opacity 0.2s ease;
|
|
1672
|
+
cursor: zoom-out;
|
|
1673
|
+
}
|
|
1674
|
+
.aas-zoom.is-open {
|
|
1675
|
+
opacity: 1;
|
|
1676
|
+
}
|
|
1677
|
+
.aas-zoom[hidden] {
|
|
1678
|
+
display: none;
|
|
1679
|
+
}
|
|
1680
|
+
/* A large stage. The media is sized by the script (svg) or fit (img); `margin:
|
|
1681
|
+
auto` centres it when it's smaller than the stage and lets the stage scroll
|
|
1682
|
+
when it's bigger — so a complex diagram can be panned. */
|
|
1683
|
+
.aas-zoom-stage {
|
|
1684
|
+
width: 92vw;
|
|
1685
|
+
height: 86vh;
|
|
1686
|
+
overflow: auto;
|
|
1687
|
+
overscroll-behavior: contain;
|
|
1688
|
+
cursor: default;
|
|
1689
|
+
/* Same text context as .aas-slide-inner, where Mermaid measured its labels.
|
|
1690
|
+
Without keep-all, Korean labels re-wrap per syllable inside their measured
|
|
1691
|
+
boxes and drift to the top-left of each node. */
|
|
1692
|
+
word-break: keep-all;
|
|
1693
|
+
overflow-wrap: break-word;
|
|
1694
|
+
}
|
|
1695
|
+
/* Centres content that fits; grows with (and scrolls) content that doesn't. */
|
|
1696
|
+
.aas-zoom-fit {
|
|
1697
|
+
display: flex;
|
|
1698
|
+
align-items: center;
|
|
1699
|
+
justify-content: center;
|
|
1700
|
+
min-width: 100%;
|
|
1701
|
+
min-height: 100%;
|
|
1702
|
+
}
|
|
1703
|
+
/* Holds the transform-scaled diagram at its scaled size (so scroll/centre work). */
|
|
1704
|
+
.aas-zoom-scalebox {
|
|
1705
|
+
flex: none;
|
|
1706
|
+
}
|
|
1707
|
+
.aas-zoom-stage svg {
|
|
1708
|
+
max-width: none !important;
|
|
1709
|
+
flex: none;
|
|
1710
|
+
display: block;
|
|
1711
|
+
}
|
|
1712
|
+
.aas-zoom-stage img {
|
|
1713
|
+
max-width: 100%;
|
|
1714
|
+
max-height: 100%;
|
|
1715
|
+
width: auto;
|
|
1716
|
+
height: auto;
|
|
1717
|
+
object-fit: contain;
|
|
1718
|
+
border-radius: 0.6rem;
|
|
1719
|
+
}
|
|
1720
|
+
.aas-zoom-close {
|
|
1721
|
+
position: fixed;
|
|
1722
|
+
top: clamp(1rem, 3vh, 2rem);
|
|
1723
|
+
right: clamp(1rem, 3vw, 2rem);
|
|
1724
|
+
display: flex;
|
|
1725
|
+
align-items: center;
|
|
1726
|
+
justify-content: center;
|
|
1727
|
+
width: 2.6rem;
|
|
1728
|
+
height: 2.6rem;
|
|
1729
|
+
border: 1px solid var(--aas-border);
|
|
1730
|
+
border-radius: 0.7rem;
|
|
1731
|
+
background: var(--aas-panel);
|
|
1732
|
+
color: var(--aas-text);
|
|
1733
|
+
cursor: pointer;
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1736
|
+
/* --- Overview grid (press `o`) ------------------------------------------- */
|
|
1737
|
+
.aas-ov {
|
|
1738
|
+
position: fixed;
|
|
1739
|
+
inset: 0;
|
|
1740
|
+
z-index: 40;
|
|
1741
|
+
overflow-y: auto;
|
|
1742
|
+
padding: clamp(1rem, 4vh, 3rem);
|
|
1743
|
+
display: grid;
|
|
1744
|
+
grid-template-columns: repeat(auto-fill, 260px);
|
|
1745
|
+
justify-content: center;
|
|
1746
|
+
align-content: start;
|
|
1747
|
+
gap: clamp(0.8rem, 2vw, 1.6rem);
|
|
1748
|
+
background: color-mix(in srgb, var(--aas-bg) 93%, #000);
|
|
1749
|
+
opacity: 0;
|
|
1750
|
+
transition: opacity 0.18s ease;
|
|
1751
|
+
}
|
|
1752
|
+
.aas-ov.is-open {
|
|
1753
|
+
opacity: 1;
|
|
1754
|
+
}
|
|
1755
|
+
.aas-ov[hidden] {
|
|
1756
|
+
display: none;
|
|
1757
|
+
}
|
|
1758
|
+
.aas-ov-cell {
|
|
1759
|
+
position: relative;
|
|
1760
|
+
padding: 0;
|
|
1761
|
+
border: 2px solid var(--aas-border);
|
|
1762
|
+
border-radius: 0.6rem;
|
|
1763
|
+
background: var(--aas-panel);
|
|
1764
|
+
overflow: hidden;
|
|
1765
|
+
cursor: pointer;
|
|
1766
|
+
transition: border-color 0.15s ease;
|
|
1767
|
+
}
|
|
1768
|
+
.aas-ov-cell:hover,
|
|
1769
|
+
.aas-ov-cell:focus-visible {
|
|
1770
|
+
border-color: var(--aas-accent);
|
|
1771
|
+
}
|
|
1772
|
+
.aas-ov-cell.is-current {
|
|
1773
|
+
border-color: var(--aas-accent);
|
|
1774
|
+
box-shadow: 0 0 0 2px var(--aas-accent);
|
|
1775
|
+
}
|
|
1776
|
+
.aas-ov-thumb {
|
|
1777
|
+
position: relative;
|
|
1778
|
+
width: 260px;
|
|
1779
|
+
overflow: hidden;
|
|
1780
|
+
background: var(--aas-bg);
|
|
1781
|
+
pointer-events: none;
|
|
1782
|
+
}
|
|
1783
|
+
.aas-ov-num {
|
|
1784
|
+
position: absolute;
|
|
1785
|
+
left: 0.4rem;
|
|
1786
|
+
bottom: 0.4rem;
|
|
1787
|
+
padding: 0.05rem 0.45rem;
|
|
1788
|
+
border-radius: 0.4rem;
|
|
1789
|
+
background: rgba(0, 0, 0, 0.62);
|
|
1790
|
+
color: #fff;
|
|
1791
|
+
font-size: 0.75rem;
|
|
1792
|
+
font-variant-numeric: tabular-nums;
|
|
1793
|
+
}
|
|
1794
|
+
/* Overview + lightbox are screen-only affordances. */
|
|
1795
|
+
@media print {
|
|
1796
|
+
.aas-ov {
|
|
1797
|
+
display: none !important;
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1801
|
+
/* Stack image + text on narrow screens (screen only — print keeps them side by
|
|
1802
|
+
side regardless of the page width). */
|
|
1803
|
+
@media screen and (max-width: 48rem) {
|
|
1804
|
+
.aas-slide-inner .aas-split,
|
|
1805
|
+
.aas-slide-inner .aas-split.r-30-70,
|
|
1806
|
+
.aas-slide-inner .aas-split.r-70-30 {
|
|
1807
|
+
grid-template-columns: 1fr;
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1811
|
+
/* --- Callout boxes (:::note / :::tip / :::warning / :::info) -------------- */
|
|
1812
|
+
.aas-slide-inner .aas-callout {
|
|
1813
|
+
--cal: var(--aas-accent);
|
|
1814
|
+
margin: 0.9em 0;
|
|
1815
|
+
padding: 0.9em 1.2em;
|
|
1816
|
+
border-left: 4px solid var(--cal);
|
|
1817
|
+
border-radius: 0.6rem;
|
|
1818
|
+
background: color-mix(in srgb, var(--cal) 12%, transparent);
|
|
1819
|
+
}
|
|
1820
|
+
.aas-slide-inner .aas-callout > :first-child {
|
|
1821
|
+
margin-top: 0;
|
|
1822
|
+
}
|
|
1823
|
+
.aas-slide-inner .aas-callout > :last-child {
|
|
1824
|
+
margin-bottom: 0;
|
|
1825
|
+
}
|
|
1826
|
+
.aas-slide-inner .aas-callout strong:first-child {
|
|
1827
|
+
color: var(--cal);
|
|
1828
|
+
}
|
|
1829
|
+
/* Scoped to match the base rule's specificity so the colour actually wins. */
|
|
1830
|
+
.aas-slide-inner .aas-callout-tip {
|
|
1831
|
+
--cal: #16a34a;
|
|
1832
|
+
}
|
|
1833
|
+
.aas-slide-inner .aas-callout-warning {
|
|
1834
|
+
--cal: #d97706;
|
|
1835
|
+
}
|
|
1836
|
+
.aas-slide-inner .aas-callout-info {
|
|
1837
|
+
--cal: #0284c7;
|
|
1838
|
+
}
|
|
1839
|
+
|
|
1840
|
+
/* --- Stats / KPI (:::stats, cards split by ---) -------------------------- */
|
|
1841
|
+
.aas-slide-inner .aas-stats {
|
|
1842
|
+
display: grid;
|
|
1843
|
+
grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
|
|
1844
|
+
gap: clamp(1rem, 3vw, 2rem);
|
|
1845
|
+
margin: 1.1em 0;
|
|
1846
|
+
text-align: center;
|
|
1847
|
+
}
|
|
1848
|
+
.aas-slide-inner .aas-stat {
|
|
1849
|
+
padding: 1.2em 1em;
|
|
1850
|
+
border: 1px solid var(--aas-border);
|
|
1851
|
+
border-radius: 0.9rem;
|
|
1852
|
+
background: var(--aas-tint);
|
|
1853
|
+
}
|
|
1854
|
+
.aas-slide-inner .aas-stat > :first-child {
|
|
1855
|
+
margin: 0 0 0.15em;
|
|
1856
|
+
font-size: clamp(2.2rem, 5.5vw, 3.8rem);
|
|
1857
|
+
font-weight: 800;
|
|
1858
|
+
line-height: 1;
|
|
1859
|
+
letter-spacing: -0.02em;
|
|
1860
|
+
color: var(--aas-accent);
|
|
1861
|
+
}
|
|
1862
|
+
.aas-slide-inner .aas-stat > :first-child + * {
|
|
1863
|
+
margin-top: 0;
|
|
1864
|
+
}
|
|
1865
|
+
.aas-slide-inner .aas-stat p {
|
|
1866
|
+
margin: 0;
|
|
1867
|
+
color: var(--aas-muted);
|
|
1868
|
+
}
|
|
1869
|
+
|
|
1870
|
+
/* --- Comparison (:::compare, cards split by ---) ------------------------- */
|
|
1871
|
+
.aas-slide-inner .aas-compare {
|
|
1872
|
+
display: grid;
|
|
1873
|
+
grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
|
|
1874
|
+
gap: clamp(1rem, 3vw, 2rem);
|
|
1875
|
+
margin: 1.1em 0;
|
|
1876
|
+
align-items: start;
|
|
1877
|
+
}
|
|
1878
|
+
.aas-slide-inner .aas-compare-col {
|
|
1879
|
+
padding: 1.1em 1.3em 1.2em;
|
|
1880
|
+
border: 1px solid var(--aas-border);
|
|
1881
|
+
border-radius: 0.9rem;
|
|
1882
|
+
background: var(--aas-tint);
|
|
1883
|
+
}
|
|
1884
|
+
.aas-slide-inner .aas-compare-col > :first-child {
|
|
1885
|
+
margin-top: 0;
|
|
1886
|
+
}
|
|
1887
|
+
.aas-slide-inner .aas-compare-col > :last-child {
|
|
1888
|
+
margin-bottom: 0;
|
|
1889
|
+
}
|
|
1890
|
+
.aas-slide-inner .aas-compare-col > :is(h2, h3, h4):first-child {
|
|
1891
|
+
font-size: clamp(1.2rem, 2.4vw, 1.7rem);
|
|
1892
|
+
margin: 0 0 0.5em;
|
|
1893
|
+
color: var(--aas-text);
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
/* --- Hero quote (<Slide class="quote">) ---------------------------------- */
|
|
1897
|
+
.aas-slide.quote .aas-slide-inner {
|
|
1898
|
+
text-align: center;
|
|
1899
|
+
max-width: min(60rem, 90%);
|
|
1900
|
+
}
|
|
1901
|
+
.aas-slide.quote blockquote {
|
|
1902
|
+
position: relative;
|
|
1903
|
+
margin: 0;
|
|
1904
|
+
padding: 0;
|
|
1905
|
+
border: none;
|
|
1906
|
+
font-size: clamp(1.8rem, 4.4vw, 3.1rem);
|
|
1907
|
+
font-weight: 600;
|
|
1908
|
+
line-height: 1.28;
|
|
1909
|
+
letter-spacing: -0.01em;
|
|
1910
|
+
color: var(--aas-text);
|
|
1911
|
+
}
|
|
1912
|
+
.aas-slide.quote blockquote p {
|
|
1913
|
+
margin: 0;
|
|
1914
|
+
font-size: inherit;
|
|
1915
|
+
}
|
|
1916
|
+
.aas-slide.quote blockquote::before {
|
|
1917
|
+
content: '\201C';
|
|
1918
|
+
display: block;
|
|
1919
|
+
font-size: 2.2em;
|
|
1920
|
+
line-height: 0.7;
|
|
1921
|
+
margin-bottom: 0.1em;
|
|
1922
|
+
color: var(--aas-accent);
|
|
1923
|
+
opacity: 0.55;
|
|
1924
|
+
}
|
|
1925
|
+
.aas-slide.quote .aas-subtitle {
|
|
1926
|
+
margin: 1.1em 0 0;
|
|
1927
|
+
font-size: clamp(1rem, 1.9vw, 1.45rem);
|
|
1928
|
+
color: var(--aas-muted);
|
|
1929
|
+
}
|
|
1930
|
+
|
|
1931
|
+
/* --- Step reveal (:::steps) — fragments shown one at a time -------------- */
|
|
1932
|
+
/* Progressive enhancement: hidden state is added by the deck script, so with no
|
|
1933
|
+
JS (and in print) every step is visible. */
|
|
1934
|
+
.aas-slide-inner .aas-step {
|
|
1935
|
+
transition:
|
|
1936
|
+
opacity 0.3s ease,
|
|
1937
|
+
transform 0.3s ease;
|
|
1938
|
+
}
|
|
1939
|
+
.aas-slide-inner .aas-step.is-step-hidden {
|
|
1940
|
+
opacity: 0;
|
|
1941
|
+
transform: translateY(0.4em);
|
|
1942
|
+
}
|
|
1943
|
+
|
|
1944
|
+
/* Walkthrough steps (`:::step{scroll=…}`): the block-level step gets some room,
|
|
1945
|
+
and while stepping the non-active ones dim so the current one leads the eye
|
|
1946
|
+
(paired with the diagram scrolling to the step's spot). */
|
|
1947
|
+
.aas-slide-inner .aas-step[data-scroll] {
|
|
1948
|
+
margin: 0 0 0.9em;
|
|
1949
|
+
padding-left: 0.9em;
|
|
1950
|
+
border-left: 3px solid transparent;
|
|
1951
|
+
}
|
|
1952
|
+
.aas-slide-inner .aas-step[data-scroll] > :first-child {
|
|
1953
|
+
margin-top: 0;
|
|
1954
|
+
}
|
|
1955
|
+
.aas-slide-inner .aas-step[data-scroll]:not(.is-step-hidden):not(.is-step-active) {
|
|
1956
|
+
opacity: 0.4;
|
|
1957
|
+
}
|
|
1958
|
+
.aas-slide-inner .aas-step[data-scroll].is-step-active {
|
|
1959
|
+
border-left-color: var(--aas-accent);
|
|
1960
|
+
}
|
|
1961
|
+
|
|
1962
|
+
/* --- Visual themes ------------------------------------------------------- */
|
|
1963
|
+
/* Picked per deck via `theme:` in frontmatter (adds .aas-theme-<name> to the
|
|
1964
|
+
deck). They restyle slide typography only; light/dark still follows the site.
|
|
1965
|
+
`default` is the base look above — the classes below are the alternatives. */
|
|
1966
|
+
|
|
1967
|
+
/* simple — quiet and monochrome: headings in the text colour (no accent pop),
|
|
1968
|
+
markers and table headers muted. Reads like clean notes. */
|
|
1969
|
+
.aas-theme-simple .aas-slide-inner h2 {
|
|
1970
|
+
color: var(--aas-text);
|
|
1971
|
+
font-weight: 600;
|
|
1972
|
+
}
|
|
1973
|
+
.aas-theme-simple .aas-slide-inner li::marker {
|
|
1974
|
+
color: var(--aas-muted);
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1977
|
+
/* calm — serif headings, softened accent, roomier lines. A relaxed, editorial
|
|
1978
|
+
feel. Uses the site's reading serif (MaruBuri) for headings. */
|
|
1979
|
+
.aas-theme-calm .aas-slide-inner h1,
|
|
1980
|
+
.aas-theme-calm .aas-slide-inner h2,
|
|
1981
|
+
.aas-theme-calm .aas-slide-inner h3 {
|
|
1982
|
+
font-family: 'MaruBuri', ui-serif, Georgia, serif;
|
|
1983
|
+
font-weight: 600;
|
|
1984
|
+
letter-spacing: 0;
|
|
1985
|
+
}
|
|
1986
|
+
.aas-theme-calm .aas-slide-inner h2 {
|
|
1987
|
+
color: color-mix(in srgb, var(--aas-accent) 55%, var(--aas-text));
|
|
1988
|
+
}
|
|
1989
|
+
.aas-theme-calm .aas-slide-inner p,
|
|
1990
|
+
.aas-theme-calm .aas-slide-inner li {
|
|
1991
|
+
line-height: 1.75;
|
|
1992
|
+
}
|
|
1993
|
+
.aas-theme-calm .aas-slide-inner p {
|
|
1994
|
+
margin-bottom: 0.9em;
|
|
1995
|
+
}
|
|
1996
|
+
|
|
1997
|
+
/* bold — big, heavy, high-contrast headings; accent-coloured emphasis. */
|
|
1998
|
+
.aas-theme-bold .aas-slide-inner h1 {
|
|
1999
|
+
font-weight: 800;
|
|
2000
|
+
letter-spacing: -0.03em;
|
|
2001
|
+
}
|
|
2002
|
+
.aas-theme-bold .aas-slide-inner h2 {
|
|
2003
|
+
font-weight: 800;
|
|
2004
|
+
letter-spacing: -0.025em;
|
|
2005
|
+
font-size: clamp(1.7rem, 4.2vw, 3rem);
|
|
2006
|
+
}
|
|
2007
|
+
.aas-theme-bold .aas-slide-inner strong {
|
|
2008
|
+
color: var(--aas-accent);
|
|
2009
|
+
}
|
|
2010
|
+
.aas-theme-bold .aas-slide.cover h1 {
|
|
2011
|
+
font-size: clamp(3rem, 9vw, 6.5rem);
|
|
2012
|
+
font-weight: 800;
|
|
2013
|
+
letter-spacing: -0.04em;
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
/* --- Deck chrome (progress bar, back link, prev/next + counter) ---------- */
|
|
2017
|
+
.aas-deck-progress {
|
|
2018
|
+
position: fixed;
|
|
2019
|
+
top: 0;
|
|
2020
|
+
left: 0;
|
|
2021
|
+
right: 0;
|
|
2022
|
+
height: 3px;
|
|
2023
|
+
background: var(--aas-border);
|
|
2024
|
+
z-index: 10;
|
|
2025
|
+
}
|
|
2026
|
+
.aas-deck-progress-fill {
|
|
2027
|
+
height: 100%;
|
|
2028
|
+
width: 0;
|
|
2029
|
+
background: var(--aas-accent);
|
|
2030
|
+
transition: width 0.25s ease;
|
|
2031
|
+
}
|
|
2032
|
+
|
|
2033
|
+
.aas-deck-back {
|
|
2034
|
+
position: fixed;
|
|
2035
|
+
top: 1rem;
|
|
2036
|
+
left: 1rem;
|
|
2037
|
+
z-index: 10;
|
|
2038
|
+
display: inline-flex;
|
|
2039
|
+
align-items: center;
|
|
2040
|
+
gap: 0.3rem;
|
|
2041
|
+
padding: 0.4rem 0.75rem 0.4rem 0.55rem;
|
|
2042
|
+
border-radius: 999px;
|
|
2043
|
+
font-size: 0.85rem;
|
|
2044
|
+
color: var(--aas-muted);
|
|
2045
|
+
background: color-mix(in srgb, var(--aas-panel) 85%, transparent);
|
|
2046
|
+
border: 1px solid var(--aas-border);
|
|
2047
|
+
text-decoration: none;
|
|
2048
|
+
opacity: 0.5;
|
|
2049
|
+
transition: opacity 0.2s ease, color 0.2s ease;
|
|
2050
|
+
}
|
|
2051
|
+
.aas-deck-back:hover {
|
|
2052
|
+
opacity: 1;
|
|
2053
|
+
color: var(--aas-text);
|
|
2054
|
+
}
|
|
2055
|
+
|
|
2056
|
+
/* Actions drawer (left edge, vertically centered): a slim tab pokes out; when
|
|
2057
|
+
opened, the panel slides in from the left and the tab's arrow flips. */
|
|
2058
|
+
.aas-deck-menu {
|
|
2059
|
+
--menu-w: 12rem;
|
|
2060
|
+
position: fixed;
|
|
2061
|
+
top: 50%;
|
|
2062
|
+
left: 0;
|
|
2063
|
+
z-index: 11;
|
|
2064
|
+
display: flex;
|
|
2065
|
+
align-items: center;
|
|
2066
|
+
/* Closed: the panel is parked off-screen left, only the tab shows at the edge. */
|
|
2067
|
+
transform: translate(calc(-1 * var(--menu-w)), -50%);
|
|
2068
|
+
transition: transform 0.28s ease;
|
|
2069
|
+
}
|
|
2070
|
+
.aas-deck-menu.is-open {
|
|
2071
|
+
transform: translate(0, -50%);
|
|
2072
|
+
}
|
|
2073
|
+
.aas-deck-menu-panel {
|
|
2074
|
+
width: var(--menu-w);
|
|
2075
|
+
padding: 0.4rem;
|
|
2076
|
+
border: 1px solid var(--aas-border);
|
|
2077
|
+
border-left: none;
|
|
2078
|
+
border-radius: 0 0.9rem 0.9rem 0;
|
|
2079
|
+
background: var(--aas-panel);
|
|
2080
|
+
box-shadow: var(--aas-shadow);
|
|
2081
|
+
}
|
|
2082
|
+
.aas-deck-menu-panel button {
|
|
2083
|
+
display: flex;
|
|
2084
|
+
align-items: center;
|
|
2085
|
+
gap: 0.55rem;
|
|
2086
|
+
width: 100%;
|
|
2087
|
+
text-align: left;
|
|
2088
|
+
border: none;
|
|
2089
|
+
background: transparent;
|
|
2090
|
+
color: var(--aas-text);
|
|
2091
|
+
font-size: 0.9rem;
|
|
2092
|
+
padding: 0.45rem 0.6rem;
|
|
2093
|
+
border-radius: 0.5rem;
|
|
2094
|
+
cursor: pointer;
|
|
2095
|
+
}
|
|
2096
|
+
.aas-deck-menu-panel button:hover {
|
|
2097
|
+
background: var(--aas-tint);
|
|
2098
|
+
}
|
|
2099
|
+
.aas-deck-menu-panel button svg {
|
|
2100
|
+
color: var(--aas-muted);
|
|
2101
|
+
flex: none;
|
|
2102
|
+
}
|
|
2103
|
+
/* Divider between the actions and the theme options. */
|
|
2104
|
+
.aas-deck-menu-sep {
|
|
2105
|
+
height: 1px;
|
|
2106
|
+
margin: 0.35rem 0.3rem;
|
|
2107
|
+
background: var(--aas-border);
|
|
2108
|
+
}
|
|
2109
|
+
/* Theme options: a single row of icon buttons (system · light · dark). */
|
|
2110
|
+
.aas-deck-menu-themes {
|
|
2111
|
+
display: flex;
|
|
2112
|
+
gap: 0.25rem;
|
|
2113
|
+
padding: 0.15rem 0.2rem 0.05rem;
|
|
2114
|
+
}
|
|
2115
|
+
.aas-deck-menu-themes button {
|
|
2116
|
+
flex: 1;
|
|
2117
|
+
justify-content: center;
|
|
2118
|
+
padding: 0.4rem 0;
|
|
2119
|
+
color: var(--aas-muted);
|
|
2120
|
+
}
|
|
2121
|
+
.aas-deck-menu-themes button svg {
|
|
2122
|
+
color: inherit;
|
|
2123
|
+
}
|
|
2124
|
+
.aas-deck-menu-themes button[aria-pressed='true'] {
|
|
2125
|
+
background: var(--aas-tint);
|
|
2126
|
+
color: var(--aas-accent, var(--aas-text));
|
|
2127
|
+
}
|
|
2128
|
+
/* The handle/tab — attached to the panel's right edge. */
|
|
2129
|
+
.aas-deck-menu-tab {
|
|
2130
|
+
display: flex;
|
|
2131
|
+
align-items: center;
|
|
2132
|
+
justify-content: center;
|
|
2133
|
+
width: 1.5rem;
|
|
2134
|
+
height: 3.25rem;
|
|
2135
|
+
padding: 0;
|
|
2136
|
+
border: 1px solid var(--aas-border);
|
|
2137
|
+
border-left: none;
|
|
2138
|
+
border-radius: 0 0.6rem 0.6rem 0;
|
|
2139
|
+
background: color-mix(in srgb, var(--aas-panel) 88%, transparent);
|
|
2140
|
+
color: var(--aas-muted);
|
|
2141
|
+
cursor: pointer;
|
|
2142
|
+
opacity: 0.55;
|
|
2143
|
+
transition: opacity 0.2s ease, color 0.2s ease;
|
|
2144
|
+
}
|
|
2145
|
+
.aas-deck-menu-tab:hover,
|
|
2146
|
+
.aas-deck-menu.is-open .aas-deck-menu-tab {
|
|
2147
|
+
opacity: 1;
|
|
2148
|
+
color: var(--aas-text);
|
|
2149
|
+
}
|
|
2150
|
+
.aas-deck-menu-arrow {
|
|
2151
|
+
transition: transform 0.28s ease;
|
|
2152
|
+
}
|
|
2153
|
+
.aas-deck-menu.is-open .aas-deck-menu-arrow {
|
|
2154
|
+
transform: rotate(180deg); /* ▶ (open) → ◀ (close) */
|
|
2155
|
+
}
|
|
2156
|
+
|
|
2157
|
+
/* Footer (bottom-left): presenter · date. */
|
|
2158
|
+
.aas-deck-footer {
|
|
2159
|
+
position: fixed;
|
|
2160
|
+
bottom: 1.1rem;
|
|
2161
|
+
left: 1rem;
|
|
2162
|
+
z-index: 10;
|
|
2163
|
+
display: inline-flex;
|
|
2164
|
+
align-items: center;
|
|
2165
|
+
gap: 0.4rem;
|
|
2166
|
+
font-size: 0.8rem;
|
|
2167
|
+
color: var(--aas-muted);
|
|
2168
|
+
opacity: 0.7;
|
|
2169
|
+
}
|
|
2170
|
+
.aas-deck-footer-sep {
|
|
2171
|
+
opacity: 0.5;
|
|
2172
|
+
}
|
|
2173
|
+
|
|
2174
|
+
/* Print / PDF export (menu → Print/PDF, or the browser print dialog). Each slide
|
|
2175
|
+
becomes exactly one 16:9 page — a fixed physical size so it can't overflow onto
|
|
2176
|
+
a stray extra page, and wide enough that image splits never stack. Enable
|
|
2177
|
+
"Background graphics" in the print dialog for themed/image backgrounds. */
|
|
2178
|
+
@media print {
|
|
2179
|
+
/* PowerPoint-style 16:9 page (13.333in × 7.5in). */
|
|
2180
|
+
@page {
|
|
2181
|
+
size: 13.333in 7.5in;
|
|
2182
|
+
margin: 0;
|
|
2183
|
+
}
|
|
2184
|
+
.aas-deck-body {
|
|
2185
|
+
overflow: visible;
|
|
2186
|
+
-webkit-print-color-adjust: exact;
|
|
2187
|
+
print-color-adjust: exact;
|
|
2188
|
+
}
|
|
2189
|
+
.aas-deck-back,
|
|
2190
|
+
.aas-deck-menu,
|
|
2191
|
+
.aas-deck-toc,
|
|
2192
|
+
.aas-deck-nav,
|
|
2193
|
+
.aas-deck-progress,
|
|
2194
|
+
.aas-deck-footer,
|
|
2195
|
+
.mermaidTooltip {
|
|
2196
|
+
/* the last one is Mermaid's stray hover-tooltip div — its few px otherwise
|
|
2197
|
+
overflow into a trailing blank page. */
|
|
2198
|
+
display: none !important;
|
|
2199
|
+
}
|
|
2200
|
+
.aas-deck {
|
|
2201
|
+
position: static;
|
|
2202
|
+
display: block;
|
|
2203
|
+
overflow: visible;
|
|
2204
|
+
height: auto;
|
|
2205
|
+
scroll-snap-type: none;
|
|
2206
|
+
}
|
|
2207
|
+
.aas-slide {
|
|
2208
|
+
width: 13.333in;
|
|
2209
|
+
height: 7.5in;
|
|
2210
|
+
overflow: hidden;
|
|
2211
|
+
scroll-snap-align: none;
|
|
2212
|
+
break-inside: avoid;
|
|
2213
|
+
}
|
|
2214
|
+
.aas-slide:not(:last-child) {
|
|
2215
|
+
break-after: page;
|
|
2216
|
+
}
|
|
2217
|
+
/* Fixed page size, so don't derive the content width from viewport units. */
|
|
2218
|
+
.aas-slide-inner {
|
|
2219
|
+
max-width: 92%;
|
|
2220
|
+
}
|
|
2221
|
+
}
|
|
2222
|
+
|
|
2223
|
+
/* Table of contents — a top-right toggle that opens a jump-list of headings. */
|
|
2224
|
+
.aas-deck-toc {
|
|
2225
|
+
position: fixed;
|
|
2226
|
+
top: 1rem;
|
|
2227
|
+
right: 1rem;
|
|
2228
|
+
z-index: 11;
|
|
2229
|
+
}
|
|
2230
|
+
.aas-deck-toc-btn {
|
|
2231
|
+
display: inline-flex;
|
|
2232
|
+
align-items: center;
|
|
2233
|
+
justify-content: center;
|
|
2234
|
+
width: 2.1rem;
|
|
2235
|
+
height: 2.1rem;
|
|
2236
|
+
border-radius: 999px;
|
|
2237
|
+
color: var(--aas-muted);
|
|
2238
|
+
background: color-mix(in srgb, var(--aas-panel) 85%, transparent);
|
|
2239
|
+
border: 1px solid var(--aas-border);
|
|
2240
|
+
cursor: pointer;
|
|
2241
|
+
opacity: 0.5;
|
|
2242
|
+
transition: opacity 0.2s ease, color 0.2s ease;
|
|
2243
|
+
}
|
|
2244
|
+
.aas-deck-toc-btn:hover,
|
|
2245
|
+
.aas-deck-toc-btn[aria-expanded='true'] {
|
|
2246
|
+
opacity: 1;
|
|
2247
|
+
color: var(--aas-text);
|
|
2248
|
+
}
|
|
2249
|
+
.aas-deck-toc-panel {
|
|
2250
|
+
position: absolute;
|
|
2251
|
+
top: calc(100% + 0.4rem);
|
|
2252
|
+
right: 0;
|
|
2253
|
+
min-width: 15rem;
|
|
2254
|
+
max-width: min(22rem, 80vw);
|
|
2255
|
+
max-height: 70vh;
|
|
2256
|
+
overflow-y: auto;
|
|
2257
|
+
padding: 0.4rem;
|
|
2258
|
+
border-radius: 0.9rem;
|
|
2259
|
+
background: var(--aas-panel);
|
|
2260
|
+
border: 1px solid var(--aas-border);
|
|
2261
|
+
box-shadow: var(--aas-shadow);
|
|
2262
|
+
}
|
|
2263
|
+
.aas-deck-toc-panel ul {
|
|
2264
|
+
list-style: none;
|
|
2265
|
+
margin: 0;
|
|
2266
|
+
padding: 0;
|
|
2267
|
+
}
|
|
2268
|
+
.aas-deck-toc-panel li {
|
|
2269
|
+
margin: 0;
|
|
2270
|
+
}
|
|
2271
|
+
.aas-deck-toc-panel button {
|
|
2272
|
+
display: block;
|
|
2273
|
+
width: 100%;
|
|
2274
|
+
text-align: left;
|
|
2275
|
+
border: none;
|
|
2276
|
+
background: transparent;
|
|
2277
|
+
color: var(--aas-text);
|
|
2278
|
+
font-size: 0.9rem;
|
|
2279
|
+
line-height: 1.35;
|
|
2280
|
+
padding: 0.4rem 0.6rem;
|
|
2281
|
+
border-radius: 0.5rem;
|
|
2282
|
+
cursor: pointer;
|
|
2283
|
+
}
|
|
2284
|
+
.aas-deck-toc-panel button:hover {
|
|
2285
|
+
background: var(--aas-tint);
|
|
2286
|
+
}
|
|
2287
|
+
.aas-deck-toc-panel button.active {
|
|
2288
|
+
color: var(--aas-accent);
|
|
2289
|
+
font-weight: 600;
|
|
2290
|
+
background: color-mix(in srgb, var(--aas-accent) 10%, transparent);
|
|
2291
|
+
}
|
|
2292
|
+
/* ### / #### sub-entries (toc_level 3-4) sit indented and a touch smaller. */
|
|
2293
|
+
.aas-deck-toc-panel .aas-toc-l3 button,
|
|
2294
|
+
.aas-deck-toc-panel .aas-toc-l4 button {
|
|
2295
|
+
font-size: 0.82rem;
|
|
2296
|
+
color: var(--aas-muted);
|
|
2297
|
+
}
|
|
2298
|
+
.aas-deck-toc-panel .aas-toc-l3 button {
|
|
2299
|
+
padding-left: 1.4rem;
|
|
2300
|
+
}
|
|
2301
|
+
.aas-deck-toc-panel .aas-toc-l4 button {
|
|
2302
|
+
padding-left: 2.4rem;
|
|
2303
|
+
}
|
|
2304
|
+
.aas-deck-toc-panel .aas-toc-l3 button.active,
|
|
2305
|
+
.aas-deck-toc-panel .aas-toc-l4 button.active {
|
|
2306
|
+
color: var(--aas-accent);
|
|
2307
|
+
}
|
|
2308
|
+
|
|
2309
|
+
.aas-deck-nav {
|
|
2310
|
+
position: fixed;
|
|
2311
|
+
bottom: 1.1rem;
|
|
2312
|
+
left: 50%;
|
|
2313
|
+
transform: translateX(-50%);
|
|
2314
|
+
z-index: 10;
|
|
2315
|
+
display: inline-flex;
|
|
2316
|
+
align-items: center;
|
|
2317
|
+
gap: 0.35rem;
|
|
2318
|
+
padding: 0.3rem 0.4rem;
|
|
2319
|
+
border-radius: 999px;
|
|
2320
|
+
background: color-mix(in srgb, var(--aas-panel) 85%, transparent);
|
|
2321
|
+
border: 1px solid var(--aas-border);
|
|
2322
|
+
backdrop-filter: blur(6px);
|
|
2323
|
+
box-shadow: var(--aas-shadow);
|
|
2324
|
+
}
|
|
2325
|
+
.aas-deck-btn {
|
|
2326
|
+
display: inline-flex;
|
|
2327
|
+
align-items: center;
|
|
2328
|
+
justify-content: center;
|
|
2329
|
+
width: 2rem;
|
|
2330
|
+
height: 2rem;
|
|
2331
|
+
border: none;
|
|
2332
|
+
border-radius: 999px;
|
|
2333
|
+
background: transparent;
|
|
2334
|
+
color: var(--aas-text);
|
|
2335
|
+
cursor: pointer;
|
|
2336
|
+
}
|
|
2337
|
+
.aas-deck-btn:hover:not(:disabled) {
|
|
2338
|
+
background: var(--aas-tint);
|
|
2339
|
+
}
|
|
2340
|
+
.aas-deck-btn:disabled {
|
|
2341
|
+
opacity: 0.3;
|
|
2342
|
+
cursor: default;
|
|
2343
|
+
}
|
|
2344
|
+
.aas-deck-count {
|
|
2345
|
+
font-size: 0.85rem;
|
|
2346
|
+
color: var(--aas-muted);
|
|
2347
|
+
font-variant-numeric: tabular-nums;
|
|
2348
|
+
min-width: 3.5ch;
|
|
2349
|
+
text-align: center;
|
|
2350
|
+
}
|