datalog-theme 0.6.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.
Files changed (180) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +162 -0
  3. data/CITATION.cff +29 -0
  4. data/LICENSE +21 -0
  5. data/README.md +257 -0
  6. data/_data/academic.yml +217 -0
  7. data/_data/cdn-integrity.yml +51 -0
  8. data/_data/config/author.yml +121 -0
  9. data/_data/config/features.yml +262 -0
  10. data/_data/config/site.yml +42 -0
  11. data/_data/config/theme.yml +181 -0
  12. data/_data/datasets.yml +28 -0
  13. data/_data/i18n/en.yml +438 -0
  14. data/_data/i18n/es.yml +438 -0
  15. data/_data/i18n/pt.yml +438 -0
  16. data/_data/js_manifest.json +22 -0
  17. data/_data/js_meta.json +371 -0
  18. data/_data/navigation.yml +145 -0
  19. data/_data/projects.yml +41 -0
  20. data/_data/publications.yml +28 -0
  21. data/_data/social.yml +73 -0
  22. data/_data/visualizations.yml +51 -0
  23. data/_includes/analytics/dashboard.html +149 -0
  24. data/_includes/analytics.html +9 -0
  25. data/_includes/components/academic-dashboard.html +347 -0
  26. data/_includes/components/advanced-search.html +682 -0
  27. data/_includes/components/api-function.html +94 -0
  28. data/_includes/components/author-bio.html +166 -0
  29. data/_includes/components/bookmark-system.html +96 -0
  30. data/_includes/components/breadcrumbs.html +89 -0
  31. data/_includes/components/citation-tools.html +94 -0
  32. data/_includes/components/comments.html +244 -0
  33. data/_includes/components/content-provenance.html +43 -0
  34. data/_includes/components/content-recommendations.html +228 -0
  35. data/_includes/components/difficulty-badge.html +84 -0
  36. data/_includes/components/email-preferences.html +200 -0
  37. data/_includes/components/enhanced-code-block.html +212 -0
  38. data/_includes/components/enhanced-metadata.html +228 -0
  39. data/_includes/components/enhanced-toc.html +209 -0
  40. data/_includes/components/hero.html +15 -0
  41. data/_includes/components/language-switcher.html +396 -0
  42. data/_includes/components/math-fallback.html +19 -0
  43. data/_includes/components/navigation-enhancements.html +454 -0
  44. data/_includes/components/newsletter-signup.html +178 -0
  45. data/_includes/components/open-science-badges.html +16 -0
  46. data/_includes/components/package-install.html +194 -0
  47. data/_includes/components/performance-monitor.html +170 -0
  48. data/_includes/components/popular-posts.html +233 -0
  49. data/_includes/components/post-hero.html +62 -0
  50. data/_includes/components/reading-progress.html +133 -0
  51. data/_includes/components/reading-time.html +121 -0
  52. data/_includes/components/responsive-image.html +63 -0
  53. data/_includes/components/search-facets.html +307 -0
  54. data/_includes/components/series-navigation.html +124 -0
  55. data/_includes/components/social-proof.html +34 -0
  56. data/_includes/components/social-share.html +119 -0
  57. data/_includes/components/user-preferences.html +566 -0
  58. data/_includes/components/visualization-card.html +24 -0
  59. data/_includes/components/viz-table-fallback.html +19 -0
  60. data/_includes/critical-css/default.html +0 -0
  61. data/_includes/critical-css/home.html +0 -0
  62. data/_includes/critical-css/post.html +0 -0
  63. data/_includes/csp-meta.html +17 -0
  64. data/_includes/footer/nav-column.html +31 -0
  65. data/_includes/footer.html +76 -0
  66. data/_includes/head.html +337 -0
  67. data/_includes/header/navigation.html +48 -0
  68. data/_includes/header.html +70 -0
  69. data/_includes/helpers/array-to-sentence.html +21 -0
  70. data/_includes/helpers/date-format.html +16 -0
  71. data/_includes/helpers/link-with-icon.html +26 -0
  72. data/_includes/layouts/default/article.html +67 -0
  73. data/_includes/meta/language-attributes.html +25 -0
  74. data/_includes/meta/math-config.html +21 -0
  75. data/_includes/meta/schema.html +153 -0
  76. data/_includes/meta/scripts-loader.html +52 -0
  77. data/_includes/post/related-posts.html +63 -0
  78. data/_includes/scripts.html +72 -0
  79. data/_includes/skip-link.html +1 -0
  80. data/_includes/toc.html +2 -0
  81. data/_layouts/archive.html +282 -0
  82. data/_layouts/dataset.html +52 -0
  83. data/_layouts/default.html +33 -0
  84. data/_layouts/home.html +48 -0
  85. data/_layouts/notebook.html +173 -0
  86. data/_layouts/package.html +238 -0
  87. data/_layouts/page.html +16 -0
  88. data/_layouts/portfolio.html +41 -0
  89. data/_layouts/post-sidebar.html +183 -0
  90. data/_layouts/post.html +338 -0
  91. data/_layouts/project.html +252 -0
  92. data/_layouts/research.html +504 -0
  93. data/_plugins/analytics_dashboard.rb +315 -0
  94. data/_plugins/config_validator.rb +397 -0
  95. data/_plugins/csp_generator.rb +115 -0
  96. data/_plugins/datalog_bibliography.rb +19 -0
  97. data/_plugins/datalog_comments.rb +18 -0
  98. data/_plugins/datalog_slides.rb +20 -0
  99. data/_plugins/front_matter_compat.rb +109 -0
  100. data/_plugins/i18n.rb +160 -0
  101. data/_plugins/image_optimizer.rb +445 -0
  102. data/_plugins/math_preprocessor.rb +185 -0
  103. data/_plugins/notebook_converter.rb +1107 -0
  104. data/_plugins/plugin_loader.rb +185 -0
  105. data/_plugins/publications_generator.rb +234 -0
  106. data/_plugins/reading_time.rb +15 -0
  107. data/_plugins/search_normalizer.rb +74 -0
  108. data/_plugins/sri_filter.rb +18 -0
  109. data/_plugins/toc_filter.rb +68 -0
  110. data/_plugins/warning_filter.rb +3 -0
  111. data/_sass/_base.scss +142 -0
  112. data/_sass/_components.scss +2380 -0
  113. data/_sass/_header.scss +470 -0
  114. data/_sass/_interactive.scss +344 -0
  115. data/_sass/_layout.scss +1760 -0
  116. data/_sass/_mathematical.scss +368 -0
  117. data/_sass/_mixins.scss +99 -0
  118. data/_sass/_package-docs.scss +715 -0
  119. data/_sass/_phase1-enhancements.scss +721 -0
  120. data/_sass/_phase3-enhancements.scss +874 -0
  121. data/_sass/_phase4-enhancements.scss +1214 -0
  122. data/_sass/_phase5-enhancements.scss +414 -0
  123. data/_sass/_search.scss +654 -0
  124. data/_sass/_syntax-highlighting.scss +128 -0
  125. data/_sass/_theme.scss +79 -0
  126. data/_sass/_typography.scss +148 -0
  127. data/_sass/_utilities.scss +334 -0
  128. data/_sass/_variables.scss +153 -0
  129. data/_sass/_visualizations.scss +242 -0
  130. data/assets/css/main.scss +4 -0
  131. data/assets/img/20220607123041_detail.001.png +0 -0
  132. data/assets/img/favicons/android-chrome-192x192.png +0 -0
  133. data/assets/img/favicons/android-chrome-512x512.png +0 -0
  134. data/assets/img/favicons/apple-touch-icon.png +0 -0
  135. data/assets/img/favicons/favicon-16x16.png +0 -0
  136. data/assets/img/favicons/favicon-32x32.png +0 -0
  137. data/assets/img/favicons/favicon.ico +0 -0
  138. data/assets/img/favicons/site.webmanifest +21 -0
  139. data/assets/img/portfolio-placeholder.svg +20 -0
  140. data/assets/js/academic.js +262 -0
  141. data/assets/js/analytics-dashboard.js +382 -0
  142. data/assets/js/core/dark-mode.js +79 -0
  143. data/assets/js/core/github-cards.js +123 -0
  144. data/assets/js/core/language-filter.js +69 -0
  145. data/assets/js/core/navigation.js +184 -0
  146. data/assets/js/core/scroll-progress.js +45 -0
  147. data/assets/js/core/search-hotkeys.js +62 -0
  148. data/assets/js/core/skip-links.js +62 -0
  149. data/assets/js/loader.js +163 -0
  150. data/assets/js/main.js +23 -0
  151. data/assets/js/math.js +818 -0
  152. data/assets/js/notebook.js +158 -0
  153. data/assets/js/search/analytics.js +91 -0
  154. data/assets/js/search/app.js +271 -0
  155. data/assets/js/search/autocomplete.js +120 -0
  156. data/assets/js/search/engine.js +260 -0
  157. data/assets/js/search/filters.js +38 -0
  158. data/assets/js/search/render.js +217 -0
  159. data/assets/js/search/utils.js +99 -0
  160. data/assets/js/search.js +354 -0
  161. data/assets/js/visualizations.js +816 -0
  162. data/assets/publications/datalog-publications.bib +8 -0
  163. data/assets/publications/datalog-publications.ris +9 -0
  164. data/assets/publications/publications.bib +30 -0
  165. data/assets/templates/diogo-ribeiro-cv.md +31 -0
  166. data/assets/templates/diogo-ribeiro-cv.tex +32 -0
  167. data/bin/datalog +26 -0
  168. data/datalog-theme.gemspec +72 -0
  169. data/lib/datalog/cli.rb +563 -0
  170. data/lib/datalog/plugin_system/dependency_resolver.rb +223 -0
  171. data/lib/datalog/plugin_system.rb +237 -0
  172. data/lib/datalog/plugins/citations.rb +182 -0
  173. data/lib/datalog/plugins/comments.rb +183 -0
  174. data/lib/datalog/plugins/search.rb +45 -0
  175. data/lib/datalog/plugins/slides.rb +121 -0
  176. data/lib/datalog/theme/theme.rb +18 -0
  177. data/lib/datalog/theme/version.rb +7 -0
  178. data/lib/datalog/warning_filter.rb +28 -0
  179. data/lib/datalog-theme.rb +17 -0
  180. metadata +555 -0
@@ -0,0 +1,2380 @@
1
+ @use 'sass:map';
2
+ @use "sass:color";
3
+
4
+ @use 'variables' as *;
5
+ @use 'mixins' as *;
6
+
7
+ .card {
8
+ background: white;
9
+ border-radius: 0.75rem;
10
+ padding: map.get($spacing, 5);
11
+ box-shadow: 0 1px 3px rgba(15, 23, 42, 0.06), 0 4px 12px rgba(15, 23, 42, 0.04);
12
+ border: 1px solid rgba($color-neutral-200, 0.5);
13
+ display: grid;
14
+ gap: map.get($spacing, 2);
15
+ transition: box-shadow $transition-base, transform $transition-base, border-color $transition-base;
16
+
17
+ &:hover {
18
+ box-shadow: 0 4px 16px rgba(15, 23, 42, 0.1), 0 8px 24px rgba(15, 23, 42, 0.06);
19
+ transform: translateY(-2px);
20
+ border-color: rgba($color-accent-primary, 0.2);
21
+ }
22
+
23
+ h3 {
24
+ font-size: map.get($font-size-scale, md);
25
+ margin: 0;
26
+ line-height: $line-height-tight;
27
+
28
+ a {
29
+ color: $color-ink-900;
30
+ text-decoration: none;
31
+
32
+ &:hover { color: $color-accent-primary; }
33
+ }
34
+ }
35
+
36
+ p {
37
+ margin: 0;
38
+ font-size: map.get($font-size-scale, sm);
39
+ color: $color-ink-500;
40
+ line-height: $line-height-base;
41
+ }
42
+ }
43
+
44
+ body.dark-mode .card {
45
+ background: rgba($dark-surface-200, 0.85);
46
+ border-color: rgba($dark-ink-500, 0.15);
47
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
48
+
49
+ &:hover {
50
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
51
+ border-color: rgba($dark-accent-primary, 0.25);
52
+ }
53
+
54
+ h3 a { color: $dark-ink-900; &:hover { color: $dark-accent-primary; } }
55
+ p { color: $dark-ink-500; }
56
+ }
57
+
58
+ .card--highlight {
59
+ border-color: rgba($color-accent-primary, 0.3);
60
+ box-shadow: 0 4px 16px rgba($color-accent-primary, 0.12);
61
+ }
62
+
63
+ // ---------------------------------------------------------------------------
64
+ // Buttons
65
+ // ---------------------------------------------------------------------------
66
+ .btn {
67
+ display: inline-flex;
68
+ align-items: center;
69
+ gap: 0.375rem;
70
+ padding: 0.625rem 1.5rem;
71
+ border-radius: 999px;
72
+ font-weight: 600;
73
+ font-size: map.get($font-size-scale, sm);
74
+ text-decoration: none;
75
+ border: 1px solid transparent;
76
+ cursor: pointer;
77
+ transition: background 0.2s ease, box-shadow 0.2s ease, transform 0.15s ease;
78
+ letter-spacing: 0.01em;
79
+ }
80
+
81
+ .btn-primary {
82
+ background: $color-accent-primary;
83
+ color: #fff;
84
+
85
+ &:hover {
86
+ background: color.adjust($color-accent-primary, $lightness: 6%);
87
+ box-shadow: 0 6px 20px rgba($color-accent-primary, 0.35);
88
+ transform: translateY(-1px);
89
+ }
90
+ }
91
+
92
+ .btn-secondary {
93
+ background: transparent;
94
+ color: $color-accent-primary;
95
+ border-color: $color-accent-primary;
96
+
97
+ &:hover {
98
+ background: rgba($color-accent-primary, 0.08);
99
+ }
100
+ }
101
+
102
+ body.dark-mode .btn-primary {
103
+ background: $dark-accent-primary;
104
+ color: $color-surface-900;
105
+ }
106
+
107
+ body.dark-mode .btn-secondary {
108
+ color: $dark-accent-primary;
109
+ border-color: $dark-accent-primary;
110
+ }
111
+
112
+ .stat {
113
+ display: grid;
114
+ gap: map.get($spacing, 1);
115
+ font-family: $font-family-mono;
116
+ background: rgba($color-accent-secondary, 0.08);
117
+ border-radius: 0.75rem;
118
+ padding: map.get($spacing, 4);
119
+ }
120
+
121
+ .stat__label {
122
+ font-size: map.get($font-size-scale, xs);
123
+ text-transform: uppercase;
124
+ letter-spacing: 0.1em;
125
+ }
126
+
127
+ .stat__value {
128
+ font-size: 1.75rem;
129
+ color: $color-accent-secondary;
130
+ }
131
+
132
+ body.dark-mode .stat {
133
+ background: rgba($dark-accent-secondary, 0.15);
134
+ }
135
+
136
+ .code-toolbar {
137
+ position: relative;
138
+ margin-bottom: map.get($spacing, 2);
139
+ display: flex;
140
+ justify-content: space-between;
141
+ align-items: center;
142
+ font-size: map.get($font-size-scale, xs);
143
+ color: $color-ink-500;
144
+ }
145
+
146
+ .code-toolbar__language {
147
+ letter-spacing: 0.1em;
148
+ text-transform: uppercase;
149
+ }
150
+
151
+ .code-toolbar__copy {
152
+ border: none;
153
+ background: rgba($color-ink-900, 0.05);
154
+ padding: map.get($spacing, 2) map.get($spacing, 3);
155
+ border-radius: 0.5rem;
156
+ font-size: map.get($font-size-scale, xs);
157
+ display: inline-flex;
158
+ align-items: center;
159
+ gap: map.get($spacing, 1);
160
+
161
+ &:hover,
162
+ &:focus {
163
+ background: rgba($color-accent-primary, 0.15);
164
+ }
165
+ }
166
+
167
+ body.dark-mode .code-toolbar {
168
+ color: rgba($dark-ink-500, 0.85);
169
+ }
170
+
171
+ body.dark-mode .code-toolbar__copy {
172
+ background: rgba($dark-surface-300, 0.65);
173
+
174
+ &:hover,
175
+ &:focus {
176
+ background: rgba($dark-accent-primary, 0.25);
177
+ }
178
+ }
179
+
180
+ pre {
181
+ @include code-block();
182
+ }
183
+
184
+ body.dark-mode pre {
185
+ @include code-block(rgba($dark-surface-300, 0.65));
186
+ border-color: rgba($dark-ink-500, 0.35);
187
+ box-shadow: none;
188
+ }
189
+
190
+ .dataset-meta,
191
+ .project-meta,
192
+ .research-meta {
193
+ @include data-grid(16rem);
194
+ }
195
+
196
+ .dataset-meta dt,
197
+ .project-meta dt,
198
+ .research-meta dt {
199
+ font-size: map.get($font-size-scale, xs);
200
+ text-transform: uppercase;
201
+ letter-spacing: 0.12em;
202
+ color: $color-ink-500;
203
+ }
204
+
205
+ .dataset-meta dd,
206
+ .project-meta dd,
207
+ .research-meta dd {
208
+ font-size: map.get($font-size-scale, md);
209
+ color: $color-ink-900;
210
+ margin: 0;
211
+ }
212
+
213
+ body.dark-mode .dataset-meta dt,
214
+ body.dark-mode .project-meta dt,
215
+ body.dark-mode .research-meta dt {
216
+ color: rgba($dark-ink-500, 0.85);
217
+ }
218
+
219
+ body.dark-mode .dataset-meta dd,
220
+ body.dark-mode .project-meta dd,
221
+ body.dark-mode .research-meta dd {
222
+ color: $dark-ink-900;
223
+ }
224
+
225
+ .metric-grid {
226
+ @include data-grid(14rem, map.get($spacing, 4));
227
+ }
228
+
229
+ .metric {
230
+ padding: map.get($spacing, 4);
231
+ border-radius: 0.75rem;
232
+ border: 1px dashed rgba($color-accent-primary, 0.4);
233
+ background: rgba($color-accent-primary, 0.04);
234
+ }
235
+
236
+ body.dark-mode .metric {
237
+ border-color: rgba($dark-accent-primary, 0.5);
238
+ background: rgba($dark-accent-primary, 0.18);
239
+ }
240
+
241
+ .callout {
242
+ @include callout();
243
+ }
244
+
245
+ .callout--warning {
246
+ @include callout($color-warning);
247
+ }
248
+
249
+ .callout--danger {
250
+ @include callout($color-critical);
251
+ }
252
+
253
+ .academic-card {
254
+ padding: map.get($spacing, 5);
255
+ border-radius: 1rem;
256
+ background: linear-gradient(135deg, rgba($color-accent-primary, 0.1), rgba($color-accent-tertiary, 0.1));
257
+ border: 1px solid rgba($color-accent-primary, 0.35);
258
+ }
259
+
260
+ body.dark-mode .academic-card {
261
+ background: linear-gradient(135deg, rgba($dark-accent-primary, 0.2), rgba($dark-accent-secondary, 0.2));
262
+ border-color: rgba($dark-accent-primary, 0.55);
263
+ }
264
+
265
+ .viz-container {
266
+ @include responsive-chart();
267
+ }
268
+
269
+ .dataset-license {
270
+ font-size: map.get($font-size-scale, sm);
271
+ color: $color-ink-500;
272
+ padding: map.get($spacing, 3);
273
+ border: 1px solid rgba($color-neutral-200, 0.8);
274
+ border-radius: 0.75rem;
275
+ background: rgba($color-neutral-100, 0.6);
276
+ }
277
+
278
+ body.dark-mode .dataset-license {
279
+ color: rgba($dark-ink-500, 0.9);
280
+ border-color: rgba($dark-ink-500, 0.35);
281
+ background: rgba($dark-surface-300, 0.75);
282
+ }
283
+
284
+ .footer-grid {
285
+ @include data-grid(16rem);
286
+ align-items: start;
287
+ }
288
+
289
+ .footer-column {
290
+ display: grid;
291
+ gap: map.get($spacing, 2);
292
+ font-size: map.get($font-size-scale, sm);
293
+ }
294
+
295
+ .footer-heading {
296
+ font-size: map.get($font-size-scale, md);
297
+ font-weight: 600;
298
+ }
299
+
300
+ //
301
+ // Code & computational content
302
+ // ------------------------------------------------------------
303
+
304
+ .code-block {
305
+ position: relative;
306
+ margin: map.get($spacing, 5) 0;
307
+ border-radius: 0.85rem;
308
+ overflow: hidden;
309
+ background: rgba($color-surface-900, 0.02);
310
+ border: 1px solid rgba($color-ink-900, 0.08);
311
+
312
+ pre {
313
+ margin: 0;
314
+ border-radius: 0;
315
+ padding-top: map.get($spacing, 6);
316
+ }
317
+ }
318
+
319
+ .code-block__header {
320
+ position: absolute;
321
+ top: 0;
322
+ right: 0;
323
+ left: 0;
324
+ display: flex;
325
+ align-items: center;
326
+ justify-content: space-between;
327
+ padding: map.get($spacing, 3) map.get($spacing, 5);
328
+ font-size: map.get($font-size-scale, xs);
329
+ letter-spacing: 0.08em;
330
+ text-transform: uppercase;
331
+ color: $color-ink-500;
332
+ background: linear-gradient(
333
+ 180deg,
334
+ rgba($color-surface-900, 0.9) 0%,
335
+ rgba($color-surface-900, 0.05) 75%,
336
+ transparent 100%
337
+ );
338
+ pointer-events: none;
339
+
340
+ > * {
341
+ pointer-events: auto;
342
+ }
343
+ }
344
+
345
+ .code-block__language {
346
+ font-family: $font-family-mono;
347
+ }
348
+
349
+ .code-block__copy {
350
+ border: 1px solid rgba($color-ink-900, 0.08);
351
+ border-radius: 999px;
352
+ padding: map.get($spacing, 1) map.get($spacing, 3);
353
+ background: rgba($color-ink-900, 0.04);
354
+ color: inherit;
355
+ display: inline-flex;
356
+ align-items: center;
357
+ gap: map.get($spacing, 2);
358
+ cursor: pointer;
359
+ transition: background 200ms ease, color 200ms ease;
360
+
361
+ &:hover,
362
+ &:focus-visible {
363
+ background: rgba($color-accent-primary, 0.16);
364
+ color: $color-accent-primary;
365
+ }
366
+
367
+ &:focus-visible {
368
+ @include focus-ring($color-accent-primary);
369
+ }
370
+ }
371
+
372
+ .code-block--numbered {
373
+ counter-reset: line;
374
+
375
+ code > span {
376
+ position: relative;
377
+ display: block;
378
+ padding-left: map.get($spacing, 8) + map.get($spacing, 2);
379
+ counter-increment: line;
380
+
381
+ &::before {
382
+ content: counter(line);
383
+ position: absolute;
384
+ left: map.get($spacing, 2);
385
+ color: rgba($color-ink-500, 0.75);
386
+ font-variant-numeric: tabular-nums;
387
+ font-size: map.get($font-size-scale, xs);
388
+ }
389
+ }
390
+ }
391
+
392
+ .code-block__annotations {
393
+ display: flex;
394
+ flex-wrap: wrap;
395
+ gap: map.get($spacing, 2);
396
+ margin-top: map.get($spacing, 3);
397
+ font-size: map.get($font-size-scale, xs);
398
+ color: $color-ink-500;
399
+ }
400
+
401
+ body.dark-mode .code-block {
402
+ background: rgba($dark-surface-300, 0.75);
403
+ border-color: rgba($dark-ink-500, 0.35);
404
+
405
+ .code-block__header {
406
+ color: rgba($dark-ink-500, 0.85);
407
+ background: linear-gradient(
408
+ 180deg,
409
+ rgba($dark-surface-100, 0.75) 0%,
410
+ rgba($dark-surface-300, 0.4) 70%,
411
+ transparent 100%
412
+ );
413
+ }
414
+
415
+ .code-block__copy {
416
+ border-color: rgba($dark-ink-500, 0.35);
417
+ background: rgba($dark-surface-100, 0.35);
418
+
419
+ &:hover,
420
+ &:focus-visible {
421
+ background: rgba($dark-accent-primary, 0.35);
422
+ color: $dark-accent-primary;
423
+ }
424
+ }
425
+
426
+ &.code-block--numbered code > span::before {
427
+ color: rgba($dark-ink-500, 0.7);
428
+ }
429
+ }
430
+
431
+ //
432
+ // Mathematical presentation
433
+ // ------------------------------------------------------------
434
+
435
+ .equation-block {
436
+ margin: map.get($spacing, 6) auto;
437
+ padding: map.get($spacing, 5);
438
+ border-radius: 0.85rem;
439
+ background: rgba($color-accent-secondary, 0.05);
440
+ border: 1px solid rgba($color-accent-secondary, 0.3);
441
+ display: grid;
442
+ gap: map.get($spacing, 3);
443
+ justify-items: center;
444
+ }
445
+
446
+ .equation-block__math {
447
+ @include math-display;
448
+ }
449
+
450
+ .equation-block__number {
451
+ align-self: end;
452
+ justify-self: end;
453
+ font-size: map.get($font-size-scale, xs);
454
+ color: $color-ink-500;
455
+ font-variant-numeric: tabular-nums;
456
+ }
457
+
458
+ .equation-block__context {
459
+ font-size: map.get($font-size-scale, sm);
460
+ color: $color-ink-600;
461
+ text-align: center;
462
+ }
463
+
464
+ body.dark-mode .equation-block {
465
+ background: rgba($dark-accent-secondary, 0.18);
466
+ border-color: rgba($dark-accent-secondary, 0.5);
467
+
468
+ .equation-block__number,
469
+ .equation-block__context {
470
+ color: rgba($dark-ink-500, 0.85);
471
+ }
472
+ }
473
+
474
+ //
475
+ // Interactive visualization wrappers
476
+ // ------------------------------------------------------------
477
+
478
+ .viz-frame {
479
+ position: relative;
480
+ border-radius: 1rem;
481
+ border: 1px solid rgba($color-accent-primary, 0.28);
482
+ background: rgba($color-accent-primary, 0.05);
483
+ padding: map.get($spacing, 4);
484
+ display: grid;
485
+ gap: map.get($spacing, 3);
486
+ }
487
+
488
+ .viz-frame__header {
489
+ display: flex;
490
+ align-items: center;
491
+ justify-content: space-between;
492
+ gap: map.get($spacing, 3);
493
+ font-size: map.get($font-size-scale, sm);
494
+ }
495
+
496
+ .viz-frame__meta {
497
+ display: inline-flex;
498
+ gap: map.get($spacing, 2);
499
+ font-size: map.get($font-size-scale, xs);
500
+ color: $color-ink-500;
501
+ }
502
+
503
+ .viz-frame__body {
504
+ @include responsive-chart();
505
+ background: rgba($color-surface-900, 0.02);
506
+ }
507
+
508
+ body.dark-mode .viz-frame {
509
+ border-color: rgba($dark-accent-primary, 0.5);
510
+ background: rgba($dark-accent-primary, 0.2);
511
+
512
+ .viz-frame__meta {
513
+ color: rgba($dark-ink-500, 0.85);
514
+ }
515
+ }
516
+
517
+ //
518
+ // Dataset & research components
519
+ // ------------------------------------------------------------
520
+
521
+ .dataset-card {
522
+ border-radius: 1rem;
523
+ border: 1px solid rgba($color-neutral-300, 0.9);
524
+ padding: map.get($spacing, 5);
525
+ display: grid;
526
+ gap: map.get($spacing, 4);
527
+ background: linear-gradient(135deg, rgba($color-neutral-100, 0.85), rgba($color-neutral-200, 0.5));
528
+ }
529
+
530
+ .dataset-card__header {
531
+ display: flex;
532
+ justify-content: space-between;
533
+ gap: map.get($spacing, 3);
534
+ align-items: baseline;
535
+ }
536
+
537
+ .dataset-card__title {
538
+ font-size: map.get($font-size-scale, lg);
539
+ font-weight: 600;
540
+ }
541
+
542
+ .dataset-card__meta {
543
+ display: flex;
544
+ flex-wrap: wrap;
545
+ gap: map.get($spacing, 2);
546
+ font-size: map.get($font-size-scale, xs);
547
+ color: $color-ink-500;
548
+ }
549
+
550
+ .dataset-card__downloads {
551
+ display: inline-flex;
552
+ gap: map.get($spacing, 2);
553
+ align-items: center;
554
+
555
+ .button {
556
+ font-size: map.get($font-size-scale, xs);
557
+ }
558
+ }
559
+
560
+ .dataset-card__license {
561
+ font-size: map.get($font-size-scale, xs);
562
+ color: $color-ink-600;
563
+ padding: map.get($spacing, 2) map.get($spacing, 3);
564
+ border-radius: 0.5rem;
565
+ background: rgba($color-accent-secondary, 0.12);
566
+ border: 1px solid rgba($color-accent-secondary, 0.35);
567
+ }
568
+
569
+ .citation-block {
570
+ border-left: 4px solid $color-accent-tertiary;
571
+ padding: map.get($spacing, 4) map.get($spacing, 5);
572
+ background: rgba($color-accent-tertiary, 0.08);
573
+ border-radius: 0.75rem;
574
+ display: grid;
575
+ gap: map.get($spacing, 3);
576
+ }
577
+
578
+ .citation-block__meta {
579
+ display: flex;
580
+ flex-wrap: wrap;
581
+ gap: map.get($spacing, 2);
582
+ font-size: map.get($font-size-scale, xs);
583
+ color: $color-ink-500;
584
+ }
585
+
586
+ .citation-block__actions {
587
+ display: flex;
588
+ flex-wrap: wrap;
589
+ gap: map.get($spacing, 2);
590
+ }
591
+
592
+ body.dark-mode {
593
+ .dataset-card {
594
+ border-color: rgba($dark-ink-500, 0.45);
595
+ background: linear-gradient(135deg, rgba($dark-surface-200, 0.85), rgba($dark-surface-300, 0.6));
596
+ }
597
+
598
+ .dataset-card__meta,
599
+ .dataset-card__license {
600
+ color: rgba($dark-ink-500, 0.85);
601
+ }
602
+
603
+ .citation-block {
604
+ background: rgba($dark-accent-tertiary, 0.25);
605
+ border-left-color: $dark-accent-tertiary;
606
+ }
607
+
608
+ .citation-block__meta {
609
+ color: rgba($dark-ink-500, 0.8);
610
+ }
611
+ }
612
+
613
+ //
614
+ // Project showcases & performance
615
+ // ------------------------------------------------------------
616
+
617
+ .project-card {
618
+ border-radius: 1rem;
619
+ border: 1px solid rgba($color-accent-primary, 0.25);
620
+ padding: map.get($spacing, 5);
621
+ display: grid;
622
+ gap: map.get($spacing, 4);
623
+ background: rgba($color-accent-primary, 0.06);
624
+ }
625
+
626
+ .project-card__header {
627
+ display: flex;
628
+ flex-wrap: wrap;
629
+ gap: map.get($spacing, 3);
630
+ justify-content: space-between;
631
+ align-items: baseline;
632
+ }
633
+
634
+ .project-card__tech {
635
+ display: flex;
636
+ flex-wrap: wrap;
637
+ gap: map.get($spacing, 2);
638
+ }
639
+
640
+ .tech-badge {
641
+ display: inline-flex;
642
+ align-items: center;
643
+ gap: map.get($spacing, 1);
644
+ padding: map.get($spacing, 1) map.get($spacing, 3);
645
+ border-radius: 999px;
646
+ font-size: map.get($font-size-scale, xs);
647
+ background: rgba($color-accent-primary, 0.12);
648
+ border: 1px solid rgba($color-accent-primary, 0.3);
649
+ }
650
+
651
+ .project-card__stats {
652
+ display: grid;
653
+ gap: map.get($spacing, 3);
654
+ font-size: map.get($font-size-scale, sm);
655
+ color: $color-ink-600;
656
+ }
657
+
658
+ .performance-metric {
659
+ display: grid;
660
+ gap: map.get($spacing, 1);
661
+ padding: map.get($spacing, 3);
662
+ border-radius: 0.75rem;
663
+ background: rgba($color-accent-secondary, 0.1);
664
+ border: 1px solid rgba($color-accent-secondary, 0.35);
665
+ }
666
+
667
+ .performance-metric__label {
668
+ font-size: map.get($font-size-scale, xs);
669
+ letter-spacing: 0.08em;
670
+ text-transform: uppercase;
671
+ color: $color-ink-500;
672
+ }
673
+
674
+ .performance-metric__value {
675
+ font-family: $font-family-mono;
676
+ font-size: map.get($font-size-scale, lg);
677
+ }
678
+
679
+ body.dark-mode {
680
+ .project-card {
681
+ border-color: rgba($dark-accent-primary, 0.45);
682
+ background: rgba($dark-accent-primary, 0.18);
683
+ }
684
+
685
+ .tech-badge {
686
+ background: rgba($dark-accent-primary, 0.25);
687
+ border-color: rgba($dark-accent-primary, 0.45);
688
+ }
689
+
690
+ .project-card__stats {
691
+ color: rgba($dark-ink-500, 0.85);
692
+ }
693
+
694
+ .performance-metric {
695
+ background: rgba($dark-accent-secondary, 0.25);
696
+ border-color: rgba($dark-accent-secondary, 0.5);
697
+ }
698
+ }
699
+
700
+ //
701
+ // Tutorials & learning scaffolding
702
+ // ------------------------------------------------------------
703
+
704
+ .tutorial-steps {
705
+ display: grid;
706
+ gap: map.get($spacing, 4);
707
+ counter-reset: tutorial-step;
708
+ }
709
+
710
+ .tutorial-step {
711
+ position: relative;
712
+ padding-left: map.get($spacing, 8) + map.get($spacing, 2);
713
+ border-left: 2px solid rgba($color-accent-primary, 0.3);
714
+ display: grid;
715
+ gap: map.get($spacing, 2);
716
+
717
+ &::before {
718
+ counter-increment: tutorial-step;
719
+ content: 'Step ' counter(tutorial-step);
720
+ position: absolute;
721
+ left: map.get($spacing, 8);
722
+ top: 0;
723
+ font-size: map.get($font-size-scale, xs);
724
+ letter-spacing: 0.1em;
725
+ text-transform: uppercase;
726
+ color: $color-accent-primary;
727
+ }
728
+ }
729
+
730
+ .tutorial-step__progress {
731
+ height: 4px;
732
+ background: rgba($color-accent-primary, 0.15);
733
+ border-radius: 2px;
734
+ overflow: hidden;
735
+
736
+ span {
737
+ display: block;
738
+ height: 100%;
739
+ width: var(--tutorial-progress, 0%);
740
+ background: $color-accent-primary;
741
+ transition: width 240ms ease;
742
+ }
743
+ }
744
+
745
+ .difficulty-badge {
746
+ display: inline-flex;
747
+ align-items: center;
748
+ gap: map.get($spacing, 1);
749
+ padding: map.get($spacing, 1) map.get($spacing, 3);
750
+ border-radius: 999px;
751
+ font-size: map.get($font-size-scale, xs);
752
+ text-transform: uppercase;
753
+ letter-spacing: 0.12em;
754
+ background: rgba($color-neutral-900, 0.06);
755
+ border: 1px solid rgba($color-neutral-900, 0.18);
756
+ }
757
+
758
+ body.dark-mode {
759
+ .tutorial-step::before {
760
+ color: $dark-accent-primary;
761
+ }
762
+
763
+ .tutorial-step {
764
+ border-left-color: rgba($dark-accent-primary, 0.45);
765
+ }
766
+
767
+ .tutorial-step__progress {
768
+ background: rgba($dark-accent-primary, 0.35);
769
+
770
+ span {
771
+ background: $dark-accent-primary;
772
+ }
773
+ }
774
+
775
+ .difficulty-badge {
776
+ background: rgba($dark-surface-200, 0.85);
777
+ border-color: rgba($dark-ink-500, 0.35);
778
+ }
779
+ }
780
+
781
+ //
782
+ // Data presentation & tabular content
783
+ // ------------------------------------------------------------
784
+
785
+ .stat-table {
786
+ width: 100%;
787
+ border-collapse: separate;
788
+ border-spacing: 0;
789
+ font-size: map.get($font-size-scale, sm);
790
+ border: 1px solid rgba($color-neutral-300, 0.8);
791
+ border-radius: 0.85rem;
792
+ overflow: hidden;
793
+ }
794
+
795
+ .stat-table thead {
796
+ background: rgba($color-accent-primary, 0.12);
797
+ text-transform: uppercase;
798
+ letter-spacing: 0.08em;
799
+ font-size: map.get($font-size-scale, xs);
800
+ }
801
+
802
+ .stat-table th,
803
+ .stat-table td {
804
+ padding: map.get($spacing, 3) map.get($spacing, 4);
805
+ text-align: left;
806
+ }
807
+
808
+ .stat-table tbody tr:nth-child(odd) {
809
+ background: rgba($color-surface-900, 0.03);
810
+ }
811
+
812
+ .stat-table__controls {
813
+ display: flex;
814
+ flex-wrap: wrap;
815
+ gap: map.get($spacing, 2);
816
+ margin-bottom: map.get($spacing, 3);
817
+ font-size: map.get($font-size-scale, xs);
818
+ }
819
+
820
+ .stat-table__sort {
821
+ display: inline-flex;
822
+ align-items: center;
823
+ gap: map.get($spacing, 1);
824
+ padding: map.get($spacing, 1) map.get($spacing, 2);
825
+ border-radius: 999px;
826
+ border: 1px solid rgba($color-ink-900, 0.1);
827
+ background: rgba($color-ink-900, 0.04);
828
+ cursor: pointer;
829
+
830
+ &:focus-visible {
831
+ @include focus-ring($color-accent-primary);
832
+ }
833
+ }
834
+
835
+ body.dark-mode {
836
+ .stat-table {
837
+ border-color: rgba($dark-ink-500, 0.45);
838
+ }
839
+
840
+ .stat-table thead {
841
+ background: rgba($dark-accent-primary, 0.25);
842
+ }
843
+
844
+ .stat-table tbody tr:nth-child(odd) {
845
+ background: rgba($dark-surface-200, 0.75);
846
+ }
847
+
848
+ .stat-table__sort {
849
+ border-color: rgba($dark-ink-500, 0.35);
850
+ background: rgba($dark-surface-100, 0.35);
851
+ }
852
+ }
853
+
854
+ //
855
+ // Notebook & scholarly references
856
+ // ------------------------------------------------------------
857
+
858
+ .notebook-article {
859
+ display: grid;
860
+ gap: map.get($spacing, 5);
861
+ margin: map.get($spacing, 6) auto;
862
+ max-width: 1200px;
863
+ }
864
+
865
+ .notebook-article__header {
866
+ background: rgba($color-surface-100, 0.8);
867
+ padding: map.get($spacing, 6);
868
+ border-radius: 1.25rem;
869
+ box-shadow: 0 20px 60px rgba($color-ink-900, 0.08);
870
+ position: relative;
871
+ overflow: hidden;
872
+ }
873
+
874
+ .notebook-article__header::after {
875
+ content: '';
876
+ position: absolute;
877
+ inset: auto -30% -45% auto;
878
+ width: 45%;
879
+ height: 45%;
880
+ background: radial-gradient(circle at center, rgba($color-accent-primary, 0.35), transparent 65%);
881
+ pointer-events: none;
882
+ }
883
+
884
+ .notebook-article__label {
885
+ text-transform: uppercase;
886
+ letter-spacing: 0.12em;
887
+ font-size: map.get($font-size-scale, xs);
888
+ color: $color-accent-primary;
889
+ margin-bottom: map.get($spacing, 2);
890
+ }
891
+
892
+ .notebook-article__title {
893
+ font-size: clamp(2.4rem, 4vw, 3.2rem);
894
+ margin: 0 0 map.get($spacing, 3);
895
+ }
896
+
897
+ .notebook-article__summary {
898
+ font-size: map.get($font-size-scale, md);
899
+ color: $color-ink-600;
900
+ max-width: 65ch;
901
+ margin-bottom: map.get($spacing, 4);
902
+ }
903
+
904
+ .notebook-article__meta {
905
+ list-style: none;
906
+ padding: 0;
907
+ margin: 0 0 map.get($spacing, 4);
908
+ display: flex;
909
+ flex-wrap: wrap;
910
+ gap: map.get($spacing, 3);
911
+ color: $color-ink-600;
912
+ }
913
+
914
+ .notebook-article__meta li {
915
+ display: flex;
916
+ gap: map.get($spacing, 1);
917
+ align-items: baseline;
918
+ }
919
+
920
+ .notebook-article__meta span {
921
+ font-weight: 600;
922
+ color: $color-ink-800;
923
+ }
924
+
925
+ .notebook-article__actions {
926
+ display: flex;
927
+ flex-wrap: wrap;
928
+ gap: map.get($spacing, 3);
929
+ margin-bottom: map.get($spacing, 4);
930
+ }
931
+
932
+ .notebook-article__actions .btn {
933
+ display: inline-flex;
934
+ align-items: center;
935
+ gap: map.get($spacing, 2);
936
+ }
937
+
938
+ .notebook-article__tags {
939
+ display: flex;
940
+ flex-wrap: wrap;
941
+ gap: map.get($spacing, 2);
942
+ padding: 0;
943
+ margin: 0;
944
+ list-style: none;
945
+ }
946
+
947
+ .notebook-article__tags li {
948
+ background: rgba($color-accent-tertiary, 0.18);
949
+ color: $color-accent-tertiary;
950
+ border-radius: 999px;
951
+ padding: map.get($spacing, 1) map.get($spacing, 3);
952
+ font-size: map.get($font-size-scale, xs);
953
+ letter-spacing: 0.04em;
954
+ }
955
+
956
+ .notebook-article__layout {
957
+ display: grid;
958
+ gap: map.get($spacing, 5);
959
+ }
960
+
961
+ @media (min-width: 960px) {
962
+ .notebook-article__layout {
963
+ grid-template-columns: minmax(0, 2.3fr) minmax(280px, 1fr);
964
+ gap: map.get($spacing, 6);
965
+ }
966
+ }
967
+
968
+ .notebook-article__content {
969
+ display: flex;
970
+ flex-direction: column;
971
+ gap: map.get($spacing, 4);
972
+ }
973
+
974
+ .notebook-article__sidebar {
975
+ position: sticky;
976
+ top: calc(var(--header-height, 96px) + map.get($spacing, 4));
977
+ align-self: start;
978
+ display: flex;
979
+ flex-direction: column;
980
+ gap: map.get($spacing, 4);
981
+ }
982
+
983
+ .notebook-sidebar__section {
984
+ background: rgba($color-surface-100, 0.8);
985
+ border-radius: 1rem;
986
+ padding: map.get($spacing, 4);
987
+ box-shadow: 0 12px 30px rgba($color-ink-900, 0.04);
988
+ }
989
+
990
+ .notebook-sidebar__section h2 {
991
+ font-size: map.get($font-size-scale, sm);
992
+ text-transform: uppercase;
993
+ letter-spacing: 0.08em;
994
+ margin-bottom: map.get($spacing, 3);
995
+ }
996
+
997
+ .notebook-sidebar__stats {
998
+ list-style: none;
999
+ padding: 0;
1000
+ margin: 0;
1001
+ display: grid;
1002
+ gap: map.get($spacing, 2);
1003
+ }
1004
+
1005
+ .notebook-sidebar__stats li {
1006
+ font-size: map.get($font-size-scale, sm);
1007
+ color: $color-ink-700;
1008
+ }
1009
+
1010
+ .notebook-sidebar__metadata {
1011
+ margin: 0;
1012
+ display: grid;
1013
+ gap: map.get($spacing, 2);
1014
+ }
1015
+
1016
+ .notebook-sidebar__metadata div {
1017
+ display: grid;
1018
+ gap: map.get($spacing, 1);
1019
+ }
1020
+
1021
+ .notebook-sidebar__metadata dt {
1022
+ font-size: map.get($font-size-scale, xs);
1023
+ text-transform: uppercase;
1024
+ letter-spacing: 0.06em;
1025
+ color: $color-ink-500;
1026
+ }
1027
+
1028
+ .notebook-sidebar__metadata dd {
1029
+ margin: 0;
1030
+ font-size: map.get($font-size-scale, sm);
1031
+ color: $color-ink-700;
1032
+ word-break: break-word;
1033
+ }
1034
+
1035
+ .notebook-sidebar__clone {
1036
+ background: rgba($color-ink-900, 0.08);
1037
+ border-radius: 0.75rem;
1038
+ padding: map.get($spacing, 3);
1039
+ font-family: $font-stack-code;
1040
+ overflow-x: auto;
1041
+ }
1042
+
1043
+ .notebook-sidebar__links {
1044
+ list-style: none;
1045
+ padding: 0;
1046
+ margin: 0;
1047
+ display: grid;
1048
+ gap: map.get($spacing, 2);
1049
+ }
1050
+
1051
+ .notebook-sidebar__link {
1052
+ font-weight: 600;
1053
+ color: $color-accent-primary;
1054
+ }
1055
+
1056
+ .notebook-cell {
1057
+ border-left: 4px solid $color-accent-primary;
1058
+ padding: map.get($spacing, 4);
1059
+ border-radius: 1rem;
1060
+ background: rgba($color-accent-primary, 0.06);
1061
+ margin: map.get($spacing, 3) 0;
1062
+ box-shadow: inset 0 0 0 1px rgba($color-ink-900, 0.04);
1063
+ }
1064
+
1065
+ .notebook-cell--input {
1066
+ border-left-color: $color-accent-secondary;
1067
+ }
1068
+
1069
+ .notebook-cell--output {
1070
+ border-left-color: $color-accent-tertiary;
1071
+ }
1072
+
1073
+ .notebook-cell__header {
1074
+ display: flex;
1075
+ align-items: center;
1076
+ justify-content: space-between;
1077
+ font-size: map.get($font-size-scale, xs);
1078
+ color: $color-ink-500;
1079
+ margin-bottom: map.get($spacing, 2);
1080
+ text-transform: uppercase;
1081
+ letter-spacing: 0.08em;
1082
+ }
1083
+
1084
+ .notebook-cell__code {
1085
+ margin: 0;
1086
+ overflow: auto;
1087
+ border-radius: 0.75rem;
1088
+ background: rgba($color-ink-900, 0.08);
1089
+ padding: map.get($spacing, 3);
1090
+ }
1091
+
1092
+ .notebook-cell__outputs {
1093
+ display: grid;
1094
+ gap: map.get($spacing, 3);
1095
+ }
1096
+
1097
+ .notebook-output {
1098
+ border-radius: 0.75rem;
1099
+ padding: map.get($spacing, 3);
1100
+ font-family: $font-stack-code;
1101
+ background: rgba($color-ink-900, 0.04);
1102
+ overflow-x: auto;
1103
+ margin: 0;
1104
+ }
1105
+
1106
+ .notebook-output--stream {
1107
+ color: $color-ink-700;
1108
+ }
1109
+
1110
+ .notebook-output--error {
1111
+ color: $color-critical-600;
1112
+ background: rgba($color-critical-200, 0.35);
1113
+ border: 1px solid rgba($color-critical-400, 0.6);
1114
+ }
1115
+
1116
+ .notebook-output__trace {
1117
+ margin-top: map.get($spacing, 2);
1118
+ white-space: pre-wrap;
1119
+ }
1120
+
1121
+ .notebook-output__figure {
1122
+ margin: 0;
1123
+ }
1124
+
1125
+ .notebook-output__figure img {
1126
+ width: 100%;
1127
+ height: auto;
1128
+ border-radius: 0.75rem;
1129
+ box-shadow: 0 10px 30px rgba($color-ink-900, 0.15);
1130
+ }
1131
+
1132
+ .notebook-output-plotly,
1133
+ .notebook-output-vega {
1134
+ min-height: 320px;
1135
+ border-radius: 0.75rem;
1136
+ background: rgba($color-ink-900, 0.04);
1137
+ display: grid;
1138
+ place-items: center;
1139
+ padding: map.get($spacing, 3);
1140
+ }
1141
+
1142
+ .notebook-output__warning {
1143
+ font-size: map.get($font-size-scale, sm);
1144
+ color: $color-ink-600;
1145
+ text-align: center;
1146
+ margin: 0;
1147
+ }
1148
+
1149
+ .notebook-output--widget {
1150
+ font-style: italic;
1151
+ color: $color-accent-secondary;
1152
+ }
1153
+
1154
+ .notebook-segment {
1155
+ display: grid;
1156
+ gap: map.get($spacing, 2);
1157
+ }
1158
+
1159
+ .notebook-segment__label {
1160
+ font-size: map.get($font-size-scale, xs);
1161
+ letter-spacing: 0.1em;
1162
+ text-transform: uppercase;
1163
+ color: $color-ink-400;
1164
+ }
1165
+
1166
+ .notebook-segment__body {
1167
+ display: grid;
1168
+ gap: map.get($spacing, 3);
1169
+ }
1170
+
1171
+ .reference-list {
1172
+ list-style: none;
1173
+ margin: map.get($spacing, 5) 0;
1174
+ padding: 0;
1175
+ display: grid;
1176
+ gap: map.get($spacing, 3);
1177
+ counter-reset: reference;
1178
+ }
1179
+
1180
+ .reference-list li {
1181
+ counter-increment: reference;
1182
+ padding-left: map.get($spacing, 6);
1183
+ position: relative;
1184
+ font-size: map.get($font-size-scale, sm);
1185
+
1186
+ &::before {
1187
+ content: '[' counter(reference) ']';
1188
+ position: absolute;
1189
+ left: 0;
1190
+ color: $color-ink-500;
1191
+ font-variant-numeric: tabular-nums;
1192
+ }
1193
+ }
1194
+
1195
+ .figure-caption,
1196
+ .table-caption {
1197
+ font-size: map.get($font-size-scale, xs);
1198
+ color: $color-ink-500;
1199
+ margin-top: map.get($spacing, 2);
1200
+ font-style: italic;
1201
+ display: flex;
1202
+ gap: map.get($spacing, 2);
1203
+ }
1204
+
1205
+ .figure-caption::before,
1206
+ .table-caption::before {
1207
+ font-weight: 600;
1208
+ text-transform: uppercase;
1209
+ letter-spacing: 0.08em;
1210
+ }
1211
+
1212
+ .figure-caption::before {
1213
+ content: var(--caption-label, 'Figure');
1214
+ }
1215
+
1216
+ .table-caption::before {
1217
+ content: var(--caption-label, 'Table');
1218
+ }
1219
+
1220
+ body.dark-mode {
1221
+ .notebook-article__header,
1222
+ .notebook-sidebar__section {
1223
+ background: rgba($dark-surface-100, 0.65);
1224
+ box-shadow: 0 20px 48px rgba($dark-ink-900, 0.32);
1225
+ }
1226
+
1227
+ .notebook-article__summary,
1228
+ .notebook-article__meta,
1229
+ .notebook-sidebar__metadata dd,
1230
+ .notebook-sidebar__stats li {
1231
+ color: rgba($dark-ink-200, 0.9);
1232
+ }
1233
+
1234
+ .notebook-article__meta span,
1235
+ .notebook-sidebar__metadata dt {
1236
+ color: $dark-ink-000;
1237
+ }
1238
+
1239
+ .notebook-article__tags li {
1240
+ background: rgba($dark-accent-tertiary, 0.2);
1241
+ color: $dark-accent-tertiary;
1242
+ }
1243
+
1244
+ .notebook-cell {
1245
+ background: rgba($dark-accent-primary, 0.14);
1246
+ box-shadow: inset 0 0 0 1px rgba($dark-ink-900, 0.35);
1247
+ }
1248
+
1249
+ .notebook-cell__code {
1250
+ background: rgba($dark-ink-900, 0.45);
1251
+ }
1252
+
1253
+ .notebook-output {
1254
+ background: rgba($dark-ink-900, 0.35);
1255
+ color: $dark-ink-050;
1256
+ }
1257
+
1258
+ .notebook-output__warning {
1259
+ color: rgba($dark-ink-100, 0.8);
1260
+ }
1261
+
1262
+ .notebook-output--widget {
1263
+ color: $dark-accent-secondary;
1264
+ }
1265
+
1266
+ .notebook-output-plotly,
1267
+ .notebook-output-vega {
1268
+ background: rgba($dark-ink-900, 0.32);
1269
+ }
1270
+
1271
+ .notebook-cell {
1272
+ background: rgba($dark-accent-primary, 0.22);
1273
+ }
1274
+
1275
+ .reference-list li::before,
1276
+ .figure-caption,
1277
+ .table-caption {
1278
+ color: rgba($dark-ink-500, 0.8);
1279
+ }
1280
+ }
1281
+
1282
+ //
1283
+ // Taxonomy & tagging systems
1284
+ // ------------------------------------------------------------
1285
+
1286
+ .tag-list {
1287
+ display: flex;
1288
+ flex-wrap: wrap;
1289
+ gap: map.get($spacing, 2);
1290
+ margin: map.get($spacing, 3) 0;
1291
+ }
1292
+
1293
+ .tag {
1294
+ display: inline-flex;
1295
+ align-items: center;
1296
+ gap: map.get($spacing, 1);
1297
+ padding: map.get($spacing, 1) map.get($spacing, 3);
1298
+ border-radius: 999px;
1299
+ font-size: map.get($font-size-scale, xs);
1300
+ background: rgba($color-neutral-900, 0.06);
1301
+ color: $color-ink-600;
1302
+ border: 1px solid rgba($color-neutral-900, 0.14);
1303
+ text-decoration: none;
1304
+ transition: background 200ms ease, color 200ms ease, border-color 200ms ease;
1305
+
1306
+ &:hover,
1307
+ &:focus-visible {
1308
+ background: rgba($color-accent-primary, 0.18);
1309
+ color: $color-accent-primary;
1310
+ border-color: rgba($color-accent-primary, 0.4);
1311
+ }
1312
+
1313
+ &:focus-visible {
1314
+ @include focus-ring($color-accent-primary);
1315
+ }
1316
+ }
1317
+
1318
+ .tag--category {
1319
+ background: rgba($color-accent-secondary, 0.18);
1320
+ border-color: rgba($color-accent-secondary, 0.35);
1321
+ }
1322
+
1323
+ .tag--primary {
1324
+ background: rgba($color-accent-primary, 0.2);
1325
+ border-color: rgba($color-accent-primary, 0.45);
1326
+ color: $color-accent-primary;
1327
+ }
1328
+
1329
+ body.dark-mode {
1330
+ .tag {
1331
+ background: rgba($dark-surface-200, 0.75);
1332
+ color: rgba($dark-ink-500, 0.85);
1333
+ border-color: rgba($dark-ink-500, 0.35);
1334
+
1335
+ &:hover,
1336
+ &:focus-visible {
1337
+ background: rgba($dark-accent-primary, 0.35);
1338
+ color: $dark-accent-primary;
1339
+ border-color: rgba($dark-accent-primary, 0.55);
1340
+ }
1341
+ }
1342
+
1343
+ .tag--category {
1344
+ background: rgba($dark-accent-secondary, 0.35);
1345
+ border-color: rgba($dark-accent-secondary, 0.55);
1346
+ }
1347
+
1348
+ .tag--primary {
1349
+ background: rgba($dark-accent-primary, 0.45);
1350
+ color: $dark-ink-900;
1351
+ border-color: rgba($dark-accent-primary, 0.65);
1352
+ }
1353
+ }
1354
+
1355
+ //
1356
+ // Technical search experience
1357
+ // ------------------------------------------------------------
1358
+
1359
+ .search-page {
1360
+ .page {
1361
+ padding-bottom: map.get($spacing, 7);
1362
+ }
1363
+
1364
+ .page-header {
1365
+ max-width: $max-width-wide;
1366
+ }
1367
+ }
1368
+
1369
+ .search-app {
1370
+ display: grid;
1371
+ gap: map.get($spacing, 6);
1372
+ margin-top: map.get($spacing, 4);
1373
+
1374
+ @media (min-width: map.get($breakpoints, lg)) {
1375
+ grid-template-columns: minmax(0, 25rem) minmax(0, 1fr);
1376
+ align-items: start;
1377
+ }
1378
+ }
1379
+
1380
+ .search-app__panel {
1381
+ display: grid;
1382
+ gap: map.get($spacing, 5);
1383
+
1384
+ @media (min-width: map.get($breakpoints, lg)) {
1385
+ position: sticky;
1386
+ top: 6.5rem;
1387
+ }
1388
+ }
1389
+
1390
+ .search-app__form,
1391
+ .search-app__analytics {
1392
+ background: rgba($color-neutral-100, 0.7);
1393
+ border: 1px solid rgba($color-neutral-900, 0.1);
1394
+ border-radius: 1rem;
1395
+ padding: map.get($spacing, 5);
1396
+ box-shadow: $shadow-soft;
1397
+ backdrop-filter: blur(8px);
1398
+ }
1399
+
1400
+ .search-app__form {
1401
+ display: grid;
1402
+ gap: map.get($spacing, 5);
1403
+ }
1404
+
1405
+ .search-app__label {
1406
+ font-weight: 600;
1407
+ color: $color-ink-700;
1408
+ }
1409
+
1410
+ .search-app__input-group {
1411
+ display: flex;
1412
+ align-items: center;
1413
+ gap: map.get($spacing, 2);
1414
+ }
1415
+
1416
+ .search-app__input {
1417
+ flex: 1;
1418
+ padding: map.get($spacing, 3) map.get($spacing, 4);
1419
+ border-radius: 0.75rem;
1420
+ border: 1px solid rgba($color-neutral-900, 0.18);
1421
+ background: #fff;
1422
+ font-size: map.get($font-size-scale, md);
1423
+ font-family: $font-family-mono;
1424
+ color: $color-ink-900;
1425
+ transition: border-color $transition-snappy, box-shadow $transition-snappy;
1426
+
1427
+ &:focus {
1428
+ outline: none;
1429
+ border-color: $color-accent-primary;
1430
+ box-shadow: 0 0 0 3px rgba($color-accent-primary, 0.2);
1431
+ }
1432
+ }
1433
+
1434
+ .search-app__submit {
1435
+ padding: map.get($spacing, 3) map.get($spacing, 4);
1436
+ border-radius: 0.75rem;
1437
+ border: none;
1438
+ background: $color-accent-primary;
1439
+ color: #fff;
1440
+ font-weight: 600;
1441
+ letter-spacing: 0.02em;
1442
+ transition: transform $transition-snappy, box-shadow $transition-snappy, background $transition-snappy;
1443
+
1444
+ &:hover,
1445
+ &:focus-visible {
1446
+ background: color.adjust($color-accent-primary, $lightness: -6%);
1447
+ transform: translateY(-1px);
1448
+ box-shadow: 0 10px 24px rgba($color-accent-primary, 0.25);
1449
+ }
1450
+
1451
+ &:focus-visible {
1452
+ @include focus-ring($color-accent-primary);
1453
+ }
1454
+ }
1455
+
1456
+ .search-app__shortcuts {
1457
+ margin: map.get($spacing, 2) 0 0;
1458
+ color: $color-ink-500;
1459
+ font-size: map.get($font-size-scale, sm);
1460
+
1461
+ kbd {
1462
+ display: inline-flex;
1463
+ align-items: center;
1464
+ justify-content: center;
1465
+ min-width: 1.75rem;
1466
+ padding: map.get($spacing, 1) map.get($spacing, 2);
1467
+ margin: 0 map.get($spacing, 1);
1468
+ border-radius: 0.5rem;
1469
+ border: 1px solid rgba($color-neutral-900, 0.2);
1470
+ background: #fff;
1471
+ font-family: $font-family-mono;
1472
+ font-size: 0.75em;
1473
+ }
1474
+ }
1475
+
1476
+ .search-app__autocomplete {
1477
+ margin-top: map.get($spacing, 3);
1478
+ border-radius: 0.75rem;
1479
+ border: 1px solid rgba($color-neutral-900, 0.14);
1480
+ background: #fff;
1481
+ box-shadow: $shadow-soft;
1482
+ max-height: 16rem;
1483
+ overflow: auto;
1484
+ padding: map.get($spacing, 2);
1485
+ display: grid;
1486
+ gap: map.get($spacing, 1);
1487
+ }
1488
+
1489
+ .search-autocomplete__option {
1490
+ width: 100%;
1491
+ text-align: left;
1492
+ padding: map.get($spacing, 2) map.get($spacing, 3);
1493
+ border-radius: 0.5rem;
1494
+ border: none;
1495
+ background: transparent;
1496
+ cursor: pointer;
1497
+ font-size: map.get($font-size-scale, sm);
1498
+ color: $color-ink-700;
1499
+ transition: background $transition-snappy, color $transition-snappy;
1500
+
1501
+ &.is-active,
1502
+ &:hover,
1503
+ &:focus-visible {
1504
+ background: rgba($color-accent-primary, 0.12);
1505
+ color: $color-accent-primary;
1506
+ }
1507
+ }
1508
+
1509
+ .search-app__filters {
1510
+ border: 1px dashed rgba($color-neutral-900, 0.18);
1511
+ border-radius: 0.75rem;
1512
+ padding: map.get($spacing, 4);
1513
+ }
1514
+
1515
+ .search-app__filters-grid {
1516
+ display: grid;
1517
+ gap: map.get($spacing, 4);
1518
+
1519
+ @media (min-width: map.get($breakpoints, md)) {
1520
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1521
+ }
1522
+ }
1523
+
1524
+ .search-filter {
1525
+ display: grid;
1526
+ gap: map.get($spacing, 2);
1527
+ font-size: map.get($font-size-scale, sm);
1528
+
1529
+ select {
1530
+ width: 100%;
1531
+ border-radius: 0.75rem;
1532
+ border: 1px solid rgba($color-neutral-900, 0.18);
1533
+ padding: map.get($spacing, 2) map.get($spacing, 3);
1534
+ font-size: map.get($font-size-scale, sm);
1535
+ background: #fff;
1536
+ color: $color-ink-700;
1537
+
1538
+ &:focus {
1539
+ outline: none;
1540
+ border-color: $color-accent-primary;
1541
+ box-shadow: 0 0 0 3px rgba($color-accent-primary, 0.2);
1542
+ }
1543
+ }
1544
+ }
1545
+
1546
+ .search-filter__tags {
1547
+ display: flex;
1548
+ flex-wrap: wrap;
1549
+ gap: map.get($spacing, 2);
1550
+ }
1551
+
1552
+ .search-filter__tag {
1553
+ padding: map.get($spacing, 2) map.get($spacing, 3);
1554
+ border-radius: 999px;
1555
+ border: 1px solid rgba($color-neutral-900, 0.18);
1556
+ background: rgba($color-neutral-900, 0.05);
1557
+ font-size: map.get($font-size-scale, xs);
1558
+ letter-spacing: 0.04em;
1559
+ text-transform: uppercase;
1560
+ color: $color-ink-600;
1561
+ transition: background $transition-snappy, color $transition-snappy, border-color $transition-snappy;
1562
+
1563
+ &[aria-pressed='true'] {
1564
+ background: rgba($color-accent-primary, 0.16);
1565
+ color: $color-accent-primary;
1566
+ border-color: rgba($color-accent-primary, 0.45);
1567
+ }
1568
+
1569
+ &:hover,
1570
+ &:focus-visible {
1571
+ background: rgba($color-accent-secondary, 0.16);
1572
+ color: $color-accent-secondary;
1573
+ }
1574
+ }
1575
+
1576
+ .search-filter__empty {
1577
+ font-size: map.get($font-size-scale, sm);
1578
+ color: $color-ink-500;
1579
+ }
1580
+
1581
+ .search-app__analytics-title {
1582
+ font-size: map.get($font-size-scale, md);
1583
+ margin-bottom: map.get($spacing, 2);
1584
+ }
1585
+
1586
+ .search-app__analytics-empty {
1587
+ font-size: map.get($font-size-scale, sm);
1588
+ color: $color-ink-500;
1589
+ }
1590
+
1591
+ .search-app__analytics-list {
1592
+ display: grid;
1593
+ gap: map.get($spacing, 2);
1594
+ margin: 0;
1595
+ padding: 0;
1596
+ list-style: none;
1597
+ }
1598
+
1599
+ .search-analytics__query {
1600
+ width: 100%;
1601
+ border-radius: 0.75rem;
1602
+ border: 1px solid rgba($color-neutral-900, 0.14);
1603
+ background: rgba($color-neutral-900, 0.04);
1604
+ padding: map.get($spacing, 2) map.get($spacing, 3);
1605
+ font-size: map.get($font-size-scale, sm);
1606
+ text-align: left;
1607
+ cursor: pointer;
1608
+ color: $color-ink-700;
1609
+ transition: background $transition-snappy, color $transition-snappy, border-color $transition-snappy;
1610
+
1611
+ &:hover,
1612
+ &:focus-visible {
1613
+ background: rgba($color-accent-primary, 0.14);
1614
+ border-color: rgba($color-accent-primary, 0.35);
1615
+ color: $color-accent-primary;
1616
+ }
1617
+ }
1618
+
1619
+ .search-app__results {
1620
+ display: grid;
1621
+ gap: map.get($spacing, 4);
1622
+ }
1623
+
1624
+ .search-app__results-header {
1625
+ display: flex;
1626
+ flex-direction: column;
1627
+ gap: map.get($spacing, 1);
1628
+ }
1629
+
1630
+ .search-app__results-meta {
1631
+ font-size: map.get($font-size-scale, sm);
1632
+ color: $color-ink-500;
1633
+ }
1634
+
1635
+ .search-app__results-list {
1636
+ display: grid;
1637
+ gap: map.get($spacing, 4);
1638
+ margin: 0;
1639
+ padding: 0;
1640
+ list-style: none;
1641
+ }
1642
+
1643
+ .search-result__card {
1644
+ border-radius: 1rem;
1645
+ border: 1px solid rgba($color-neutral-900, 0.1);
1646
+ background: rgba($color-neutral-100, 0.65);
1647
+ box-shadow: $shadow-soft;
1648
+ padding: map.get($spacing, 5);
1649
+ display: grid;
1650
+ gap: map.get($spacing, 3);
1651
+ }
1652
+
1653
+ .search-result__meta {
1654
+ display: flex;
1655
+ flex-wrap: wrap;
1656
+ gap: map.get($spacing, 2);
1657
+ font-size: map.get($font-size-scale, xs);
1658
+ text-transform: uppercase;
1659
+ letter-spacing: 0.08em;
1660
+ color: $color-ink-500;
1661
+ }
1662
+
1663
+ .search-result__title a {
1664
+ color: $color-ink-900;
1665
+ text-decoration: none;
1666
+ transition: color $transition-snappy;
1667
+
1668
+ &:hover,
1669
+ &:focus-visible {
1670
+ color: $color-accent-primary;
1671
+ }
1672
+ }
1673
+
1674
+ .search-result__body {
1675
+ display: grid;
1676
+ gap: map.get($spacing, 3);
1677
+ }
1678
+
1679
+ .search-result__code {
1680
+ margin: 0;
1681
+ border-radius: 0.75rem;
1682
+ overflow: hidden;
1683
+ border: 1px solid rgba($color-neutral-900, 0.1);
1684
+ max-height: 16rem;
1685
+ font-size: 0.85rem;
1686
+ }
1687
+
1688
+ .search-result__math {
1689
+ display: grid;
1690
+ gap: map.get($spacing, 2);
1691
+ padding: map.get($spacing, 3);
1692
+ border-radius: 0.75rem;
1693
+ border: 1px solid rgba($color-neutral-900, 0.12);
1694
+ background: rgba($color-neutral-100, 0.85);
1695
+ }
1696
+
1697
+ .search-result__math-preview {
1698
+ overflow-x: auto;
1699
+ padding-bottom: map.get($spacing, 1);
1700
+ }
1701
+
1702
+ .search-result__math-source {
1703
+ margin: 0;
1704
+ background: rgba($color-neutral-900, 0.04);
1705
+ border-radius: 0.5rem;
1706
+ padding: map.get($spacing, 2);
1707
+ font-size: 0.85rem;
1708
+ }
1709
+
1710
+ .search-result__math-copy {
1711
+ justify-self: flex-start;
1712
+ display: inline-flex;
1713
+ align-items: center;
1714
+ gap: map.get($spacing, 1);
1715
+ border-radius: 999px;
1716
+ border: 1px solid rgba($color-neutral-900, 0.18);
1717
+ padding: 0.35rem 0.9rem;
1718
+ font-size: map.get($font-size-scale, xs);
1719
+ background: white;
1720
+ color: $color-ink-700;
1721
+ transition: background $transition-snappy, border-color $transition-snappy, color $transition-snappy;
1722
+
1723
+ &:hover,
1724
+ &:focus-visible {
1725
+ background: rgba($color-accent-primary, 0.1);
1726
+ border-color: rgba($color-accent-primary, 0.35);
1727
+ color: $color-accent-primary;
1728
+ }
1729
+ }
1730
+
1731
+ .search-result__math-copy.is-copied {
1732
+ background: rgba($color-accent-primary, 0.12);
1733
+ border-color: rgba($color-accent-primary, 0.4);
1734
+ color: $color-accent-primary;
1735
+ }
1736
+
1737
+ .search-result__excerpt {
1738
+ font-size: map.get($font-size-scale, sm);
1739
+ color: $color-ink-600;
1740
+
1741
+ .math-expression {
1742
+ font-family: $font-family-mono;
1743
+ background: rgba($color-accent-secondary, 0.1);
1744
+ padding: map.get($spacing, 1) map.get($spacing, 2);
1745
+ border-radius: 0.5rem;
1746
+ }
1747
+ }
1748
+
1749
+ .search-result__footer {
1750
+ display: flex;
1751
+ flex-wrap: wrap;
1752
+ gap: map.get($spacing, 3);
1753
+ align-items: center;
1754
+ justify-content: space-between;
1755
+ font-size: map.get($font-size-scale, xs);
1756
+ color: $color-ink-500;
1757
+ }
1758
+
1759
+ .search-result__tags {
1760
+ display: flex;
1761
+ gap: map.get($spacing, 2);
1762
+ flex-wrap: wrap;
1763
+ margin: 0;
1764
+ padding: 0;
1765
+ list-style: none;
1766
+
1767
+ li {
1768
+ background: rgba($color-neutral-900, 0.06);
1769
+ border-radius: 999px;
1770
+ padding: map.get($spacing, 1) map.get($spacing, 2);
1771
+ }
1772
+ }
1773
+
1774
+ .search-app__no-results {
1775
+ font-size: map.get($font-size-scale, md);
1776
+ color: $color-ink-500;
1777
+ text-align: center;
1778
+ }
1779
+
1780
+ .search-app__noscript {
1781
+ margin-top: map.get($spacing, 4);
1782
+ padding: map.get($spacing, 4);
1783
+ border-radius: 0.75rem;
1784
+ background: rgba($color-warning, 0.15);
1785
+ border: 1px solid rgba($color-warning, 0.45);
1786
+ color: $color-ink-700;
1787
+ }
1788
+
1789
+ body.dark-mode {
1790
+ .search-app__form,
1791
+ .search-app__analytics,
1792
+ .search-result__card {
1793
+ background: rgba($dark-surface-200, 0.9);
1794
+ border-color: rgba($dark-ink-500, 0.25);
1795
+ box-shadow: none;
1796
+ }
1797
+
1798
+ .search-app__input,
1799
+ .search-filter select {
1800
+ background: $dark-surface-300;
1801
+ border-color: rgba($dark-ink-500, 0.35);
1802
+ color: $dark-ink-900;
1803
+
1804
+ &:focus {
1805
+ border-color: $dark-accent-primary;
1806
+ box-shadow: 0 0 0 3px rgba($dark-accent-primary, 0.35);
1807
+ }
1808
+ }
1809
+
1810
+ .search-app__autocomplete,
1811
+ .search-autocomplete__option,
1812
+ .search-analytics__query,
1813
+ .search-filter__tag,
1814
+ .search-result__tags li {
1815
+ background: rgba($dark-surface-300, 0.85);
1816
+ border-color: rgba($dark-ink-500, 0.3);
1817
+ color: $dark-ink-700;
1818
+ }
1819
+
1820
+ .search-app__shortcuts,
1821
+ .search-app__analytics-empty,
1822
+ .search-app__results-meta,
1823
+ .search-result__meta,
1824
+ .search-app__no-results {
1825
+ color: rgba($dark-ink-500, 0.85);
1826
+ }
1827
+
1828
+ .search-result__title a {
1829
+ color: $dark-ink-900;
1830
+
1831
+ &:hover,
1832
+ &:focus-visible {
1833
+ color: $dark-accent-primary;
1834
+ }
1835
+ }
1836
+
1837
+ .search-result__excerpt {
1838
+ color: $dark-ink-700;
1839
+
1840
+ .math-expression {
1841
+ background: rgba($dark-accent-secondary, 0.25);
1842
+ color: $dark-ink-900;
1843
+ }
1844
+ }
1845
+
1846
+ .search-result__math {
1847
+ background: rgba($dark-surface-300, 0.85);
1848
+ border-color: rgba($dark-ink-500, 0.3);
1849
+ }
1850
+
1851
+ .search-result__math-source {
1852
+ background: rgba($dark-surface-300, 0.65);
1853
+ }
1854
+
1855
+ .search-result__math-copy {
1856
+ background: $dark-surface-300;
1857
+ border-color: rgba($dark-ink-500, 0.35);
1858
+ color: $dark-ink-700;
1859
+
1860
+ &:hover,
1861
+ &:focus-visible {
1862
+ background: rgba($dark-accent-primary, 0.15);
1863
+ border-color: rgba($dark-accent-primary, 0.45);
1864
+ color: $dark-accent-primary;
1865
+ }
1866
+ }
1867
+
1868
+ .search-result__math-copy.is-copied {
1869
+ background: rgba($dark-accent-primary, 0.2);
1870
+ border-color: rgba($dark-accent-primary, 0.5);
1871
+ color: $dark-accent-primary;
1872
+ }
1873
+
1874
+ .search-filter__tag[aria-pressed='true'] {
1875
+ background: rgba($dark-accent-primary, 0.35);
1876
+ color: $dark-ink-900;
1877
+ border-color: rgba($dark-accent-primary, 0.55);
1878
+ }
1879
+ }
1880
+
1881
+ .portfolio-card__github-stats {
1882
+ display: grid;
1883
+ grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
1884
+ gap: 0.75rem;
1885
+ margin-top: 1rem;
1886
+
1887
+ div {
1888
+ padding: 0.75rem;
1889
+ background: rgba(50, 119, 246, 0.08);
1890
+ border-radius: 0.75rem;
1891
+ text-align: center;
1892
+ }
1893
+
1894
+ dt {
1895
+ margin: 0;
1896
+ font-size: 0.75rem;
1897
+ text-transform: uppercase;
1898
+ letter-spacing: 0.08em;
1899
+ color: rgba(11, 29, 61, 0.7);
1900
+ }
1901
+
1902
+ dd {
1903
+ margin: 0.25rem 0 0;
1904
+ font-size: 1.25rem;
1905
+ font-weight: 600;
1906
+ color: inherit;
1907
+ }
1908
+
1909
+ body.dark-mode & {
1910
+ div {
1911
+ background: rgba(50, 119, 246, 0.2);
1912
+ }
1913
+
1914
+ dt {
1915
+ color: rgba(245, 247, 255, 0.8);
1916
+ }
1917
+ }
1918
+ }
1919
+
1920
+ .header-languages {
1921
+ margin-top: 1.5rem;
1922
+
1923
+ &__title {
1924
+ margin-bottom: 0.5rem;
1925
+ font-size: 0.875rem;
1926
+ font-weight: 600;
1927
+ text-transform: uppercase;
1928
+ letter-spacing: 0.08em;
1929
+ }
1930
+
1931
+ ul {
1932
+ margin: 0;
1933
+ padding: 0;
1934
+ list-style: none;
1935
+ display: flex;
1936
+ flex-wrap: wrap;
1937
+ gap: 0.5rem;
1938
+ }
1939
+
1940
+ a {
1941
+ display: inline-flex;
1942
+ align-items: center;
1943
+ padding: 0.25rem 0.75rem;
1944
+ border-radius: 999px;
1945
+ background: rgba(50, 119, 246, 0.1);
1946
+ color: inherit;
1947
+ text-decoration: none;
1948
+ font-size: 0.8125rem;
1949
+ }
1950
+
1951
+ a:hover,
1952
+ a:focus-visible {
1953
+ background: rgba(50, 119, 246, 0.2);
1954
+ }
1955
+
1956
+ body.dark-mode & a {
1957
+ background: rgba(50, 119, 246, 0.25);
1958
+ }
1959
+
1960
+ body.dark-mode & a:hover,
1961
+ body.dark-mode & a:focus-visible {
1962
+ background: rgba(50, 119, 246, 0.35);
1963
+ }
1964
+ }
1965
+
1966
+ .citation-tools {
1967
+ margin-block: 3rem;
1968
+ padding: 2rem;
1969
+ border-radius: 1rem;
1970
+ background: var(--surface-elevated, rgba(12, 35, 64, 0.04));
1971
+ box-shadow: 0 1px 3px rgba(12, 35, 64, 0.08);
1972
+ }
1973
+
1974
+ .citation-tools__header {
1975
+ display: grid;
1976
+ gap: 0.5rem;
1977
+ margin-bottom: 1.5rem;
1978
+ }
1979
+
1980
+ .citation-tools__header h2 {
1981
+ font-size: clamp(1.35rem, 2vw, 1.6rem);
1982
+ margin: 0;
1983
+ }
1984
+
1985
+ .citation-tools__header p {
1986
+ color: var(--muted-foreground, #4a5568);
1987
+ margin: 0;
1988
+ }
1989
+
1990
+ .citation-tools__citation {
1991
+ font-size: 0.95rem;
1992
+ color: var(--muted-foreground, #4a5568);
1993
+ }
1994
+
1995
+ .citation-tools__exports {
1996
+ display: grid;
1997
+ gap: 1.5rem;
1998
+ }
1999
+
2000
+ .citation-tools__format {
2001
+ border: 1px solid rgba(12, 35, 64, 0.12);
2002
+ border-radius: 0.75rem;
2003
+ padding: 1rem;
2004
+ background-color: var(--surface-card, #fff);
2005
+ }
2006
+
2007
+ .citation-tools__format header {
2008
+ display: flex;
2009
+ justify-content: space-between;
2010
+ align-items: center;
2011
+ gap: 1rem;
2012
+ margin-bottom: 1rem;
2013
+ }
2014
+
2015
+ .citation-tools__format h3 {
2016
+ margin: 0;
2017
+ font-size: 1rem;
2018
+ font-weight: 600;
2019
+ }
2020
+
2021
+ .citation-tools__format textarea {
2022
+ width: 100%;
2023
+ min-height: 8rem;
2024
+ font-family: var(--font-mono, "Fira Code", monospace);
2025
+ font-size: 0.875rem;
2026
+ background: rgba(12, 35, 64, 0.04);
2027
+ border: 1px dashed rgba(12, 35, 64, 0.2);
2028
+ border-radius: 0.5rem;
2029
+ padding: 1rem;
2030
+ color: inherit;
2031
+ resize: vertical;
2032
+ }
2033
+
2034
+ [data-copied='true'] {
2035
+ background-color: var(--accent, #3277f6);
2036
+ color: #fff;
2037
+ }
2038
+
2039
+ .open-science-badges {
2040
+ margin-block: 3rem;
2041
+ padding: 1.5rem;
2042
+ border-radius: 1rem;
2043
+ background: linear-gradient(135deg, rgba(12, 35, 64, 0.05), rgba(50, 119, 246, 0.08));
2044
+ }
2045
+
2046
+ .open-science-badges__intro {
2047
+ margin-bottom: 1rem;
2048
+ color: var(--muted-foreground, #4a5568);
2049
+ }
2050
+
2051
+ .open-science-badges__list {
2052
+ display: flex;
2053
+ flex-wrap: wrap;
2054
+ gap: 1rem;
2055
+ padding: 0;
2056
+ margin: 0;
2057
+ list-style: none;
2058
+ }
2059
+
2060
+ .open-science-badge {
2061
+ display: grid;
2062
+ gap: 0.25rem;
2063
+ padding: 0.85rem 1rem;
2064
+ min-width: 10rem;
2065
+ border-radius: 0.75rem;
2066
+ background: rgba(12, 35, 64, 0.08);
2067
+ border: 1px solid rgba(12, 35, 64, 0.12);
2068
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
2069
+ }
2070
+
2071
+ .open-science-badge:focus-within,
2072
+ .open-science-badge:hover {
2073
+ transform: translateY(-2px);
2074
+ box-shadow: 0 8px 24px rgba(12, 35, 64, 0.12);
2075
+ }
2076
+
2077
+ .open-science-badge__label {
2078
+ font-weight: 600;
2079
+ }
2080
+
2081
+ .open-science-badge__description,
2082
+ .open-science-badge__criteria {
2083
+ font-size: 0.85rem;
2084
+ color: var(--muted-foreground, #4a5568);
2085
+ }
2086
+
2087
+ .academic-dashboard {
2088
+ display: grid;
2089
+ gap: 2.5rem;
2090
+ }
2091
+
2092
+ .academic-dashboard__header {
2093
+ text-align: center;
2094
+ max-width: 60ch;
2095
+ margin: 0 auto;
2096
+ }
2097
+
2098
+ .academic-dashboard__header h1 {
2099
+ font-size: clamp(1.8rem, 3vw, 2.4rem);
2100
+ margin-bottom: 0.5rem;
2101
+ }
2102
+
2103
+ .academic-dashboard__header p {
2104
+ color: var(--muted-foreground, #4a5568);
2105
+ }
2106
+
2107
+ .academic-dashboard__profiles {
2108
+ background: var(--surface-card, #fff);
2109
+ border-radius: 1.25rem;
2110
+ padding: 2rem;
2111
+ box-shadow: 0 12px 40px rgba(12, 35, 64, 0.08);
2112
+ }
2113
+
2114
+ .academic-profiles__grid {
2115
+ display: grid;
2116
+ gap: 1.5rem;
2117
+ }
2118
+
2119
+ @media (min-width: 56rem) {
2120
+ .academic-profiles__grid {
2121
+ grid-template-columns: repeat(2, minmax(0, 1fr));
2122
+ }
2123
+ }
2124
+
2125
+ .academic-profile {
2126
+ border: 1px solid rgba(12, 35, 64, 0.12);
2127
+ border-radius: 1rem;
2128
+ padding: 1.5rem;
2129
+ background: rgba(12, 35, 64, 0.03);
2130
+ display: grid;
2131
+ gap: 1rem;
2132
+ }
2133
+
2134
+ .academic-profile header {
2135
+ display: flex;
2136
+ justify-content: space-between;
2137
+ align-items: center;
2138
+ }
2139
+
2140
+ .academic-profile h3 {
2141
+ margin: 0;
2142
+ font-size: 1.1rem;
2143
+ }
2144
+
2145
+ .academic-profile a {
2146
+ font-size: 0.875rem;
2147
+ font-weight: 500;
2148
+ color: var(--accent, #3277f6);
2149
+ }
2150
+
2151
+ .academic-profile dl {
2152
+ display: grid;
2153
+ gap: 0.5rem;
2154
+ }
2155
+
2156
+ .academic-profile dl div {
2157
+ display: flex;
2158
+ justify-content: space-between;
2159
+ gap: 1rem;
2160
+ }
2161
+
2162
+ .academic-profile dt {
2163
+ font-weight: 600;
2164
+ color: var(--muted-foreground, #4a5568);
2165
+ }
2166
+
2167
+ .academic-profile dd {
2168
+ margin: 0;
2169
+ }
2170
+
2171
+ .citation-metrics {
2172
+ display: grid;
2173
+ gap: 1.5rem;
2174
+ border-radius: 1.25rem;
2175
+ padding: 2rem;
2176
+ background: rgba(50, 119, 246, 0.08);
2177
+ }
2178
+
2179
+ .citation-metrics__totals {
2180
+ display: grid;
2181
+ gap: 1rem;
2182
+ }
2183
+
2184
+ @media (min-width: 40rem) {
2185
+ .citation-metrics__totals {
2186
+ grid-template-columns: repeat(3, minmax(0, 1fr));
2187
+ }
2188
+ }
2189
+
2190
+ .citation-metrics .metric {
2191
+ background: rgba(255, 255, 255, 0.8);
2192
+ border-radius: 1rem;
2193
+ padding: 1rem;
2194
+ text-align: center;
2195
+ font-weight: 600;
2196
+ display: grid;
2197
+ gap: 0.5rem;
2198
+ }
2199
+
2200
+ .citation-metrics .metric dt {
2201
+ margin: 0;
2202
+ font-size: 0.9rem;
2203
+ color: var(--muted-foreground, #4a5568);
2204
+ }
2205
+
2206
+ .citation-metrics .metric dd {
2207
+ margin: 0;
2208
+ font-size: 1.5rem;
2209
+ }
2210
+
2211
+ .citation-metrics__details {
2212
+ background: rgba(255, 255, 255, 0.92);
2213
+ border-radius: 1rem;
2214
+ padding: 1rem 1.5rem;
2215
+ }
2216
+
2217
+ .citation-metrics__details ul {
2218
+ margin: 0;
2219
+ padding-left: 1.25rem;
2220
+ }
2221
+
2222
+ .citation-metrics__timeline {
2223
+ background: rgba(12, 35, 64, 0.08);
2224
+ border-radius: 1rem;
2225
+ padding: 1rem 1.5rem;
2226
+ }
2227
+
2228
+ .citation-metrics__timeline ul {
2229
+ display: grid;
2230
+ gap: 0.75rem;
2231
+ margin: 0;
2232
+ padding: 0;
2233
+ list-style: none;
2234
+ }
2235
+
2236
+ .citation-metrics__timeline li {
2237
+ display: flex;
2238
+ justify-content: space-between;
2239
+ align-items: center;
2240
+ gap: 1rem;
2241
+ padding: 0.5rem 0.75rem;
2242
+ border-radius: 0.75rem;
2243
+ background: linear-gradient(90deg, rgba(50, 119, 246, 0.15) var(--timeline-value, 35%), transparent 0);
2244
+ }
2245
+
2246
+ .bibliography-export {
2247
+ display: grid;
2248
+ gap: 1rem;
2249
+ }
2250
+
2251
+ .bibliography-export textarea {
2252
+ width: 100%;
2253
+ min-height: 16rem;
2254
+ font-family: var(--font-mono, "Fira Code", monospace);
2255
+ border-radius: 0.75rem;
2256
+ border: 1px solid rgba(12, 35, 64, 0.2);
2257
+ padding: 1.25rem;
2258
+ background: rgba(12, 35, 64, 0.04);
2259
+ }
2260
+
2261
+ .bibliography-export__actions {
2262
+ display: flex;
2263
+ flex-wrap: wrap;
2264
+ gap: 0.75rem;
2265
+ }
2266
+
2267
+ .submission-controls,
2268
+ .calendar-controls {
2269
+ display: flex;
2270
+ align-items: center;
2271
+ gap: 0.75rem;
2272
+ margin-bottom: 1rem;
2273
+ }
2274
+
2275
+ .submission-controls select,
2276
+ .calendar-controls select {
2277
+ border-radius: 0.5rem;
2278
+ padding: 0.5rem 0.75rem;
2279
+ }
2280
+
2281
+ .submission-list,
2282
+ .calendar-list,
2283
+ .funding-list,
2284
+ .opportunity-list,
2285
+ .mentorship-list,
2286
+ .workflow-list {
2287
+ list-style: none;
2288
+ margin: 0;
2289
+ padding: 0;
2290
+ display: grid;
2291
+ gap: 1rem;
2292
+ }
2293
+
2294
+ .submission-card,
2295
+ .calendar-list li,
2296
+ .funding-list li,
2297
+ .opportunity-list li,
2298
+ .mentorship-list li,
2299
+ .workflow-list li {
2300
+ border: 1px solid rgba(12, 35, 64, 0.12);
2301
+ border-radius: 1rem;
2302
+ padding: 1.25rem;
2303
+ background: rgba(255, 255, 255, 0.92);
2304
+ }
2305
+
2306
+ .status-badge {
2307
+ display: inline-flex;
2308
+ align-items: center;
2309
+ gap: 0.4rem;
2310
+ padding: 0.2rem 0.65rem;
2311
+ border-radius: 999px;
2312
+ background: rgba(50, 119, 246, 0.15);
2313
+ color: var(--accent-foreground, #0b1d3d);
2314
+ font-size: 0.85rem;
2315
+ font-weight: 600;
2316
+ }
2317
+
2318
+ .workflow-grid {
2319
+ display: grid;
2320
+ gap: 1.5rem;
2321
+ }
2322
+
2323
+ @media (min-width: 56rem) {
2324
+ .workflow-grid {
2325
+ grid-template-columns: repeat(2, minmax(0, 1fr));
2326
+ }
2327
+ }
2328
+
2329
+ .networking-grid {
2330
+ display: grid;
2331
+ gap: 1.25rem;
2332
+ }
2333
+
2334
+ @media (min-width: 48rem) {
2335
+ .networking-grid {
2336
+ grid-template-columns: repeat(2, minmax(0, 1fr));
2337
+ }
2338
+ }
2339
+
2340
+ .research-profiles {
2341
+ margin: 1.5rem 0;
2342
+ }
2343
+
2344
+ .research-profiles ul {
2345
+ display: flex;
2346
+ gap: 1rem;
2347
+ flex-wrap: wrap;
2348
+ list-style: none;
2349
+ padding: 0;
2350
+ margin: 0;
2351
+ }
2352
+
2353
+ .research-profiles a {
2354
+ font-weight: 600;
2355
+ color: var(--accent, #3277f6);
2356
+ }
2357
+
2358
+ .research-metrics {
2359
+ margin: 2rem 0;
2360
+ padding: 1.5rem;
2361
+ border-radius: 1rem;
2362
+ background: rgba(12, 35, 64, 0.05);
2363
+ }
2364
+
2365
+ .research-metrics__list {
2366
+ list-style: none;
2367
+ margin: 0;
2368
+ padding: 0;
2369
+ display: grid;
2370
+ gap: 0.75rem;
2371
+ }
2372
+
2373
+ .research-metric-label {
2374
+ font-weight: 600;
2375
+ }
2376
+
2377
+ .research-metric-value {
2378
+ font-variant-numeric: tabular-nums;
2379
+ margin-left: 0.5rem;
2380
+ }