@dataimago/css 0.1.0-alpha.22 → 0.1.0-alpha.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -0
- package/dist/bin/dataimago-sync.mjs +19 -1
- package/dist/dataviz/dataimago-dataviz.css +1 -1
- package/dist/dataviz/dataimago-dataviz.json +2 -2
- package/dist/dataviz/dataimago-dataviz.tex +1 -1
- package/dist/dataviz/dataimago_dataviz.R +1 -1
- package/dist/figures/dataimago-figure.sty +1 -1
- package/dist/figures/dataimago-tokens.sty +1 -1
- package/dist/fonts/cyrillic/fonts.css +1 -1
- package/dist/fonts/cyrillic-ext/fonts.css +1 -1
- package/dist/fonts/greek/fonts.css +1 -1
- package/dist/fonts/greek-ext/fonts.css +1 -1
- package/dist/fonts/josefin/fonts.css +1 -1
- package/dist/fonts/lang.css +1 -1
- package/dist/fonts/latin/fonts.css +1 -1
- package/dist/fonts/latin-ext/fonts.css +1 -1
- package/dist/fonts/math/fonts.css +1 -1
- package/dist/fonts/pkg/fonts.css +1 -1
- package/dist/fonts/vietnamese/fonts.css +1 -1
- package/dist/latex/dataimago-tokens.sty +1 -1
- package/dist/latex/dataimago.sty +1 -1
- package/dist/outputs.json +53 -44
- package/dist/quarto/_extensions/dataimago/monograph/_extension.yml +1 -1
- package/dist/quarto/_extensions/dataimago/monograph/dataimago-base.sty +1 -1
- package/dist/quarto/_extensions/dataimago/monograph/dataimago-monograph.sty +1 -1
- package/dist/quarto/_extensions/dataimago/monograph/dataimago-tokens.sty +1 -1
- package/dist/quarto/_extensions/dataimago/monograph/filters/figure-plate.lua +1 -1
- package/dist/quarto/_extensions/dataimago/monograph/filters/matter.lua +1 -1
- package/dist/quarto/_extensions/dataimago/monograph/filters/pkg-name.lua +1 -1
- package/dist/quarto/_extensions/dataimago/monograph/partials/before-body.tex +1 -1
- package/dist/quarto/_extensions/dataimago/monograph/partials/title.tex +1 -1
- package/dist/quarto/_extensions/dataimago/pkgsite/_extension.yml +28 -0
- package/dist/quarto/_extensions/dataimago/pkgsite/components.scss +243 -0
- package/dist/quarto/_extensions/dataimago/pkgsite/dataimago-dark.scss +344 -0
- package/dist/quarto/_extensions/dataimago/pkgsite/dataimago-light.scss +338 -0
- package/dist/quarto/_extensions/dataimago/pkgsite/filters/landing.lua +233 -0
- package/dist/quarto/_extensions/dataimago/pkgsite/filters/provenance.lua +212 -0
- package/dist/quarto/_extensions/dataimago/pkgsite/hero-fallback.svg +53 -0
- package/dist/quarto/_extensions/dataimago/pkgsite/pkgsite-hero.js +99 -0
- package/dist/quarto/_extensions/dataimago/pkgsite/pkgsite.scss +281 -0
- package/dist/quarto/components.scss +1 -1
- package/dist/quarto/dataimago-dark.scss +1 -1
- package/dist/quarto/dataimago-light.scss +1 -1
- package/dist/templates/KNOWLEDGE-explorer.md +1 -1
- package/dist/templates/KNOWLEDGE-framework.md +1 -1
- package/dist/templates/KNOWLEDGE-research.md +1 -1
- package/dist/templates/quarto_website/README.md +4 -2
- package/dist/templates/quarto_website/_quarto.yml.template +1 -1
- package/dist/templates/quarto_website/about.qmd.template +1 -1
- package/dist/templates/quarto_website/assets/css/lang.css +1 -1
- package/dist/templates/quarto_website/assets/js/custom-anchors.js +1 -1
- package/dist/templates/quarto_website/assets/js/logo-switch.js +1 -1
- package/dist/templates/quarto_website/assets/js/scroll.js +1 -1
- package/dist/templates/quarto_website/ethics.qmd.template +1 -1
- package/dist/templates/quarto_website/index.qmd.template +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
// @dataimago/css@0.1.0-alpha.23 dist/quarto/_extensions/dataimago/pkgsite/dataimago-light.scss · sha256:e456b3e8cfaa03df7fe5ac29bb6e8288454ee5daab29ff6470c45a12ff8d3f32 · generated from tokens; do not edit · restore: npx -p @dataimago/css@0.1.0-alpha.23 dataimago-sync
|
|
2
|
+
// dataimago light theme for Quarto 1.8 — generated from the design tokens (tools/formats/quarto.mjs).
|
|
3
|
+
// Bootstrap Sass variables are compile-time sRGB; runtime colours come from the custom properties below.
|
|
4
|
+
|
|
5
|
+
/*-- scss:defaults --*/
|
|
6
|
+
$body-bg: #ededeb !default;
|
|
7
|
+
$body-color: #14140f !default;
|
|
8
|
+
$headings-color: #14140f !default;
|
|
9
|
+
$navbar-bg: #ededeb !default;
|
|
10
|
+
$link-color: #434739 !default;
|
|
11
|
+
$link-hover-color: #363a2e !default;
|
|
12
|
+
$code-color: #1f618d !default;
|
|
13
|
+
$code-bg: #faf2e3 !default;
|
|
14
|
+
$border-color: #888785 !default;
|
|
15
|
+
$font-family-sans-serif: Noto Sans, Fira Sans, system-ui, sans-serif !default;
|
|
16
|
+
$font-family-monospace: Noto Sans Mono, SF Mono, Monaco, Inconsolata, monospace !default;
|
|
17
|
+
$headings-font-family: Josefin Sans, Noto Sans, system-ui, sans-serif !default;
|
|
18
|
+
$headings-font-weight: 500 !default;
|
|
19
|
+
$h2-font-size: 1.875rem !default;
|
|
20
|
+
$web-font-path: false !default;
|
|
21
|
+
|
|
22
|
+
/*-- scss:rules --*/
|
|
23
|
+
// ── Design tokens (contract custom properties) ───────────────────────
|
|
24
|
+
:root {
|
|
25
|
+
--color-palette-ink-50: #f5f5f4;
|
|
26
|
+
--color-palette-ink-100: #e7e5e4;
|
|
27
|
+
--color-palette-ink-200: #d6d3d1;
|
|
28
|
+
--color-palette-ink-300: #a8a29e;
|
|
29
|
+
--color-palette-ink-400: #78716c;
|
|
30
|
+
--color-palette-ink-500: #57534e;
|
|
31
|
+
--color-palette-ink-600: #44403c;
|
|
32
|
+
--color-palette-ink-700: #292524;
|
|
33
|
+
--color-palette-ink-800: #1c1917;
|
|
34
|
+
--color-palette-ink-900: #0c0a09;
|
|
35
|
+
--color-palette-stone-50: #f7f7f6;
|
|
36
|
+
--color-palette-stone-100: #ededeb;
|
|
37
|
+
--color-palette-stone-200: #dcdcda;
|
|
38
|
+
--color-palette-stone-300: #c1c1bf;
|
|
39
|
+
--color-palette-stone-400: #a0a0a0;
|
|
40
|
+
--color-palette-stone-500: #7c7c7c;
|
|
41
|
+
--color-palette-stone-600: #5e5e5c;
|
|
42
|
+
--color-palette-stone-700: #424240;
|
|
43
|
+
--color-palette-stone-800: #292927;
|
|
44
|
+
--color-palette-stone-900: #14140f;
|
|
45
|
+
--color-palette-forest-50: #f0f1ed;
|
|
46
|
+
--color-palette-forest-100: #dde0d4;
|
|
47
|
+
--color-palette-forest-200: #bdc4ad;
|
|
48
|
+
--color-palette-forest-300: #98a384;
|
|
49
|
+
--color-palette-forest-400: #7e8a6b;
|
|
50
|
+
--color-palette-forest-500: #5e6749;
|
|
51
|
+
--color-palette-forest-600: #4d5640;
|
|
52
|
+
--color-palette-forest-700: #434739;
|
|
53
|
+
--color-palette-forest-800: #363a2e;
|
|
54
|
+
--color-palette-forest-900: #1f2218;
|
|
55
|
+
--color-palette-paper-50: #fefdfb;
|
|
56
|
+
--color-palette-paper-100: #fdf9f2;
|
|
57
|
+
--color-palette-paper-200: #faf2e3;
|
|
58
|
+
--color-palette-paper-300: #f5e8cf;
|
|
59
|
+
--color-palette-paper-400: #edd9b3;
|
|
60
|
+
--color-palette-paper-500: #e0c088;
|
|
61
|
+
--color-palette-copper-50: #fdf4ee;
|
|
62
|
+
--color-palette-copper-100: #fbe5d1;
|
|
63
|
+
--color-palette-copper-200: #f6c79c;
|
|
64
|
+
--color-palette-copper-300: #f0a467;
|
|
65
|
+
--color-palette-copper-400: #ea8441;
|
|
66
|
+
--color-palette-copper-500: #d46820;
|
|
67
|
+
--color-palette-copper-600: #b55017;
|
|
68
|
+
--color-palette-copper-700: #913d15;
|
|
69
|
+
--color-palette-copper-800: #753318;
|
|
70
|
+
--color-palette-copper-900: #612b16;
|
|
71
|
+
--color-palette-accent-50: #f0f8fc;
|
|
72
|
+
--color-palette-accent-300: #3498DB;
|
|
73
|
+
--color-palette-accent-400: #2980B9;
|
|
74
|
+
--color-palette-accent-500: #1f618d;
|
|
75
|
+
--color-palette-accent-600: #154d6f;
|
|
76
|
+
--color-palette-accent-700: #0f3a52;
|
|
77
|
+
--color-palette-presentation-blue-50: #f0f8fc;
|
|
78
|
+
--color-palette-presentation-blue-500: #3498DB;
|
|
79
|
+
--color-palette-presentation-blue-600: #2980B9;
|
|
80
|
+
--color-palette-presentation-blue-700: #1f618d;
|
|
81
|
+
--color-functional-success: #27AE60;
|
|
82
|
+
--color-functional-warning: #F39C12;
|
|
83
|
+
--color-functional-error: #E74C3C;
|
|
84
|
+
--color-functional-info: #3498DB;
|
|
85
|
+
--transition-quick: 0.15s ease;
|
|
86
|
+
--transition-standard: 0.25s ease-in-out;
|
|
87
|
+
--transition-smooth: 0.35s ease;
|
|
88
|
+
--transition-logo: 0.3s;
|
|
89
|
+
--font-family-sans: Noto Sans, Fira Sans, system-ui, sans-serif;
|
|
90
|
+
--font-family-mono: Noto Sans Mono, SF Mono, Monaco, Inconsolata, monospace;
|
|
91
|
+
--font-family-display: var(--font-family-display-editorial);
|
|
92
|
+
--font-family-display-editorial: Josefin Sans, Noto Sans, system-ui, sans-serif;
|
|
93
|
+
--font-family-display-documentation: Noto Sans, system-ui, sans-serif;
|
|
94
|
+
--font-family-brand: Futura, system-ui, sans-serif;
|
|
95
|
+
--font-family-math: Noto Sans Math, math;
|
|
96
|
+
--font-size-micro: 0.75rem;
|
|
97
|
+
--font-size-small: 0.875rem;
|
|
98
|
+
--font-size-base: 1rem;
|
|
99
|
+
--font-size-readable: 1.125rem;
|
|
100
|
+
--font-size-emphasis: 1.25rem;
|
|
101
|
+
--font-size-heading-small: 1.5rem;
|
|
102
|
+
--font-size-heading-medium: 1.875rem;
|
|
103
|
+
--font-size-heading-large: 2.25rem;
|
|
104
|
+
--font-size-heading-xl: 3rem;
|
|
105
|
+
--font-weight-extralight: 200;
|
|
106
|
+
--font-weight-light: 300;
|
|
107
|
+
--font-weight-normal: 400;
|
|
108
|
+
--font-weight-medium: 500;
|
|
109
|
+
--font-weight-semibold: 600;
|
|
110
|
+
--font-weight-bold: 700;
|
|
111
|
+
--font-weight-heading-h1: var(--font-weight-medium);
|
|
112
|
+
--font-weight-heading-h2: var(--font-weight-medium);
|
|
113
|
+
--font-weight-heading-h3: var(--font-weight-normal);
|
|
114
|
+
--font-weight-heading-h4: var(--font-weight-light);
|
|
115
|
+
--font-weight-heading-h5: var(--font-weight-light);
|
|
116
|
+
--font-weight-heading-h6: var(--font-weight-light);
|
|
117
|
+
--font-weight-heading-subtitle: var(--font-weight-semibold);
|
|
118
|
+
--font-style-normal: normal;
|
|
119
|
+
--font-style-italic: italic;
|
|
120
|
+
--font-style-oblique: oblique;
|
|
121
|
+
--font-lineHeight-tight: 1.25;
|
|
122
|
+
--font-lineHeight-normal: 1.5;
|
|
123
|
+
--font-lineHeight-relaxed: 1.625;
|
|
124
|
+
--font-feature-settings-display: "lnum";
|
|
125
|
+
--font-feature-settings-body: "normal";
|
|
126
|
+
--spacing-xs: 0.25rem;
|
|
127
|
+
--spacing-sm: 0.5rem;
|
|
128
|
+
--spacing-md: 1rem;
|
|
129
|
+
--spacing-lg: 1.5rem;
|
|
130
|
+
--spacing-xl: 2rem;
|
|
131
|
+
--spacing-2xl: 3rem;
|
|
132
|
+
--spacing-3xl: 4rem;
|
|
133
|
+
--radius-sm: 0.25rem;
|
|
134
|
+
--radius-md: 0.5rem;
|
|
135
|
+
--radius-lg: 0.75rem;
|
|
136
|
+
--radius-xl: 1rem;
|
|
137
|
+
--radius-full: 9999px;
|
|
138
|
+
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
|
139
|
+
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
|
|
140
|
+
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
|
|
141
|
+
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1);
|
|
142
|
+
--color-dataviz-okabe-ito-orange: #E69F00;
|
|
143
|
+
--color-dataviz-okabe-ito-sky-blue: #56B4E9;
|
|
144
|
+
--color-dataviz-okabe-ito-bluish-green: #009E73;
|
|
145
|
+
--color-dataviz-okabe-ito-yellow: #F0E442;
|
|
146
|
+
--color-dataviz-okabe-ito-blue: #0072B2;
|
|
147
|
+
--color-dataviz-okabe-ito-vermillion: #D55E00;
|
|
148
|
+
--color-dataviz-okabe-ito-reddish-purple: #CC79A7;
|
|
149
|
+
--color-dataviz-categorical-1: #E69F00;
|
|
150
|
+
--color-dataviz-categorical-2: #56B4E9;
|
|
151
|
+
--color-dataviz-categorical-3: #009E73;
|
|
152
|
+
--color-dataviz-categorical-4: #F0E442;
|
|
153
|
+
--color-dataviz-categorical-5: #0072B2;
|
|
154
|
+
--color-dataviz-categorical-6: #D55E00;
|
|
155
|
+
--color-dataviz-categorical-7: #CC79A7;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
:root, [data-bs-theme="light"] {
|
|
159
|
+
--color-surface-page: #ededeb;
|
|
160
|
+
--color-surface-page: color(display-p3 0.9294 0.9294 0.9223);
|
|
161
|
+
--color-surface-page-scrolled: #ededeb;
|
|
162
|
+
--color-surface-page-scrolled: color(display-p3 0.9294 0.9294 0.9223);
|
|
163
|
+
--color-surface-elevated: #f7f7f6;
|
|
164
|
+
--color-surface-elevated: color(display-p3 0.9686 0.9686 0.9651);
|
|
165
|
+
--color-surface-sunken: #faf2e3;
|
|
166
|
+
--color-surface-sunken: color(display-p3 0.9749 0.9501 0.8963);
|
|
167
|
+
--color-surface-navbar: #ededeb;
|
|
168
|
+
--color-surface-navbar: color(display-p3 0.9294 0.9294 0.9223);
|
|
169
|
+
--color-surface-navbar-scrolled: #ededeb;
|
|
170
|
+
--color-surface-navbar-scrolled: color(display-p3 0.9294 0.9294 0.9223);
|
|
171
|
+
--color-surface-code: #faf2e3;
|
|
172
|
+
--color-surface-code: color(display-p3 0.9749 0.9501 0.8963);
|
|
173
|
+
--color-border-subtle: rgba(12, 10, 9, 0.45);
|
|
174
|
+
--color-border-subtle: color(display-p3 0.0457 0.0395 0.0358 / 0.45);
|
|
175
|
+
--color-border-moderate: rgba(12, 10, 9, 0.60);
|
|
176
|
+
--color-border-moderate: color(display-p3 0.0457 0.0395 0.0358 / 0.60);
|
|
177
|
+
--color-border-strong: rgba(12, 10, 9, 0.75);
|
|
178
|
+
--color-border-strong: color(display-p3 0.0457 0.0395 0.0358 / 0.75);
|
|
179
|
+
--color-border-card: rgba(12, 10, 9, 0.60);
|
|
180
|
+
--color-border-card: color(display-p3 0.0457 0.0395 0.0358 / 0.60);
|
|
181
|
+
--color-border-code: #d6d3d1;
|
|
182
|
+
--color-border-code: color(display-p3 0.8371 0.8278 0.8205);
|
|
183
|
+
--color-content-primary: #14140f;
|
|
184
|
+
--color-content-primary: color(display-p3 0.0784 0.0784 0.0608);
|
|
185
|
+
--color-content-secondary: #6a6a6a;
|
|
186
|
+
--color-content-secondary: color(display-p3 0.4157 0.4157 0.4157);
|
|
187
|
+
--color-content-muted: #706964;
|
|
188
|
+
--color-content-muted: color(display-p3 0.4345 0.4127 0.3945);
|
|
189
|
+
--color-content-inverse: #fdf9f2;
|
|
190
|
+
--color-content-inverse: color(display-p3 0.9894 0.977 0.9518);
|
|
191
|
+
--color-interactive-primary: #434739;
|
|
192
|
+
--color-interactive-primary: color(display-p3 0.2656 0.2779 0.2287);
|
|
193
|
+
--color-interactive-hover: #363a2e;
|
|
194
|
+
--color-interactive-hover: color(display-p3 0.2146 0.2269 0.1848);
|
|
195
|
+
--color-interactive-accent: #1f618d;
|
|
196
|
+
--color-interactive-accent: color(display-p3 0.198 0.375 0.5385);
|
|
197
|
+
--color-interactive-focus: #434739;
|
|
198
|
+
--color-interactive-focus: color(display-p3 0.2656 0.2779 0.2287);
|
|
199
|
+
--color-presentation-accent: #3498db;
|
|
200
|
+
--color-presentation-accent: color(display-p3 0.3208 0.588 0.8369);
|
|
201
|
+
--color-presentation-accent-hover: #2980b9;
|
|
202
|
+
--color-presentation-accent-hover: color(display-p3 0.2638 0.495 0.7068);
|
|
203
|
+
--color-vertical-accent-dissertation: #b87333;
|
|
204
|
+
--color-vertical-accent-dissertation: color(display-p3 0.7242 0.4389 0.1259);
|
|
205
|
+
--color-vertical-accent-rpkg: #3b82f6;
|
|
206
|
+
--color-vertical-accent-rpkg: color(display-p3 0.3047 0.5035 0.9338);
|
|
207
|
+
--color-vertical-accent-SGPc: #5a6310;
|
|
208
|
+
--color-vertical-accent-SGPc: color(display-p3 0.3595 0.3871 0.1309);
|
|
209
|
+
--color-brand-mark-red: #cc0000;
|
|
210
|
+
--color-brand-mark-red: color(display-p3 0.7331 0.1519 0.1019);
|
|
211
|
+
--contrast-high: rgb(20, 20, 16);
|
|
212
|
+
--contrast-readable: rgb(20, 20, 16);
|
|
213
|
+
--contrast-medium: #7c7c7c;
|
|
214
|
+
--contrast-subtle: #7c7c7c;
|
|
215
|
+
--shadow-subtle: 0 1px 2px 0 rgb(20 20 16 / 0.05);
|
|
216
|
+
--shadow-moderate: 0 4px 6px -1px rgb(20 20 16 / 0.1);
|
|
217
|
+
--shadow-prominent: 0 10px 15px -3px rgb(20 20 16 / 0.1);
|
|
218
|
+
--border-subtle: rgba(20, 20, 16, 0.47);
|
|
219
|
+
--border-moderate: rgba(20, 20, 16, 0.63);
|
|
220
|
+
--border-focus: #3498DB;
|
|
221
|
+
--navigation-hover-background: rgba(20, 20, 16, 0.05);
|
|
222
|
+
--navigation-active-background: rgba(20, 20, 16, 0.1);
|
|
223
|
+
--color-dataviz-okabe-ito-black: #000000;
|
|
224
|
+
--color-dataviz-categorical-8: #000000;
|
|
225
|
+
--color-dataviz-uncertainty-outer: #D6D6D6;
|
|
226
|
+
--color-dataviz-uncertainty-union: #9E9E9E;
|
|
227
|
+
--color-dataviz-uncertainty-inner: #333333;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// ── Quarto chrome → tokens ──────────────────────────────────────────────
|
|
231
|
+
body {
|
|
232
|
+
background-color: var(--color-surface-page);
|
|
233
|
+
color: var(--color-content-primary);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
h1, h2, h3, h4, h5, h6, .title {
|
|
237
|
+
color: var(--color-content-primary);
|
|
238
|
+
font-feature-settings: var(--font-feature-settings-display);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Navbar chrome is brand voice: Josefin through the editorial variable (never the
|
|
242
|
+
// Futura brand token). Tagged-language rules in lang.css still switch links to Noto;
|
|
243
|
+
// the brand is never translated (display-family-split).
|
|
244
|
+
.navbar-brand, .navbar-title, .navbar-nav .nav-link, .navbar-nav .dropdown-item {
|
|
245
|
+
font-family: var(--font-family-display-editorial);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
math { font-family: var(--font-family-math); }
|
|
249
|
+
|
|
250
|
+
// Links in running text are underlined: interactive.primary is about 1.9:1
|
|
251
|
+
// against body text in light mode, so colour cannot be the only cue (WCAG 1.4.1).
|
|
252
|
+
main.content :is(p, li, dd, td, blockquote, figcaption, .callout-body) a {
|
|
253
|
+
color: var(--color-interactive-primary);
|
|
254
|
+
text-decoration: underline;
|
|
255
|
+
text-underline-offset: 0.15em;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
main.content :is(p, li, dd, td, blockquote, figcaption, .callout-body) a:hover {
|
|
259
|
+
color: var(--color-interactive-hover);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Navigation and the outline stay plain.
|
|
263
|
+
#TOC a, nav a, .sidebar a, .navbar a, a.footnote-ref, a.anchorjs-link {
|
|
264
|
+
text-decoration: none;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
:not(pre) > code {
|
|
268
|
+
color: var(--color-interactive-accent);
|
|
269
|
+
background-color: var(--color-surface-code);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
pre, div.sourceCode {
|
|
273
|
+
background-color: var(--color-surface-code);
|
|
274
|
+
border: 1px solid var(--color-border-code);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Quarto themes its popups as [data-theme~="quarto"] at compile time ($body-bg);
|
|
278
|
+
// match that specificity so the runtime token wins.
|
|
279
|
+
.tippy-box, .tippy-box[data-theme~="quarto"] {
|
|
280
|
+
background-color: var(--color-surface-elevated);
|
|
281
|
+
color: var(--color-content-primary);
|
|
282
|
+
border: 1px solid var(--color-border-subtle);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
.tippy-box[data-theme~="quarto"] > .tippy-backdrop {
|
|
286
|
+
background-color: var(--color-surface-elevated);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
.callout {
|
|
290
|
+
background-color: var(--color-surface-elevated);
|
|
291
|
+
border-color: var(--color-border-subtle);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.column-margin, .margin-aside, figcaption {
|
|
295
|
+
color: var(--color-content-secondary);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Elevated cards carry an edge: in dark mode surface.elevated is about 1.06:1
|
|
299
|
+
// against surface.page, so a card without one disappears.
|
|
300
|
+
.di-elevated, div.abstract {
|
|
301
|
+
background-color: var(--color-surface-elevated);
|
|
302
|
+
border: 1px solid var(--color-border-subtle);
|
|
303
|
+
border-radius: var(--radius-md);
|
|
304
|
+
padding: var(--spacing-md);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// ===== THEME TOGGLE STYLING =====
|
|
308
|
+
// Light theme - show moon icon (switch to dark)
|
|
309
|
+
|
|
310
|
+
.quarto-color-scheme-toggle .bi::before {
|
|
311
|
+
display: inline-block !important;
|
|
312
|
+
height: 1rem !important;
|
|
313
|
+
width: 1rem !important;
|
|
314
|
+
content: "" !important;
|
|
315
|
+
vertical-align: -0.125em !important;
|
|
316
|
+
background-repeat: no-repeat !important;
|
|
317
|
+
background-size: 1rem 1rem !important;
|
|
318
|
+
background-color: transparent !important;
|
|
319
|
+
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="%2383838F" class="bi bi-moon" viewBox="0 0 16 16"><path d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278z"/></svg>') !important;
|
|
320
|
+
transition: background-image 0.25s ease;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
.quarto-color-scheme-toggle:hover .bi::before {
|
|
324
|
+
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="%23000000" class="bi bi-moon" viewBox="0 0 16 16"><path d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278z"/></svg>') !important;
|
|
325
|
+
transition: background-image 0.25s ease;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
329
|
+
html {
|
|
330
|
+
scroll-behavior: smooth;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
@media (prefers-reduced-motion: reduce) {
|
|
335
|
+
.quarto-color-scheme-toggle .bi::before {
|
|
336
|
+
transition: none !important;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
-- @dataimago/css@0.1.0-alpha.23 dist/quarto/_extensions/dataimago/pkgsite/filters/landing.lua · sha256:84cdab2c95ff44271f4c3cf044d3a5d4886312d26c97417f276ab45ffa1e20ec · generated from tokens; do not edit · restore: npx -p @dataimago/css@0.1.0-alpha.23 dataimago-sync
|
|
2
|
+
-- landing.lua: replaces the author's `.di-landing` div with the package-site landing stage.
|
|
3
|
+
-- Pandoc 3 Lua filter for Quarto >= 1.8. Metadata comes from `pkgsite` (index.qmd's `metadata-files`
|
|
4
|
+
-- merges the generator's _landing.yml into it). A page with no `.di-landing` div is returned unchanged.
|
|
5
|
+
--
|
|
6
|
+
-- DOM order: pause control, then div.di-landing holding div.di-landing-intro, div.di-landing-overview (the
|
|
7
|
+
-- author's content, still Pandoc blocks), div.di-landing-hero[aria-hidden], nav.di-landing-cards.
|
|
8
|
+
-- The stage, the intro and the overview are real Pandoc Div nodes, never raw open/close tags around Pandoc
|
|
9
|
+
-- content: Quarto's section-divs wraps every heading in <section>, and a section swallows a raw closing tag
|
|
10
|
+
-- that follows it (a README's `##` headings put the hero and the cards inside the overview).
|
|
11
|
+
-- A page that holds a `.di-landing` stage gets `toc: false`: the stage is the page, a TOC beside it is noise.
|
|
12
|
+
-- Layout is pkgsite.scss's job; this file only produces markup.
|
|
13
|
+
--
|
|
14
|
+
-- Only the FIRST `.di-landing` div on a page is the stage; any later one is unwrapped (its content stays in
|
|
15
|
+
-- place, without the class). The name falls back to `pagetitle`, then `title`; with none of them the intro
|
|
16
|
+
-- (and its h1) is omitted. With no cards, nav.di-landing-cards is omitted. The visible pause label lives at the
|
|
17
|
+
-- end of the intro (reachable and in reading order); the checkbox it toggles comes first in the stage.
|
|
18
|
+
|
|
19
|
+
local stringify = pandoc.utils.stringify
|
|
20
|
+
|
|
21
|
+
local function esc(s)
|
|
22
|
+
s = tostring(s or '')
|
|
23
|
+
s = s:gsub('&', '&')
|
|
24
|
+
s = s:gsub('<', '<')
|
|
25
|
+
s = s:gsub('>', '>')
|
|
26
|
+
s = s:gsub('"', '"')
|
|
27
|
+
return s
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
-- Metadata strings arrive as Inlines, parsed as markdown: `<it>` becomes a RawInline and would vanish
|
|
31
|
+
-- under stringify. Rebuild the author's literal text from the inlines instead.
|
|
32
|
+
local function text(v)
|
|
33
|
+
if v == nil then return '' end
|
|
34
|
+
local t = pandoc.utils.type(v)
|
|
35
|
+
if t == 'string' then return v end
|
|
36
|
+
if t == 'boolean' or t == 'number' then return tostring(v) end
|
|
37
|
+
if t == 'Inlines' then
|
|
38
|
+
local out = {}
|
|
39
|
+
for _, el in ipairs(v) do
|
|
40
|
+
if el.t == 'Str' then out[#out + 1] = el.text
|
|
41
|
+
elseif el.t == 'Space' or el.t == 'SoftBreak' then out[#out + 1] = ' '
|
|
42
|
+
elseif el.t == 'RawInline' or el.t == 'Code' then out[#out + 1] = el.text
|
|
43
|
+
else out[#out + 1] = stringify(el) end
|
|
44
|
+
end
|
|
45
|
+
return table.concat(out)
|
|
46
|
+
end
|
|
47
|
+
return stringify(v)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
local function list(v)
|
|
51
|
+
if v == nil then return {} end
|
|
52
|
+
if pandoc.utils.type(v) == 'List' or pandoc.utils.type(v) == 'table' then return v end
|
|
53
|
+
return { v }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
local function dirname(p)
|
|
57
|
+
return (p:match('^(.*)/[^/]*$')) or '.'
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
local function read_file(p)
|
|
61
|
+
local f = io.open(p, 'r')
|
|
62
|
+
if not f then return nil end
|
|
63
|
+
local s = f:read('a')
|
|
64
|
+
f:close()
|
|
65
|
+
return s
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
-- An inlined SVG must start at `<svg`: drop a provenance comment and an xml declaration.
|
|
69
|
+
local function clean_svg(s)
|
|
70
|
+
s = s:gsub('^%s*<%?xml.-%?>%s*', '')
|
|
71
|
+
while s:match('^%s*<!%-%-') do s = s:gsub('^%s*<!%-%-.-%-%->%s*', '', 1) end
|
|
72
|
+
return (s:gsub('%s+$', ''))
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
local function project_dir()
|
|
76
|
+
if quarto and quarto.project and quarto.project.directory then return quarto.project.directory end
|
|
77
|
+
if quarto and quarto.doc and quarto.doc.input_file then return dirname(quarto.doc.input_file) end
|
|
78
|
+
local inputs = PANDOC_STATE and PANDOC_STATE.input_files
|
|
79
|
+
if inputs and inputs[1] then return dirname(inputs[1]) end
|
|
80
|
+
return '.'
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
local function extension_dir()
|
|
84
|
+
local script = PANDOC_SCRIPT_FILE or ''
|
|
85
|
+
return dirname(dirname(script)) -- <ext>/filters/landing.lua -> <ext>
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
local function fail(msg)
|
|
90
|
+
io.stderr:write('ERROR: landing.lua: ' .. msg .. '\n')
|
|
91
|
+
os.exit(1)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
-- hero.src / hero.poster are project-relative: refuse an absolute path or any `..` segment.
|
|
95
|
+
local function check_rel(key, v)
|
|
96
|
+
if v == '' then return end
|
|
97
|
+
if v:sub(1, 1) == '/' or v:sub(1, 1) == '\\' or v:match('^%a[%w+.-]*:') or v:find('\\', 1, true) then
|
|
98
|
+
fail('hero.' .. key .. ' must be a relative path inside the project, got: ' .. v)
|
|
99
|
+
end
|
|
100
|
+
for seg in (v .. '/'):gmatch('([^/]*)/') do
|
|
101
|
+
if seg == '..' then fail('hero.' .. key .. ' must not contain a ".." segment, got: ' .. v) end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
-- Re-validate an SVG before it is inlined into the page: the leaf does not trust the generator's check.
|
|
106
|
+
-- Returns nil when clean, else the reason. Comments are stripped first.
|
|
107
|
+
local function svg_problem(raw)
|
|
108
|
+
local s = raw:gsub('<!%-%-.-%-%->', '')
|
|
109
|
+
local l = s:lower()
|
|
110
|
+
for _, t in ipairs({ 'script', 'foreignobject', 'iframe', 'object', 'embed' }) do
|
|
111
|
+
if l:find('<' .. t .. '[%s/>]') or l:find('<%w+:' .. t .. '[%s/>]') then return 'contains <' .. t .. '>' end
|
|
112
|
+
end
|
|
113
|
+
if l:find('<animate') or l:find('<%w+:animate') then return 'contains a SMIL animate element' end
|
|
114
|
+
if l:find('<set[%s/>]') or l:find('<%w+:set[%s/>]') then return 'contains a SMIL set element' end
|
|
115
|
+
if l:find('javascript:', 1, true) then return 'contains "javascript:"' end
|
|
116
|
+
if l:find('[%s"\'/]on%a+%s*=') then return 'contains an on* event-handler attribute' end
|
|
117
|
+
for body in l:gmatch('<style[^>]*>(.-)</style>') do
|
|
118
|
+
if body:find('<', 1, true) then return 'has "<" inside a <style> element' end
|
|
119
|
+
end
|
|
120
|
+
if l:find('<style[^>]*>[^<]*$') then return 'has an unterminated <style> element' end
|
|
121
|
+
for q, c in l:gmatch('url%s*%(%s*(["\']?)%s*(.?)') do
|
|
122
|
+
if c ~= '#' then return 'has a url() that does not point at a #fragment' end
|
|
123
|
+
end
|
|
124
|
+
for pos in l:gmatch('()href%s*=') do
|
|
125
|
+
local rest = s:sub(pos):match('^href%s*=%s*(.*)$') or ''
|
|
126
|
+
local q = rest:sub(1, 1)
|
|
127
|
+
local v
|
|
128
|
+
if q == '"' or q == "'" then v = rest:match('^' .. q .. '(.-)' .. q) or ''
|
|
129
|
+
else v = rest:match('^([^%s>]*)') end
|
|
130
|
+
if v:gsub('^%s+', ''):sub(1, 1) ~= '#' then return 'has an href that is not a #fragment: ' .. v:sub(1, 60) end
|
|
131
|
+
end
|
|
132
|
+
return nil
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
local function hero_html(hero)
|
|
136
|
+
local kind = text(hero and hero.kind)
|
|
137
|
+
if kind == '' then kind = 'fallback' end
|
|
138
|
+
if hero then
|
|
139
|
+
check_rel('src', text(hero.src))
|
|
140
|
+
check_rel('poster', text(hero.poster))
|
|
141
|
+
end
|
|
142
|
+
local open = '<div class="di-landing-hero" aria-hidden="true">'
|
|
143
|
+
if kind == 'svg' then
|
|
144
|
+
local src = text(hero.src)
|
|
145
|
+
local body = read_file(project_dir() .. '/' .. src)
|
|
146
|
+
if body then
|
|
147
|
+
local why = svg_problem(body)
|
|
148
|
+
if why then fail('hero.src ' .. src .. ' is not safe to inline: ' .. why) end
|
|
149
|
+
return open .. clean_svg(body) .. '</div>'
|
|
150
|
+
end
|
|
151
|
+
io.stderr:write('landing.lua: hero.src not found: ' .. src .. '; using the brand fallback\n')
|
|
152
|
+
elseif kind == 'js' then
|
|
153
|
+
local src, poster, alt = text(hero.src), text(hero.poster), text(hero.alt)
|
|
154
|
+
local img = poster ~= '' and ('<img src="' .. esc(poster) .. '" alt="' .. esc(alt) .. '">') or ''
|
|
155
|
+
return open .. '<div class="di-hero-mount" data-hero-src="' .. esc(src) .. '" data-hero-poster="'
|
|
156
|
+
.. esc(poster) .. '">' .. img .. '</div><script type="module" src="pkgsite-hero.js"></script></div>'
|
|
157
|
+
end
|
|
158
|
+
local body = read_file(extension_dir() .. '/hero-fallback.svg')
|
|
159
|
+
return open .. (body and clean_svg(body) or '') .. '</div>'
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
local function build(div, meta)
|
|
163
|
+
local p = meta.pkgsite or {}
|
|
164
|
+
local out = pandoc.List()
|
|
165
|
+
local stage = pandoc.List()
|
|
166
|
+
local function raw(s) stage:insert(pandoc.RawBlock('html', s)) end
|
|
167
|
+
|
|
168
|
+
local label = '<label class="di-hero-pause-label" for="di-hero-pause">'
|
|
169
|
+
.. '<span class="di-pause-on">Pause animation</span><span class="di-pause-off">Play animation</span></label>'
|
|
170
|
+
out:insert(pandoc.RawBlock('html', '<input type="checkbox" id="di-hero-pause" class="di-hero-pause-input">'))
|
|
171
|
+
|
|
172
|
+
local name = text(p.name)
|
|
173
|
+
if name == '' then name = text(meta.pagetitle) end
|
|
174
|
+
if name == '' then name = text(meta.title) end
|
|
175
|
+
if name ~= '' then
|
|
176
|
+
local intro = pandoc.List()
|
|
177
|
+
local function iraw(s) intro:insert(pandoc.RawBlock('html', s)) end
|
|
178
|
+
iraw('<h1 class="di-landing-name">' .. esc(name) .. '</h1>')
|
|
179
|
+
if text(p.title) ~= '' then iraw('<p class="di-landing-title">' .. esc(text(p.title)) .. '</p>') end
|
|
180
|
+
if text(p.version) ~= '' then iraw('<p class="di-landing-version">Version ' .. esc(text(p.version)) .. '</p>') end
|
|
181
|
+
local links = list(p.links)
|
|
182
|
+
if #links > 0 then
|
|
183
|
+
iraw('<ul class="pill-links">')
|
|
184
|
+
for _, l in ipairs(links) do
|
|
185
|
+
local a = pandoc.Link({ pandoc.Str(text(l.text)) }, text(l.href))
|
|
186
|
+
intro:insert(pandoc.Plain({ pandoc.RawInline('html', '<li>'), a, pandoc.RawInline('html', '</li>') }))
|
|
187
|
+
end
|
|
188
|
+
iraw('</ul>')
|
|
189
|
+
end
|
|
190
|
+
iraw('<p class="di-hero-pause">' .. label .. '</p>')
|
|
191
|
+
stage:insert(pandoc.Div(intro, pandoc.Attr('', { 'di-landing-intro' })))
|
|
192
|
+
else
|
|
193
|
+
raw('<div class="di-landing-controls"><p class="di-hero-pause">' .. label .. '</p></div>')
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
local content = nil
|
|
197
|
+
for _, b in ipairs(div.content) do
|
|
198
|
+
if b.t == 'Div' and b.classes:includes('di-landing-overview') then content = b.content end
|
|
199
|
+
end
|
|
200
|
+
stage:insert(pandoc.Div(content or div.content, pandoc.Attr('', { 'di-landing-overview' })))
|
|
201
|
+
|
|
202
|
+
raw(hero_html(p.hero))
|
|
203
|
+
|
|
204
|
+
local cards = list(p.cards)
|
|
205
|
+
if #cards > 0 then raw('<nav class="di-landing-cards" aria-label="Sections">') end
|
|
206
|
+
for _, c in ipairs(cards) do
|
|
207
|
+
local inl = {
|
|
208
|
+
pandoc.Span({ pandoc.Str(text(c.title)) }, pandoc.Attr('', { 'di-card-title' })),
|
|
209
|
+
pandoc.Span({ pandoc.Str(text(c.desc)) }, pandoc.Attr('', { 'di-card-desc' })),
|
|
210
|
+
}
|
|
211
|
+
local a = pandoc.Link(inl, text(c.href), '', pandoc.Attr('', { 'di-card' }, { { 'data-card', text(c.key) } }))
|
|
212
|
+
stage:insert(pandoc.Plain({ a }))
|
|
213
|
+
end
|
|
214
|
+
if #cards > 0 then raw('</nav>') end
|
|
215
|
+
out:insert(pandoc.Div(stage, pandoc.Attr('', { 'di-landing' })))
|
|
216
|
+
return out
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
function Pandoc(doc)
|
|
220
|
+
local found = false
|
|
221
|
+
local result = doc:walk({
|
|
222
|
+
Div = function(div)
|
|
223
|
+
if div.classes:includes('di-landing') then
|
|
224
|
+
if found then return div.content end -- a later one: unwrapped, content stays in place
|
|
225
|
+
found = true
|
|
226
|
+
return build(div, doc.meta)
|
|
227
|
+
end
|
|
228
|
+
end,
|
|
229
|
+
})
|
|
230
|
+
if not found then return nil end
|
|
231
|
+
result.meta.toc = false
|
|
232
|
+
return result
|
|
233
|
+
end
|