datalog-theme 0.6.1 → 0.8.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 (147) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +175 -0
  3. data/CITATION.cff +2 -2
  4. data/README.md +26 -19
  5. data/_data/cdn-integrity.yml +0 -30
  6. data/_includes/analytics/dashboard.html +3 -1
  7. data/_includes/components/api-function.html +20 -1
  8. data/_includes/components/author-bio.html +2 -2
  9. data/_includes/components/enhanced-code-block.html +1 -1
  10. data/_includes/components/hero.html +19 -1
  11. data/_includes/csp-meta.html +115 -11
  12. data/_includes/footer.html +19 -20
  13. data/_includes/head.html +61 -29
  14. data/_includes/header/navigation.html +12 -15
  15. data/_includes/header.html +29 -20
  16. data/_includes/layouts/default/article.html +5 -1
  17. data/_includes/meta/math-config.html +27 -1
  18. data/_includes/meta/schema.html +5 -2
  19. data/_includes/meta/scripts-loader.html +16 -31
  20. data/_includes/post/related-posts.html +4 -7
  21. data/_includes/scripts.html +1 -9
  22. data/_includes/search/index-data.json +131 -0
  23. data/_includes/search/page.html +136 -0
  24. data/_layouts/dataset.html +1 -0
  25. data/_layouts/default.html +16 -8
  26. data/_layouts/home.html +6 -0
  27. data/_layouts/notebook.html +1 -0
  28. data/_layouts/package.html +1 -0
  29. data/_layouts/portfolio.html +1 -0
  30. data/_layouts/post.html +20 -5
  31. data/_layouts/project.html +2 -1
  32. data/_plugins/analytics_dashboard.rb +9 -3
  33. data/_plugins/config_validator.rb +12 -7
  34. data/_plugins/csp_generator.rb +18 -28
  35. data/_plugins/datalog_bibliography.rb +9 -7
  36. data/_plugins/datalog_comments.rb +8 -5
  37. data/_plugins/datalog_slides.rb +9 -8
  38. data/_plugins/i18n.rb +7 -8
  39. data/_plugins/image_optimizer.rb +17 -6
  40. data/_plugins/math_preprocessor.rb +36 -3
  41. data/_plugins/notebook_converter.rb +23 -43
  42. data/_plugins/plugin_loader.rb +3 -1
  43. data/_plugins/publications_generator.rb +8 -2
  44. data/_plugins/rouge_highlight_filter.rb +42 -0
  45. data/_plugins/search_code_blocks.rb +30 -0
  46. data/_plugins/search_normalizer.rb +15 -53
  47. data/_plugins/search_pages.rb +72 -0
  48. data/_sass/_academic-dashboard.scss +262 -0
  49. data/_sass/_base.scss +19 -1
  50. data/_sass/_components.scss +77 -1144
  51. data/_sass/_features.scss +17 -0
  52. data/_sass/_font-fallbacks.scss +43 -0
  53. data/_sass/_header.scss +10 -0
  54. data/_sass/_layout.scss +18 -12
  55. data/_sass/_mathematical.scss +1 -1
  56. data/_sass/_notebooks.scss +322 -0
  57. data/_sass/_open-science-badges.scss +56 -0
  58. data/_sass/{_phase1-enhancements.scss → _post-components.scss} +46 -1
  59. data/_sass/_search-page.scss +530 -0
  60. data/_sass/_search.scss +47 -1
  61. data/_sass/_syntax-highlighting.scss +212 -97
  62. data/_sass/_theme.scss +42 -18
  63. data/_sass/_typography.scss +14 -0
  64. data/_sass/_variables.scss +7 -4
  65. data/assets/css/main.scss +14 -0
  66. data/assets/img/hero-detail-640.webp +0 -0
  67. data/assets/img/hero-detail.webp +0 -0
  68. data/assets/img/social-card.png +0 -0
  69. data/assets/js/dist/academic.js +1 -0
  70. data/assets/js/dist/analytics-dashboard.js +1 -0
  71. data/assets/js/dist/chunks/chunk-225H5YXE.js +1 -0
  72. data/assets/js/dist/core.js +1 -0
  73. data/assets/js/dist/loader.js +1 -0
  74. data/assets/js/dist/math.js +1 -0
  75. data/assets/js/dist/notebook.js +1 -0
  76. data/assets/js/dist/search.js +1 -0
  77. data/assets/js/dist/visualizations.js +11 -0
  78. data/assets/js/loader.js +3 -1
  79. data/datalog-theme.gemspec +43 -22
  80. data/lib/datalog/cli.rb +53 -15
  81. data/lib/datalog/plugin_system/dependency_resolver.rb +0 -2
  82. data/lib/datalog/theme/package.rb +57 -0
  83. data/lib/datalog/theme/repository_checkout.rb +90 -0
  84. data/lib/datalog/theme/version.rb +1 -1
  85. data/lib/datalog/warning_filter.rb +5 -11
  86. data/lib/datalog-theme.rb +21 -0
  87. metadata +75 -146
  88. data/_data/academic.yml +0 -217
  89. data/_data/config/author.yml +0 -121
  90. data/_data/config/features.yml +0 -262
  91. data/_data/config/site.yml +0 -42
  92. data/_data/config/theme.yml +0 -181
  93. data/_data/datasets.yml +0 -28
  94. data/_data/js_meta.json +0 -371
  95. data/_data/navigation.yml +0 -145
  96. data/_data/projects.yml +0 -41
  97. data/_data/publications.yml +0 -28
  98. data/_data/social.yml +0 -73
  99. data/_data/visualizations.yml +0 -51
  100. data/_includes/components/advanced-search.html +0 -682
  101. data/_includes/components/bookmark-system.html +0 -96
  102. data/_includes/components/comments.html +0 -244
  103. data/_includes/components/content-recommendations.html +0 -228
  104. data/_includes/components/email-preferences.html +0 -200
  105. data/_includes/components/enhanced-metadata.html +0 -228
  106. data/_includes/components/language-switcher.html +0 -396
  107. data/_includes/components/navigation-enhancements.html +0 -454
  108. data/_includes/components/newsletter-signup.html +0 -178
  109. data/_includes/components/popular-posts.html +0 -233
  110. data/_includes/components/reading-progress.html +0 -133
  111. data/_includes/components/reading-time.html +0 -121
  112. data/_includes/components/series-navigation.html +0 -124
  113. data/_includes/components/social-proof.html +0 -34
  114. data/_includes/components/user-preferences.html +0 -566
  115. data/_layouts/archive.html +0 -282
  116. data/_layouts/post-sidebar.html +0 -183
  117. data/_sass/_phase3-enhancements.scss +0 -874
  118. data/_sass/_phase4-enhancements.scss +0 -1214
  119. data/_sass/_phase5-enhancements.scss +0 -414
  120. data/assets/img/20220607123041_detail.001.png +0 -0
  121. data/assets/js/academic.js +0 -262
  122. data/assets/js/analytics-dashboard.js +0 -382
  123. data/assets/js/core/dark-mode.js +0 -79
  124. data/assets/js/core/github-cards.js +0 -123
  125. data/assets/js/core/language-filter.js +0 -69
  126. data/assets/js/core/navigation.js +0 -184
  127. data/assets/js/core/scroll-progress.js +0 -45
  128. data/assets/js/core/search-hotkeys.js +0 -62
  129. data/assets/js/core/skip-links.js +0 -62
  130. data/assets/js/main.js +0 -23
  131. data/assets/js/math.js +0 -818
  132. data/assets/js/notebook.js +0 -158
  133. data/assets/js/search/analytics.js +0 -91
  134. data/assets/js/search/app.js +0 -271
  135. data/assets/js/search/autocomplete.js +0 -120
  136. data/assets/js/search/engine.js +0 -260
  137. data/assets/js/search/filters.js +0 -38
  138. data/assets/js/search/render.js +0 -217
  139. data/assets/js/search/utils.js +0 -99
  140. data/assets/js/search.js +0 -354
  141. data/assets/js/visualizations.js +0 -816
  142. data/assets/publications/datalog-publications.bib +0 -8
  143. data/assets/publications/datalog-publications.ris +0 -9
  144. data/assets/publications/publications.bib +0 -30
  145. data/assets/templates/diogo-ribeiro-cv.md +0 -31
  146. data/assets/templates/diogo-ribeiro-cv.tex +0 -32
  147. data/lib/datalog/theme/theme.rb +0 -18
@@ -1,1214 +0,0 @@
1
- // ============================================================================
2
- // Phase 4 Enhancements Stylesheet
3
- // Personalization, analytics, and UI polish
4
- // ============================================================================
5
-
6
- @use 'mixins' as *;
7
-
8
- // ----------------------------------------------------------------------------
9
- // User Preferences Panel
10
- // ----------------------------------------------------------------------------
11
-
12
- .user-preferences {
13
- position: relative;
14
- z-index: 1000;
15
-
16
- &--floating {
17
- position: fixed;
18
- bottom: 2rem;
19
- right: 2rem;
20
- }
21
-
22
- &__trigger {
23
- display: flex;
24
- align-items: center;
25
- gap: 0.5rem;
26
- padding: 0.875rem 1.25rem;
27
- background: var(--color-accent, #3b82f6);
28
- color: white;
29
- border: none;
30
- border-radius: 50px;
31
- cursor: pointer;
32
- font-size: 0.9375rem;
33
- font-weight: 500;
34
- box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
35
- transition: all 0.2s ease;
36
-
37
- svg {
38
- transition: transform 0.3s ease;
39
- }
40
-
41
- &:hover {
42
- transform: translateY(-2px);
43
- box-shadow: 0 6px 20px rgba(59, 130, 246, 0.4);
44
-
45
- svg {
46
- transform: rotate(45deg);
47
- }
48
- }
49
-
50
- &:active {
51
- transform: translateY(0);
52
- }
53
-
54
- &[aria-expanded="true"] svg {
55
- transform: rotate(45deg);
56
- }
57
- }
58
-
59
- &__panel {
60
- position: fixed;
61
- top: 50%;
62
- left: 50%;
63
- transform: translate(-50%, -50%);
64
- width: 90%;
65
- max-width: 500px;
66
- max-height: 90vh;
67
- background: white;
68
- border-radius: 16px;
69
- box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
70
- overflow: hidden;
71
- z-index: 1001;
72
- animation: slideInScale 0.3s cubic-bezier(0.16, 1, 0.3, 1);
73
- }
74
-
75
- &__backdrop {
76
- position: fixed;
77
- top: 0;
78
- left: 0;
79
- right: 0;
80
- bottom: 0;
81
- background: rgba(0, 0, 0, 0.5);
82
- z-index: 1000;
83
- animation: fadeIn 0.2s ease;
84
- }
85
-
86
- &__header {
87
- display: flex;
88
- align-items: center;
89
- justify-content: space-between;
90
- padding: 1.5rem;
91
- border-bottom: 1px solid var(--color-border, #e2e8f0);
92
- }
93
-
94
- &__title {
95
- display: flex;
96
- align-items: center;
97
- gap: 0.75rem;
98
- margin: 0;
99
- font-size: 1.25rem;
100
- color: var(--color-text-primary, #1a202c);
101
- }
102
-
103
- &__close {
104
- display: flex;
105
- align-items: center;
106
- justify-content: center;
107
- width: 36px;
108
- height: 36px;
109
- padding: 0;
110
- background: transparent;
111
- border: none;
112
- border-radius: 8px;
113
- cursor: pointer;
114
- color: var(--color-text-secondary, #4a5568);
115
- transition: all 0.2s ease;
116
-
117
- &:hover {
118
- background: var(--color-background-secondary, #f7fafc);
119
- color: var(--color-text-primary, #1a202c);
120
- }
121
- }
122
-
123
- &__content {
124
- padding: 1.5rem;
125
- max-height: calc(90vh - 140px);
126
- overflow-y: auto;
127
- }
128
-
129
- &__footer {
130
- padding: 1rem 1.5rem;
131
- border-top: 1px solid var(--color-border, #e2e8f0);
132
- background: var(--color-background-secondary, #f7fafc);
133
- }
134
-
135
- &__reset-all {
136
- display: flex;
137
- align-items: center;
138
- gap: 0.5rem;
139
- width: 100%;
140
- padding: 0.75rem;
141
- background: transparent;
142
- border: 1px solid var(--color-border, #cbd5e0);
143
- border-radius: 8px;
144
- cursor: pointer;
145
- font-size: 0.875rem;
146
- color: var(--color-text-secondary, #4a5568);
147
- transition: all 0.2s ease;
148
-
149
- &:hover {
150
- background: white;
151
- border-color: var(--color-text-secondary, #4a5568);
152
- color: var(--color-text-primary, #1a202c);
153
- }
154
- }
155
- }
156
-
157
- .preference-section {
158
- margin-bottom: 2rem;
159
-
160
- &:last-child {
161
- margin-bottom: 0;
162
- }
163
-
164
- &__title {
165
- display: flex;
166
- align-items: center;
167
- gap: 0.5rem;
168
- margin: 0 0 1rem;
169
- font-size: 0.9375rem;
170
- font-weight: 600;
171
- color: var(--color-text-primary, #1a202c);
172
- }
173
-
174
- &__control {
175
- // Container for controls
176
- }
177
- }
178
-
179
- // Theme toggle
180
- .theme-toggle {
181
- display: grid;
182
- grid-template-columns: repeat(3, 1fr);
183
- gap: 0.5rem;
184
-
185
- &__option {
186
- display: flex;
187
- flex-direction: column;
188
- align-items: center;
189
- gap: 0.5rem;
190
- padding: 1rem;
191
- background: var(--color-background-secondary, #f7fafc);
192
- border: 2px solid transparent;
193
- border-radius: 8px;
194
- cursor: pointer;
195
- transition: all 0.2s ease;
196
- color: var(--color-text-secondary, #4a5568);
197
-
198
- &:hover {
199
- background: white;
200
- border-color: var(--color-border, #cbd5e0);
201
- }
202
-
203
- &--active {
204
- background: var(--color-accent, #3b82f6);
205
- border-color: var(--color-accent, #3b82f6);
206
- color: white;
207
- }
208
-
209
- span {
210
- font-size: 0.875rem;
211
- font-weight: 500;
212
- }
213
- }
214
- }
215
-
216
- // Font size control
217
- .font-size-control {
218
- display: flex;
219
- align-items: center;
220
- gap: 1rem;
221
-
222
- &__button {
223
- flex-shrink: 0;
224
- width: 44px;
225
- height: 44px;
226
- display: flex;
227
- align-items: center;
228
- justify-content: center;
229
- background: var(--color-background-secondary, #f7fafc);
230
- border: 1px solid var(--color-border, #cbd5e0);
231
- border-radius: 8px;
232
- cursor: pointer;
233
- font-weight: 600;
234
- transition: all 0.2s ease;
235
-
236
- &:hover {
237
- background: white;
238
- border-color: var(--color-accent, #3b82f6);
239
- color: var(--color-accent, #3b82f6);
240
- }
241
- }
242
-
243
- &__label {
244
- font-size: 0.9375rem;
245
- }
246
-
247
- &__display {
248
- flex: 1;
249
- text-align: center;
250
- padding: 0.75rem;
251
- background: var(--color-background-secondary, #f7fafc);
252
- border-radius: 8px;
253
- font-weight: 600;
254
- color: var(--color-accent, #3b82f6);
255
- }
256
-
257
- &__reset {
258
- padding: 0.75rem 1rem;
259
- background: transparent;
260
- border: 1px solid var(--color-border, #cbd5e0);
261
- border-radius: 8px;
262
- cursor: pointer;
263
- font-size: 0.875rem;
264
- transition: all 0.2s ease;
265
-
266
- &:hover {
267
- background: var(--color-background-secondary, #f7fafc);
268
- border-color: var(--color-accent, #3b82f6);
269
- }
270
- }
271
- }
272
-
273
- // Toggle switch
274
- .toggle-switch {
275
- display: flex;
276
- align-items: center;
277
- gap: 1rem;
278
- cursor: pointer;
279
-
280
- input {
281
- position: absolute;
282
- opacity: 0;
283
- pointer-events: none;
284
-
285
- &:checked + .toggle-switch__slider {
286
- background: var(--color-accent, #3b82f6);
287
-
288
- &::before {
289
- transform: translateX(24px);
290
- }
291
- }
292
-
293
- &:focus + .toggle-switch__slider {
294
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
295
- }
296
- }
297
-
298
- &__slider {
299
- position: relative;
300
- width: 52px;
301
- height: 28px;
302
- background: var(--color-border, #cbd5e0);
303
- border-radius: 14px;
304
- transition: all 0.2s ease;
305
-
306
- &::before {
307
- content: '';
308
- position: absolute;
309
- top: 2px;
310
- left: 2px;
311
- width: 24px;
312
- height: 24px;
313
- background: white;
314
- border-radius: 50%;
315
- transition: transform 0.2s ease;
316
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
317
- }
318
- }
319
-
320
- &__label {
321
- font-size: 0.9375rem;
322
- color: var(--color-text-primary, #1a202c);
323
- }
324
- }
325
-
326
- // Layout toggle
327
- .layout-toggle {
328
- display: grid;
329
- grid-template-columns: repeat(2, 1fr);
330
- gap: 0.5rem;
331
-
332
- &__option {
333
- display: flex;
334
- flex-direction: column;
335
- align-items: center;
336
- gap: 0.5rem;
337
- padding: 1rem;
338
- background: var(--color-background-secondary, #f7fafc);
339
- border: 2px solid transparent;
340
- border-radius: 8px;
341
- cursor: pointer;
342
- transition: all 0.2s ease;
343
-
344
- &:hover {
345
- background: white;
346
- border-color: var(--color-border, #cbd5e0);
347
- }
348
-
349
- &--active {
350
- background: var(--color-accent, #3b82f6);
351
- border-color: var(--color-accent, #3b82f6);
352
- color: white;
353
- }
354
-
355
- span {
356
- font-size: 0.875rem;
357
- font-weight: 500;
358
- }
359
- }
360
- }
361
-
362
- // Apply user font size preference
363
- :root {
364
- --user-font-size: 100%;
365
- }
366
-
367
- body {
368
- font-size: calc(var(--base-font-size, 1rem) * var(--user-font-size) / 100);
369
- }
370
-
371
- // Reading mode
372
- body.reading-mode {
373
- .site-header,
374
- .site-footer,
375
- aside:not(.enhanced-toc),
376
- .social-share,
377
- .comments-section,
378
- .content-recommendations {
379
- opacity: 0.3;
380
- pointer-events: none;
381
- transition: opacity 0.3s ease;
382
- }
383
-
384
- &:hover {
385
- .site-header,
386
- .site-footer,
387
- aside:not(.enhanced-toc),
388
- .social-share,
389
- .comments-section,
390
- .content-recommendations {
391
- opacity: 1;
392
- pointer-events: auto;
393
- }
394
- }
395
- }
396
-
397
- // ----------------------------------------------------------------------------
398
- // Popular Posts Widget
399
- // ----------------------------------------------------------------------------
400
-
401
- .popular-posts {
402
- padding: 1.5rem;
403
- background: var(--color-background-secondary, #f7fafc);
404
- border-radius: 12px;
405
- margin: 2rem 0;
406
-
407
- &__header {
408
- margin-bottom: 1.5rem;
409
- }
410
-
411
- &__title {
412
- display: flex;
413
- align-items: center;
414
- gap: 0.75rem;
415
- margin: 0 0 0.5rem;
416
- font-size: 1.25rem;
417
- color: var(--color-text-primary, #1a202c);
418
- }
419
-
420
- &__subtitle {
421
- font-size: 0.875rem;
422
- color: var(--color-text-secondary, #4a5568);
423
- }
424
-
425
- &__list {
426
- display: flex;
427
- flex-direction: column;
428
- gap: 1rem;
429
- }
430
-
431
- &__footer {
432
- margin-top: 1.5rem;
433
- text-align: center;
434
- }
435
-
436
- &__view-all {
437
- display: inline-flex;
438
- align-items: center;
439
- gap: 0.5rem;
440
- padding: 0.75rem 1.5rem;
441
- background: white;
442
- border: 1px solid var(--color-border, #cbd5e0);
443
- border-radius: 8px;
444
- color: var(--color-text-primary, #1a202c);
445
- text-decoration: none;
446
- font-weight: 500;
447
- transition: all 0.2s ease;
448
-
449
- &:hover {
450
- background: var(--color-accent, #3b82f6);
451
- color: white;
452
- border-color: var(--color-accent, #3b82f6);
453
-
454
- svg {
455
- transform: translateX(4px);
456
- }
457
- }
458
-
459
- svg {
460
- transition: transform 0.2s ease;
461
- }
462
- }
463
- }
464
-
465
- .popular-post {
466
- position: relative;
467
- display: flex;
468
- gap: 1rem;
469
- padding: 1rem;
470
- background: white;
471
- border-radius: 8px;
472
- border: 1px solid var(--color-border, #e2e8f0);
473
- transition: all 0.2s ease;
474
-
475
- &:hover {
476
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
477
- transform: translateY(-2px);
478
- }
479
-
480
- &__rank {
481
- flex-shrink: 0;
482
- width: 32px;
483
- height: 32px;
484
- display: flex;
485
- align-items: center;
486
- justify-content: center;
487
- background: linear-gradient(135deg, var(--color-accent, #3b82f6), var(--color-accent-dark, #2563eb));
488
- color: white;
489
- border-radius: 8px;
490
- font-weight: 700;
491
- font-size: 0.875rem;
492
- }
493
-
494
- &__thumbnail {
495
- flex-shrink: 0;
496
- width: 80px;
497
- height: 80px;
498
- border-radius: 8px;
499
- overflow: hidden;
500
- background: var(--color-background-secondary, #f7fafc);
501
-
502
- img {
503
- width: 100%;
504
- height: 100%;
505
- object-fit: cover;
506
- transition: transform 0.3s ease;
507
- }
508
-
509
- &:hover img {
510
- transform: scale(1.1);
511
- }
512
- }
513
-
514
- &__content {
515
- flex: 1;
516
- min-width: 0;
517
- }
518
-
519
- &__title {
520
- margin: 0 0 0.5rem;
521
- font-size: 1rem;
522
- line-height: 1.4;
523
- }
524
-
525
- &__link {
526
- color: var(--color-text-primary, #1a202c);
527
- text-decoration: none;
528
- transition: color 0.2s ease;
529
-
530
- &:hover {
531
- color: var(--color-accent, #3b82f6);
532
- }
533
- }
534
-
535
- &__meta {
536
- display: flex;
537
- gap: 0.5rem;
538
- flex-wrap: wrap;
539
- align-items: center;
540
- font-size: 0.8125rem;
541
- color: var(--color-text-secondary, #4a5568);
542
- margin-bottom: 0.5rem;
543
- }
544
-
545
- &__separator {
546
- opacity: 0.5;
547
- }
548
-
549
- &__views {
550
- display: flex;
551
- align-items: center;
552
- gap: 0.25rem;
553
- }
554
-
555
- &__excerpt {
556
- margin: 0;
557
- font-size: 0.875rem;
558
- line-height: 1.5;
559
- color: var(--color-text-secondary, #4a5568);
560
- }
561
-
562
- &__tags {
563
- display: flex;
564
- gap: 0.5rem;
565
- flex-wrap: wrap;
566
- margin-top: 0.5rem;
567
- }
568
-
569
- &__tag {
570
- padding: 0.25rem 0.5rem;
571
- background: var(--color-background-secondary, #f7fafc);
572
- border-radius: 4px;
573
- font-size: 0.75rem;
574
- color: var(--color-text-secondary, #4a5568);
575
- }
576
-
577
- &__badge {
578
- position: absolute;
579
- top: 0.5rem;
580
- right: 0.5rem;
581
- padding: 0.25rem 0.5rem;
582
- background: linear-gradient(135deg, #f59e0b, #ef4444);
583
- color: white;
584
- border-radius: 4px;
585
- font-size: 0.75rem;
586
- font-weight: 600;
587
- display: flex;
588
- align-items: center;
589
- gap: 0.25rem;
590
- box-shadow: 0 2px 8px rgba(245, 158, 11, 0.3);
591
- }
592
- }
593
-
594
- // ----------------------------------------------------------------------------
595
- // Back to Top Button
596
- // ----------------------------------------------------------------------------
597
-
598
- .back-to-top {
599
- position: fixed;
600
- bottom: 2rem;
601
- right: 2rem;
602
- width: 52px;
603
- height: 52px;
604
- display: flex;
605
- flex-direction: column;
606
- align-items: center;
607
- justify-content: center;
608
- gap: 0.125rem;
609
- background: var(--color-accent, #3b82f6);
610
- color: white;
611
- border: none;
612
- border-radius: 50%;
613
- cursor: pointer;
614
- box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
615
- transition: all 0.2s ease;
616
- z-index: 100;
617
- animation: slideInUp 0.3s ease;
618
-
619
- &:hover {
620
- transform: translateY(-4px);
621
- box-shadow: 0 6px 20px rgba(59, 130, 246, 0.4);
622
- }
623
-
624
- &:active {
625
- transform: translateY(-2px);
626
- }
627
-
628
- &__text {
629
- font-size: 0.625rem;
630
- font-weight: 600;
631
- text-transform: uppercase;
632
- letter-spacing: 0.05em;
633
- }
634
-
635
- &__progress {
636
- position: absolute;
637
- top: 0;
638
- left: 0;
639
- transform: rotate(-90deg);
640
- opacity: 0.3;
641
- }
642
-
643
- &__progress-indicator {
644
- transition: stroke-dashoffset 0.1s ease;
645
- }
646
- }
647
-
648
- // ----------------------------------------------------------------------------
649
- // Keyboard Shortcuts Panel
650
- // ----------------------------------------------------------------------------
651
-
652
- .keyboard-shortcuts {
653
- position: fixed;
654
- top: 0;
655
- left: 0;
656
- right: 0;
657
- bottom: 0;
658
- z-index: 1001;
659
- display: flex;
660
- align-items: center;
661
- justify-content: center;
662
- padding: 2rem;
663
-
664
- &__content {
665
- position: relative;
666
- width: 100%;
667
- max-width: 600px;
668
- max-height: 90vh;
669
- background: white;
670
- border-radius: 16px;
671
- box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
672
- overflow: hidden;
673
- z-index: 1;
674
- animation: slideInScale 0.3s cubic-bezier(0.16, 1, 0.3, 1);
675
- }
676
-
677
- &__backdrop {
678
- position: absolute;
679
- top: 0;
680
- left: 0;
681
- right: 0;
682
- bottom: 0;
683
- background: rgba(0, 0, 0, 0.5);
684
- animation: fadeIn 0.2s ease;
685
- }
686
-
687
- &__header {
688
- display: flex;
689
- align-items: center;
690
- justify-content: space-between;
691
- padding: 1.5rem;
692
- border-bottom: 1px solid var(--color-border, #e2e8f0);
693
- }
694
-
695
- &__title {
696
- display: flex;
697
- align-items: center;
698
- gap: 0.75rem;
699
- margin: 0;
700
- font-size: 1.25rem;
701
- color: var(--color-text-primary, #1a202c);
702
- }
703
-
704
- &__close {
705
- display: flex;
706
- align-items: center;
707
- justify-content: center;
708
- width: 36px;
709
- height: 36px;
710
- padding: 0;
711
- background: transparent;
712
- border: none;
713
- border-radius: 8px;
714
- cursor: pointer;
715
- color: var(--color-text-secondary, #4a5568);
716
- transition: all 0.2s ease;
717
-
718
- &:hover {
719
- background: var(--color-background-secondary, #f7fafc);
720
- color: var(--color-text-primary, #1a202c);
721
- }
722
- }
723
-
724
- &__body {
725
- padding: 1.5rem;
726
- max-height: calc(90vh - 180px);
727
- overflow-y: auto;
728
- }
729
-
730
- &__footer {
731
- padding: 1rem 1.5rem;
732
- border-top: 1px solid var(--color-border, #e2e8f0);
733
- background: var(--color-background-secondary, #f7fafc);
734
- text-align: center;
735
- }
736
-
737
- &__hint {
738
- margin: 0;
739
- font-size: 0.875rem;
740
- color: var(--color-text-secondary, #4a5568);
741
-
742
- kbd {
743
- margin: 0 0.25rem;
744
- }
745
- }
746
- }
747
-
748
- .shortcuts-section {
749
- margin-bottom: 2rem;
750
-
751
- &:last-child {
752
- margin-bottom: 0;
753
- }
754
-
755
- &__title {
756
- margin: 0 0 1rem;
757
- font-size: 0.875rem;
758
- font-weight: 600;
759
- text-transform: uppercase;
760
- letter-spacing: 0.05em;
761
- color: var(--color-text-secondary, #4a5568);
762
- }
763
- }
764
-
765
- .shortcuts-list {
766
- margin: 0;
767
-
768
- &__item {
769
- display: flex;
770
- align-items: center;
771
- justify-content: space-between;
772
- padding: 0.75rem 0;
773
- border-bottom: 1px solid var(--color-border, #e2e8f0);
774
-
775
- &:last-child {
776
- border-bottom: none;
777
- }
778
- }
779
-
780
- &__keys {
781
- display: flex;
782
- gap: 0.5rem;
783
- margin: 0;
784
- font-weight: normal;
785
- }
786
-
787
- &__description {
788
- margin: 0;
789
- font-size: 0.9375rem;
790
- color: var(--color-text-primary, #1a202c);
791
- }
792
- }
793
-
794
- kbd {
795
- display: inline-block;
796
- padding: 0.25rem 0.5rem;
797
- background: var(--color-background-secondary, #f7fafc);
798
- border: 1px solid var(--color-border, #cbd5e0);
799
- border-radius: 4px;
800
- font-family: var(--font-mono, monospace);
801
- font-size: 0.8125rem;
802
- font-weight: 600;
803
- color: var(--color-text-primary, #1a202c);
804
- box-shadow: 0 2px 0 var(--color-border, #cbd5e0);
805
- }
806
-
807
- // ----------------------------------------------------------------------------
808
- // Social Proof Indicators
809
- // ----------------------------------------------------------------------------
810
-
811
- .social-proof {
812
- display: flex;
813
- align-items: center;
814
- gap: 1rem;
815
- flex-wrap: wrap;
816
- padding: 1rem;
817
- background: var(--color-background-secondary, #f7fafc);
818
- border-radius: 8px;
819
- margin: 1.5rem 0;
820
-
821
- &--compact {
822
- padding: 0.75rem;
823
- gap: 0.75rem;
824
- }
825
-
826
- &__badge {
827
- display: inline-flex;
828
- align-items: center;
829
- gap: 0.375rem;
830
- padding: 0.375rem 0.75rem;
831
- border-radius: 6px;
832
- font-size: 0.8125rem;
833
- font-weight: 600;
834
-
835
- &--trending {
836
- background: linear-gradient(135deg, #f59e0b, #ef4444);
837
- color: white;
838
- box-shadow: 0 2px 8px rgba(245, 158, 11, 0.3);
839
- }
840
- }
841
-
842
- &__metrics {
843
- display: flex;
844
- align-items: center;
845
- gap: 1.5rem;
846
- flex-wrap: wrap;
847
- flex: 1;
848
- }
849
-
850
- &__metric {
851
- display: flex;
852
- align-items: center;
853
- gap: 0.5rem;
854
- font-size: 0.875rem;
855
- color: var(--color-text-secondary, #4a5568);
856
-
857
- &--live {
858
- animation: pulse 2s ease-in-out infinite;
859
- }
860
- }
861
-
862
- &__icon {
863
- flex-shrink: 0;
864
- color: var(--color-accent, #3b82f6);
865
-
866
- &--pulse {
867
- animation: iconPulse 2s ease-in-out infinite;
868
- }
869
- }
870
-
871
- &__value {
872
- font-weight: 600;
873
- color: var(--color-text-primary, #1a202c);
874
-
875
- &--live {
876
- color: #10b981;
877
- }
878
- }
879
-
880
- &__label {
881
- color: var(--color-text-secondary, #4a5568);
882
- }
883
-
884
- &__quality {
885
- display: flex;
886
- align-items: center;
887
- color: #f59e0b;
888
- }
889
- }
890
-
891
- // ----------------------------------------------------------------------------
892
- // Enhanced Metadata Display
893
- // ----------------------------------------------------------------------------
894
-
895
- .enhanced-metadata {
896
- padding: 1.5rem;
897
- background: var(--color-background-secondary, #f7fafc);
898
- border-radius: 12px;
899
- margin: 1.5rem 0;
900
-
901
- &--card {
902
- border: 1px solid var(--color-border, #e2e8f0);
903
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
904
- }
905
-
906
- &__primary {
907
- display: flex;
908
- flex-wrap: wrap;
909
- gap: 1.5rem;
910
- margin-bottom: 1rem;
911
- }
912
-
913
- &__categories,
914
- &__tags {
915
- display: flex;
916
- align-items: center;
917
- gap: 0.75rem;
918
- margin-top: 1rem;
919
- padding-top: 1rem;
920
- border-top: 1px solid var(--color-border, #e2e8f0);
921
- }
922
-
923
- &__categories-icon,
924
- &__tags-icon {
925
- flex-shrink: 0;
926
- color: var(--color-text-secondary, #4a5568);
927
- }
928
- }
929
-
930
- .metadata-item {
931
- display: flex;
932
- align-items: center;
933
- gap: 0.5rem;
934
- font-size: 0.875rem;
935
-
936
- &__icon {
937
- flex-shrink: 0;
938
- color: var(--color-accent, #3b82f6);
939
- }
940
-
941
- &__label {
942
- color: var(--color-text-secondary, #4a5568);
943
- font-weight: 500;
944
- }
945
-
946
- &__value {
947
- color: var(--color-text-primary, #1a202c);
948
- font-weight: 600;
949
- }
950
-
951
- &__separator {
952
- margin: 0 0.25rem;
953
- color: var(--color-text-secondary, #4a5568);
954
- opacity: 0.5;
955
- }
956
- }
957
-
958
- .reading-level {
959
- display: inline-block;
960
- padding: 0.375rem 0.75rem;
961
- border-radius: 6px;
962
- font-size: 0.8125rem;
963
- font-weight: 600;
964
-
965
- &--quick {
966
- background: #dbeafe;
967
- color: #1e40af;
968
- }
969
-
970
- &--standard {
971
- background: #d1fae5;
972
- color: #065f46;
973
- }
974
-
975
- &--in-depth {
976
- background: #fef3c7;
977
- color: #92400e;
978
- }
979
-
980
- &--comprehensive {
981
- background: #fce7f3;
982
- color: #9f1239;
983
- }
984
- }
985
-
986
- .category-path {
987
- display: flex;
988
- align-items: center;
989
- flex-wrap: wrap;
990
- gap: 0.5rem;
991
-
992
- &__separator {
993
- color: var(--color-text-secondary, #4a5568);
994
- opacity: 0.5;
995
- }
996
-
997
- &__link {
998
- color: var(--color-text-primary, #1a202c);
999
- text-decoration: none;
1000
- font-weight: 500;
1001
- transition: color 0.2s ease;
1002
-
1003
- &:hover {
1004
- color: var(--color-accent, #3b82f6);
1005
- }
1006
- }
1007
- }
1008
-
1009
- .tags-cloud {
1010
- display: flex;
1011
- flex-wrap: wrap;
1012
- gap: 0.5rem;
1013
- flex: 1;
1014
- }
1015
-
1016
- .tag-pill {
1017
- display: inline-block;
1018
- padding: 0.375rem 0.75rem;
1019
- background: white;
1020
- border: 1px solid var(--color-border, #e2e8f0);
1021
- border-radius: 6px;
1022
- font-size: 0.8125rem;
1023
- color: var(--color-text-primary, #1a202c);
1024
- text-decoration: none;
1025
- transition: all 0.2s ease;
1026
-
1027
- &:hover {
1028
- background: var(--color-accent, #3b82f6);
1029
- color: white;
1030
- border-color: var(--color-accent, #3b82f6);
1031
- }
1032
- }
1033
-
1034
- // ----------------------------------------------------------------------------
1035
- // Animations
1036
- // ----------------------------------------------------------------------------
1037
-
1038
- @keyframes slideInUp {
1039
- from {
1040
- transform: translateY(100px);
1041
- opacity: 0;
1042
- }
1043
- to {
1044
- transform: translateY(0);
1045
- opacity: 1;
1046
- }
1047
- }
1048
-
1049
- @keyframes slideInScale {
1050
- from {
1051
- transform: translate(-50%, -50%) scale(0.9);
1052
- opacity: 0;
1053
- }
1054
- to {
1055
- transform: translate(-50%, -50%) scale(1);
1056
- opacity: 1;
1057
- }
1058
- }
1059
-
1060
- @keyframes fadeIn {
1061
- from {
1062
- opacity: 0;
1063
- }
1064
- to {
1065
- opacity: 1;
1066
- }
1067
- }
1068
-
1069
- @keyframes pulse {
1070
- 0%, 100% {
1071
- opacity: 1;
1072
- }
1073
- 50% {
1074
- opacity: 0.6;
1075
- }
1076
- }
1077
-
1078
- @keyframes iconPulse {
1079
- 0%, 100% {
1080
- transform: scale(1);
1081
- }
1082
- 50% {
1083
- transform: scale(1.1);
1084
- }
1085
- }
1086
-
1087
- // ----------------------------------------------------------------------------
1088
- // Responsive Design
1089
- // ----------------------------------------------------------------------------
1090
-
1091
- @include respond-below(md) {
1092
- .user-preferences {
1093
- &--floating {
1094
- bottom: 1rem;
1095
- right: 1rem;
1096
- }
1097
-
1098
- &__trigger-text {
1099
- display: none;
1100
- }
1101
-
1102
- &__panel {
1103
- width: 95%;
1104
- max-height: 95vh;
1105
- }
1106
- }
1107
-
1108
- .back-to-top {
1109
- bottom: 1rem;
1110
- right: 1rem;
1111
- width: 48px;
1112
- height: 48px;
1113
- }
1114
-
1115
- .popular-post {
1116
- flex-direction: column;
1117
-
1118
- &__thumbnail {
1119
- width: 100%;
1120
- height: 180px;
1121
- }
1122
-
1123
- &__badge {
1124
- top: 0.75rem;
1125
- right: 0.75rem;
1126
- }
1127
- }
1128
-
1129
- .social-proof {
1130
- flex-direction: column;
1131
- align-items: flex-start;
1132
-
1133
- &__metrics {
1134
- width: 100%;
1135
- gap: 1rem;
1136
- }
1137
- }
1138
-
1139
- .enhanced-metadata {
1140
- &__primary {
1141
- flex-direction: column;
1142
- gap: 1rem;
1143
- }
1144
- }
1145
-
1146
- .keyboard-shortcuts {
1147
- padding: 1rem;
1148
-
1149
- &__content {
1150
- max-width: 100%;
1151
- }
1152
- }
1153
- }
1154
-
1155
- // ----------------------------------------------------------------------------
1156
- // Print Styles
1157
- // ----------------------------------------------------------------------------
1158
-
1159
- @media print {
1160
- .user-preferences,
1161
- .back-to-top,
1162
- .keyboard-shortcuts,
1163
- .popular-posts {
1164
- display: none !important;
1165
- }
1166
-
1167
- .social-proof,
1168
- .enhanced-metadata {
1169
- border: 1px solid #ddd;
1170
- box-shadow: none;
1171
- }
1172
- }
1173
-
1174
- // ----------------------------------------------------------------------------
1175
- // Accessibility
1176
- // ----------------------------------------------------------------------------
1177
-
1178
- @media (prefers-reduced-motion: reduce) {
1179
- .user-preferences__trigger svg,
1180
- .back-to-top,
1181
- .popular-post,
1182
- .social-proof__icon--pulse {
1183
- animation: none !important;
1184
- transition: none !important;
1185
- }
1186
-
1187
- .back-to-top:hover {
1188
- transform: none;
1189
- }
1190
- }
1191
-
1192
- @media (prefers-contrast: high) {
1193
- .user-preferences__trigger,
1194
- .back-to-top {
1195
- border: 2px solid currentColor;
1196
- }
1197
-
1198
- .theme-toggle__option--active,
1199
- .layout-toggle__option--active {
1200
- outline: 3px solid currentColor;
1201
- }
1202
- }
1203
-
1204
- .visually-hidden {
1205
- position: absolute;
1206
- width: 1px;
1207
- height: 1px;
1208
- padding: 0;
1209
- margin: -1px;
1210
- overflow: hidden;
1211
- clip: rect(0, 0, 0, 0);
1212
- white-space: nowrap;
1213
- border-width: 0;
1214
- }