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,368 @@
1
+ @use 'sass:map';
2
+
3
+ @use 'variables' as *;
4
+ @use 'mixins' as *;
5
+
6
+ .math-expression {
7
+ position: relative;
8
+ margin: map.get($spacing, 6) auto;
9
+ padding: map.get($spacing, 6) map.get($spacing, 6) map.get($spacing, 5) map.get($spacing, 6);
10
+ border-radius: 1.1rem;
11
+ border: 1px solid rgba($color-neutral-900, 0.12);
12
+ background: rgba($color-neutral-100, 0.9);
13
+ box-shadow: 0 12px 30px rgba($color-neutral-900, 0.08);
14
+ display: grid;
15
+ gap: map.get($spacing, 3);
16
+ transition: border-color $transition-snappy, box-shadow $transition-snappy, background $transition-snappy;
17
+
18
+ &:focus-within {
19
+ border-color: $color-accent-primary;
20
+ box-shadow: 0 0 0 4px rgba($color-accent-primary, 0.18);
21
+ background: rgba($color-neutral-100, 0.96);
22
+ }
23
+
24
+ mjx-container[display='true'] {
25
+ justify-self: center;
26
+ }
27
+ }
28
+
29
+ .math-expression--display {
30
+ max-width: 48rem;
31
+ }
32
+
33
+ .math-expression__inline {
34
+ display: inline-flex !important;
35
+ align-items: center;
36
+ padding: 0 map.get($spacing, 1);
37
+ margin: 0 map.get($spacing, 1);
38
+ background: rgba($color-accent-secondary, 0.15);
39
+ border-radius: 0.4rem;
40
+ font-family: $font-family-serif;
41
+ }
42
+
43
+ .math-expression__toolbar {
44
+ position: absolute;
45
+ top: map.get($spacing, 3);
46
+ left: map.get($spacing, 3);
47
+ display: inline-flex;
48
+ gap: map.get($spacing, 2);
49
+ z-index: 2;
50
+ }
51
+
52
+ .math-expression__button {
53
+ display: inline-flex;
54
+ align-items: center;
55
+ justify-content: center;
56
+ width: 2.25rem;
57
+ height: 2.25rem;
58
+ border-radius: 999px;
59
+ border: 1px solid rgba($color-neutral-900, 0.18);
60
+ background: white;
61
+ color: $color-ink-700;
62
+ font-size: map.get($font-size-scale, sm);
63
+ transition: background $transition-snappy, border-color $transition-snappy, color $transition-snappy;
64
+
65
+ &:hover,
66
+ &:focus-visible {
67
+ background: rgba($color-accent-primary, 0.1);
68
+ border-color: rgba($color-accent-primary, 0.35);
69
+ color: $color-accent-primary;
70
+ }
71
+
72
+ &:focus-visible {
73
+ @include focus-ring($color-accent-primary);
74
+ }
75
+ }
76
+
77
+ .math-expression__number {
78
+ position: absolute;
79
+ top: map.get($spacing, 3);
80
+ right: map.get($spacing, 3);
81
+ font-size: map.get($font-size-scale, xs);
82
+ font-weight: 600;
83
+ letter-spacing: 0.1em;
84
+ text-transform: uppercase;
85
+ color: $color-ink-500;
86
+ }
87
+
88
+ .math-expression__message {
89
+ position: absolute;
90
+ bottom: map.get($spacing, 3);
91
+ left: map.get($spacing, 3);
92
+ font-size: map.get($font-size-scale, xs);
93
+ color: $color-accent-primary;
94
+ background: rgba($color-accent-primary, 0.12);
95
+ padding: 0.25rem 0.6rem;
96
+ border-radius: 0.5rem;
97
+ box-shadow: inset 0 0 0 1px rgba($color-accent-primary, 0.2);
98
+ }
99
+
100
+ .math-reference {
101
+ font-family: $font-family-mono;
102
+ color: $color-accent-primary;
103
+ font-weight: 600;
104
+ }
105
+
106
+ .proof {
107
+ border-left: 4px solid $color-accent-tertiary;
108
+ padding-left: map.get($spacing, 4);
109
+ margin: map.get($spacing, 5) 0;
110
+ font-family: $font-family-serif;
111
+ }
112
+
113
+ .proof__title {
114
+ font-weight: 600;
115
+ text-transform: uppercase;
116
+ letter-spacing: 0.12em;
117
+ font-size: map.get($font-size-scale, xs);
118
+ color: $color-ink-500;
119
+ }
120
+
121
+ #math-tooling-panel {
122
+ position: fixed;
123
+ inset: 0;
124
+ display: grid;
125
+ place-items: center;
126
+ padding: map.get($spacing, 6);
127
+ background: rgba($color-neutral-900, 0.45);
128
+ backdrop-filter: blur(10px);
129
+ z-index: $z-overlay;
130
+
131
+ &[hidden] {
132
+ display: none;
133
+ }
134
+ }
135
+
136
+ .math-tooling {
137
+ background: $color-surface-50;
138
+ border-radius: 1.25rem;
139
+ padding: map.get($spacing, 6);
140
+ width: min(48rem, 100%);
141
+ box-shadow: $shadow-strong;
142
+ display: grid;
143
+ gap: map.get($spacing, 4);
144
+ }
145
+
146
+ .math-tooling__title {
147
+ margin: 0;
148
+ font-size: map.get($font-size-scale, xl);
149
+ }
150
+
151
+ .math-tooling__description {
152
+ margin: 0;
153
+ color: $color-ink-600;
154
+ font-size: map.get($font-size-scale, sm);
155
+ }
156
+
157
+ .math-tooling__input {
158
+ width: 100%;
159
+ min-height: 10rem;
160
+ border-radius: 1rem;
161
+ border: 1px solid rgba($color-neutral-900, 0.16);
162
+ padding: map.get($spacing, 4);
163
+ font-family: $font-family-mono;
164
+ font-size: map.get($font-size-scale, sm);
165
+ resize: vertical;
166
+
167
+ &:focus {
168
+ border-color: $color-accent-primary;
169
+ box-shadow: 0 0 0 3px rgba($color-accent-primary, 0.2);
170
+ outline: none;
171
+ }
172
+ }
173
+
174
+ .math-tooling__preview {
175
+ min-height: 6rem;
176
+ border-radius: 1rem;
177
+ border: 1px dashed rgba($color-neutral-900, 0.2);
178
+ background: rgba($color-neutral-100, 0.75);
179
+ padding: map.get($spacing, 5);
180
+ display: grid;
181
+ place-items: center;
182
+ text-align: center;
183
+ }
184
+
185
+ .math-tooling__placeholder {
186
+ margin: 0;
187
+ font-size: map.get($font-size-scale, sm);
188
+ color: $color-ink-500;
189
+ }
190
+
191
+ .math-tooling__actions {
192
+ display: flex;
193
+ justify-content: flex-end;
194
+ align-items: center;
195
+ gap: map.get($spacing, 3);
196
+ }
197
+
198
+ .math-tooling__copy,
199
+ .math-tooling__close {
200
+ border-radius: 999px;
201
+ border: 1px solid rgba($color-neutral-900, 0.18);
202
+ padding: 0.5rem 1.1rem;
203
+ font-size: map.get($font-size-scale, xs);
204
+ letter-spacing: 0.08em;
205
+ text-transform: uppercase;
206
+ background: white;
207
+ color: $color-ink-700;
208
+ transition: background $transition-snappy, border-color $transition-snappy, color $transition-snappy;
209
+
210
+ &:hover,
211
+ &:focus-visible {
212
+ background: rgba($color-accent-primary, 0.08);
213
+ border-color: rgba($color-accent-primary, 0.3);
214
+ color: $color-accent-primary;
215
+ }
216
+
217
+ &:focus-visible {
218
+ @include focus-ring($color-accent-primary);
219
+ }
220
+ }
221
+
222
+ .math-tooling__close {
223
+ display: inline-flex;
224
+ align-items: center;
225
+ justify-content: center;
226
+ width: 2.5rem;
227
+ height: 2.5rem;
228
+ padding: 0;
229
+ }
230
+
231
+ .math-tooling__status {
232
+ font-size: map.get($font-size-scale, xs);
233
+ color: $color-accent-primary;
234
+ }
235
+
236
+ .math-tooling__library {
237
+ border-top: 1px solid rgba($color-neutral-900, 0.1);
238
+ padding-top: map.get($spacing, 4);
239
+ display: grid;
240
+ gap: map.get($spacing, 3);
241
+ }
242
+
243
+ .math-tooling__library-title {
244
+ margin: 0;
245
+ font-size: map.get($font-size-scale, sm);
246
+ text-transform: uppercase;
247
+ letter-spacing: 0.08em;
248
+ color: $color-ink-500;
249
+ }
250
+
251
+ .math-tooling__symbols {
252
+ display: flex;
253
+ flex-wrap: wrap;
254
+ gap: map.get($spacing, 2);
255
+ }
256
+
257
+ .math-tooling__symbol {
258
+ border-radius: 0.75rem;
259
+ border: 1px solid rgba($color-neutral-900, 0.16);
260
+ padding: 0.45rem 0.9rem;
261
+ font-size: map.get($font-size-scale, xs);
262
+ background: rgba($color-neutral-100, 0.85);
263
+ color: $color-ink-700;
264
+ transition: background $transition-snappy, border-color $transition-snappy, color $transition-snappy;
265
+
266
+ &:hover,
267
+ &:focus-visible {
268
+ background: rgba($color-accent-secondary, 0.12);
269
+ border-color: rgba($color-accent-secondary, 0.4);
270
+ color: $color-accent-secondary;
271
+ }
272
+ }
273
+
274
+ .math-tooling-open {
275
+ overflow: hidden;
276
+ }
277
+
278
+ body.dark-mode {
279
+ .math-expression {
280
+ background: rgba($dark-surface-200, 0.92);
281
+ border-color: rgba($dark-ink-500, 0.3);
282
+ box-shadow: none;
283
+ }
284
+
285
+ .math-expression__number {
286
+ color: rgba($dark-ink-500, 0.85);
287
+ }
288
+
289
+ .math-expression__toolbar .math-expression__button {
290
+ background: $dark-surface-300;
291
+ border-color: rgba($dark-ink-500, 0.35);
292
+ color: $dark-ink-700;
293
+
294
+ &:hover,
295
+ &:focus-visible {
296
+ background: rgba($dark-accent-primary, 0.15);
297
+ border-color: rgba($dark-accent-primary, 0.45);
298
+ color: $dark-accent-primary;
299
+ }
300
+ }
301
+
302
+ .math-expression__message {
303
+ background: rgba($dark-accent-primary, 0.18);
304
+ color: $dark-accent-primary;
305
+ box-shadow: inset 0 0 0 1px rgba($dark-accent-primary, 0.35);
306
+ }
307
+
308
+ .math-expression__inline {
309
+ background: rgba($dark-accent-secondary, 0.2);
310
+ color: $dark-ink-900;
311
+ }
312
+
313
+ .math-tooling {
314
+ background: $dark-surface-200;
315
+ color: $dark-ink-900;
316
+ }
317
+
318
+ .math-tooling__description {
319
+ color: $dark-ink-700;
320
+ }
321
+
322
+ .math-tooling__input {
323
+ background: $dark-surface-300;
324
+ border-color: rgba($dark-ink-500, 0.35);
325
+ color: $dark-ink-900;
326
+
327
+ &:focus {
328
+ border-color: $dark-accent-primary;
329
+ box-shadow: 0 0 0 3px rgba($dark-accent-primary, 0.35);
330
+ }
331
+ }
332
+
333
+ .math-tooling__preview {
334
+ background: rgba($dark-surface-300, 0.85);
335
+ border-color: rgba($dark-ink-500, 0.25);
336
+ }
337
+
338
+ .math-tooling__copy,
339
+ .math-tooling__close {
340
+ background: $dark-surface-300;
341
+ border-color: rgba($dark-ink-500, 0.35);
342
+ color: $dark-ink-900;
343
+
344
+ &:hover,
345
+ &:focus-visible {
346
+ background: rgba($dark-accent-primary, 0.12);
347
+ border-color: rgba($dark-accent-primary, 0.45);
348
+ color: $dark-accent-primary;
349
+ }
350
+ }
351
+
352
+ .math-tooling__library-title {
353
+ color: $dark-ink-700;
354
+ }
355
+
356
+ .math-tooling__symbol {
357
+ background: rgba($dark-surface-300, 0.85);
358
+ border-color: rgba($dark-ink-500, 0.35);
359
+ color: $dark-ink-700;
360
+
361
+ &:hover,
362
+ &:focus-visible {
363
+ background: rgba($dark-accent-secondary, 0.18);
364
+ border-color: rgba($dark-accent-secondary, 0.45);
365
+ color: $dark-accent-secondary;
366
+ }
367
+ }
368
+ }
@@ -0,0 +1,99 @@
1
+ @use 'sass:map';
2
+ @use 'sass:math';
3
+
4
+ @use 'variables' as *;
5
+
6
+ // Media query helper referencing the $breakpoints map
7
+ @mixin respond-to($breakpoint) {
8
+ $value: map.get($breakpoints, $breakpoint);
9
+ @if $value {
10
+ @media (min-width: $value) {
11
+ @content;
12
+ }
13
+ } @else {
14
+ @warn 'Unknown breakpoint: #{$breakpoint}';
15
+ }
16
+ }
17
+
18
+ // Media query helper for max-width (desktop-first) queries
19
+ @mixin respond-below($breakpoint) {
20
+ $value: map.get($breakpoints, $breakpoint);
21
+ @if $value {
22
+ @media (max-width: $value) {
23
+ @content;
24
+ }
25
+ } @else {
26
+ @warn 'Unknown breakpoint: #{$breakpoint}';
27
+ }
28
+ }
29
+
30
+ // Fluid type scale for headings and hero text
31
+ @mixin fluid-type($min, $max, $min-vw: 20rem, $max-vw: 80rem) {
32
+ font-size: clamp($min, calc(#{$min} + (#{$max} - #{$min}) * ((100vw - #{$min-vw}) / (#{$max-vw} - #{$min-vw}))), $max);
33
+ }
34
+
35
+ // Accessible focus outline
36
+ @mixin focus-ring($color: $color-accent-secondary) {
37
+ outline: 2px solid $color;
38
+ outline-offset: 3px;
39
+ }
40
+
41
+ // Code block styling with subtle grid background
42
+ @mixin code-block($background: rgba($color-surface-900, 0.04)) {
43
+ background: linear-gradient(transparent 24px, rgba(0, 0, 0, 0.04) 24px) 0 0 / 100% 48px,
44
+ $background;
45
+ border: 1px solid rgba($color-ink-900, 0.08);
46
+ border-radius: 0.75rem;
47
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
48
+ padding: map.get($spacing, 5);
49
+ }
50
+
51
+ // Mathematical expression formatting for display equations
52
+ @mixin math-display {
53
+ font-family: $font-family-serif;
54
+ font-size: 1.05em;
55
+ line-height: $line-height-tight;
56
+ text-align: center;
57
+ margin: map.get($spacing, 5) auto;
58
+ display: block;
59
+ max-width: 100%;
60
+ overflow-x: auto;
61
+ -webkit-overflow-scrolling: touch;
62
+ }
63
+
64
+ // Responsive chart container using aspect ratio
65
+ @mixin responsive-chart($ratio: math.div(9, 16)) {
66
+ position: relative;
67
+ width: 100%;
68
+ padding-bottom: $ratio * 100%;
69
+ background: rgba($color-accent-primary, 0.04);
70
+ border: 1px solid rgba($color-accent-primary, 0.2);
71
+ border-radius: 0.75rem;
72
+ overflow: hidden;
73
+
74
+ iframe,
75
+ canvas,
76
+ svg,
77
+ object {
78
+ position: absolute;
79
+ top: 0;
80
+ left: 0;
81
+ width: 100%;
82
+ height: 100%;
83
+ }
84
+ }
85
+
86
+ // Data grid layout used across technical pages
87
+ @mixin data-grid($min: 18rem, $gap: map.get($spacing, 5)) {
88
+ display: grid;
89
+ grid-template-columns: repeat(auto-fit, minmax($min, 1fr));
90
+ gap: $gap;
91
+ }
92
+
93
+ // Utility for scientific callouts
94
+ @mixin callout($accent: $color-accent-secondary) {
95
+ border-left: 4px solid $accent;
96
+ background-color: rgba($accent, 0.08);
97
+ padding: map.get($spacing, 4) map.get($spacing, 5);
98
+ border-radius: 0.75rem;
99
+ }