datalog-theme 0.7.0 → 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 (133) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +125 -0
  3. data/CITATION.cff +2 -2
  4. data/README.md +23 -17
  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/enhanced-code-block.html +1 -1
  9. data/_includes/csp-meta.html +115 -11
  10. data/_includes/footer.html +19 -20
  11. data/_includes/head.html +60 -23
  12. data/_includes/header/navigation.html +12 -15
  13. data/_includes/header.html +28 -19
  14. data/_includes/layouts/default/article.html +5 -1
  15. data/_includes/meta/math-config.html +9 -5
  16. data/_includes/meta/schema.html +5 -2
  17. data/_includes/meta/scripts-loader.html +16 -32
  18. data/_includes/post/related-posts.html +4 -7
  19. data/_includes/search/index-data.json +9 -34
  20. data/_layouts/dataset.html +1 -0
  21. data/_layouts/default.html +16 -8
  22. data/_layouts/notebook.html +1 -0
  23. data/_layouts/package.html +1 -0
  24. data/_layouts/portfolio.html +1 -0
  25. data/_layouts/post.html +20 -5
  26. data/_layouts/project.html +2 -1
  27. data/_plugins/analytics_dashboard.rb +9 -3
  28. data/_plugins/config_validator.rb +12 -7
  29. data/_plugins/csp_generator.rb +18 -28
  30. data/_plugins/datalog_bibliography.rb +9 -7
  31. data/_plugins/datalog_comments.rb +8 -5
  32. data/_plugins/datalog_slides.rb +9 -8
  33. data/_plugins/i18n.rb +7 -8
  34. data/_plugins/image_optimizer.rb +17 -6
  35. data/_plugins/math_preprocessor.rb +33 -3
  36. data/_plugins/notebook_converter.rb +23 -4
  37. data/_plugins/plugin_loader.rb +3 -1
  38. data/_plugins/publications_generator.rb +8 -2
  39. data/_plugins/rouge_highlight_filter.rb +42 -0
  40. data/_plugins/search_code_blocks.rb +30 -0
  41. data/_plugins/search_normalizer.rb +15 -53
  42. data/_plugins/search_pages.rb +3 -4
  43. data/_sass/_academic-dashboard.scss +262 -0
  44. data/_sass/_base.scss +12 -0
  45. data/_sass/_components.scss +64 -1153
  46. data/_sass/_features.scss +17 -0
  47. data/_sass/_layout.scss +1 -1
  48. data/_sass/_notebooks.scss +322 -0
  49. data/_sass/_open-science-badges.scss +56 -0
  50. data/_sass/{_phase1-enhancements.scss → _post-components.scss} +1 -1
  51. data/_sass/_search-page.scss +530 -0
  52. data/_sass/_search.scss +46 -0
  53. data/_sass/_syntax-highlighting.scss +212 -97
  54. data/_sass/_theme.scss +29 -19
  55. data/_sass/_typography.scss +14 -0
  56. data/assets/css/main.scss +14 -0
  57. data/assets/js/dist/academic.js +1 -1
  58. data/assets/js/dist/analytics-dashboard.js +1 -1
  59. data/assets/js/dist/chunks/chunk-225H5YXE.js +1 -0
  60. data/assets/js/dist/core.js +1 -1
  61. data/assets/js/dist/loader.js +1 -1
  62. data/assets/js/dist/notebook.js +1 -1
  63. data/assets/js/dist/search.js +1 -1
  64. data/assets/js/dist/visualizations.js +11 -2
  65. data/assets/js/loader.js +3 -1
  66. data/datalog-theme.gemspec +36 -23
  67. data/lib/datalog/cli.rb +34 -14
  68. data/lib/datalog/plugin_system/dependency_resolver.rb +0 -2
  69. data/lib/datalog/theme/package.rb +57 -0
  70. data/lib/datalog/theme/repository_checkout.rb +90 -0
  71. data/lib/datalog/theme/version.rb +1 -1
  72. data/lib/datalog/warning_filter.rb +5 -11
  73. data/lib/datalog-theme.rb +5 -0
  74. metadata +48 -133
  75. data/_data/academic.yml +0 -217
  76. data/_data/config/author.yml +0 -121
  77. data/_data/datasets.yml +0 -28
  78. data/_data/js_meta.json +0 -371
  79. data/_data/navigation.yml +0 -145
  80. data/_data/projects.yml +0 -41
  81. data/_data/publications.yml +0 -28
  82. data/_data/social.yml +0 -73
  83. data/_data/visualizations.yml +0 -51
  84. data/_includes/components/advanced-search.html +0 -682
  85. data/_includes/components/bookmark-system.html +0 -96
  86. data/_includes/components/comments.html +0 -244
  87. data/_includes/components/content-recommendations.html +0 -228
  88. data/_includes/components/email-preferences.html +0 -200
  89. data/_includes/components/enhanced-metadata.html +0 -228
  90. data/_includes/components/language-switcher.html +0 -396
  91. data/_includes/components/navigation-enhancements.html +0 -454
  92. data/_includes/components/newsletter-signup.html +0 -178
  93. data/_includes/components/popular-posts.html +0 -233
  94. data/_includes/components/reading-progress.html +0 -133
  95. data/_includes/components/reading-time.html +0 -121
  96. data/_includes/components/series-navigation.html +0 -124
  97. data/_includes/components/social-proof.html +0 -34
  98. data/_includes/components/user-preferences.html +0 -566
  99. data/_includes/meta/syntax-config.html +0 -19
  100. data/_layouts/archive.html +0 -282
  101. data/_layouts/post-sidebar.html +0 -183
  102. data/_sass/_phase3-enhancements.scss +0 -874
  103. data/_sass/_phase4-enhancements.scss +0 -1214
  104. data/_sass/_phase5-enhancements.scss +0 -414
  105. data/assets/js/academic.js +0 -262
  106. data/assets/js/analytics-dashboard.js +0 -382
  107. data/assets/js/core/dark-mode.js +0 -79
  108. data/assets/js/core/github-cards.js +0 -123
  109. data/assets/js/core/language-filter.js +0 -69
  110. data/assets/js/core/navigation.js +0 -184
  111. data/assets/js/core/scroll-progress.js +0 -45
  112. data/assets/js/core/search-hotkeys.js +0 -62
  113. data/assets/js/core/skip-links.js +0 -62
  114. data/assets/js/dist/manifest.json +0 -22
  115. data/assets/js/dist/meta.json +0 -371
  116. data/assets/js/main.js +0 -23
  117. data/assets/js/math.js +0 -818
  118. data/assets/js/notebook.js +0 -158
  119. data/assets/js/search/analytics.js +0 -91
  120. data/assets/js/search/app.js +0 -271
  121. data/assets/js/search/autocomplete.js +0 -120
  122. data/assets/js/search/engine.js +0 -260
  123. data/assets/js/search/filters.js +0 -45
  124. data/assets/js/search/render.js +0 -217
  125. data/assets/js/search/utils.js +0 -99
  126. data/assets/js/search.js +0 -354
  127. data/assets/js/visualizations.js +0 -816
  128. data/assets/publications/datalog-publications.bib +0 -8
  129. data/assets/publications/datalog-publications.ris +0 -9
  130. data/assets/publications/publications.bib +0 -30
  131. data/assets/templates/diogo-ribeiro-cv.md +0 -31
  132. data/assets/templates/diogo-ribeiro-cv.tex +0 -32
  133. data/lib/datalog/theme/theme.rb +0 -18
@@ -1,282 +0,0 @@
1
- ---
2
- layout: default
3
- ---
4
-
5
- {%- comment -%}
6
- Archive Layout
7
- Displays posts organized by year and month with filtering options
8
- {%- endcomment -%}
9
-
10
- <div class="archive-layout">
11
- <header class="archive-layout__header">
12
- <h1 class="archive-layout__title">{{ page.title | default: "Archive" }}</h1>
13
- {% if page.description %}
14
- <p class="archive-layout__description">{{ page.description }}</p>
15
- {% endif %}
16
- </header>
17
-
18
- {%- comment -%} Filter options {%- endcomment -%}
19
- <div class="archive-layout__filters" data-archive-filters>
20
- <div class="archive-filter">
21
- <label for="filter-year" class="archive-filter__label">Year:</label>
22
- <select id="filter-year" class="archive-filter__select" data-filter="year">
23
- <option value="all">All Years</option>
24
- {%- assign years = "" | split: "" -%}
25
- {%- for post in site.posts -%}
26
- {%- assign year = post.date | date: "%Y" -%}
27
- {%- unless years contains year -%}
28
- {%- assign years = years | push: year -%}
29
- {%- endunless -%}
30
- {%- endfor -%}
31
- {%- assign sorted_years = years | sort | reverse -%}
32
- {%- for year in sorted_years -%}
33
- <option value="{{ year }}">{{ year }}</option>
34
- {%- endfor -%}
35
- </select>
36
- </div>
37
-
38
- <div class="archive-filter">
39
- <label for="filter-category" class="archive-filter__label">Category:</label>
40
- <select id="filter-category" class="archive-filter__select" data-filter="category">
41
- <option value="all">All Categories</option>
42
- {%- assign all_categories = "" | split: "" -%}
43
- {%- for post in site.posts -%}
44
- {%- if post.categories -%}
45
- {%- assign all_categories = all_categories | concat: post.categories -%}
46
- {%- endif -%}
47
- {%- endfor -%}
48
- {%- assign unique_categories = all_categories | uniq | sort -%}
49
- {%- for category in unique_categories -%}
50
- <option value="{{ category | slugify }}">{{ category }}</option>
51
- {%- endfor -%}
52
- </select>
53
- </div>
54
-
55
- <div class="archive-filter">
56
- <label for="filter-tag" class="archive-filter__label">Tag:</label>
57
- <select id="filter-tag" class="archive-filter__select" data-filter="tag">
58
- <option value="all">All Tags</option>
59
- {%- assign all_tags = "" | split: "" -%}
60
- {%- for post in site.posts -%}
61
- {%- if post.tags -%}
62
- {%- assign all_tags = all_tags | concat: post.tags -%}
63
- {%- endif -%}
64
- {%- endfor -%}
65
- {%- assign unique_tags = all_tags | uniq | sort -%}
66
- {%- for tag in unique_tags limit: 50 -%}
67
- <option value="{{ tag | slugify }}">{{ tag }}</option>
68
- {%- endfor -%}
69
- </select>
70
- </div>
71
-
72
- <button type="button" class="archive-filter__reset" data-reset-filters>
73
- Reset Filters
74
- </button>
75
- </div>
76
-
77
- {%- comment -%} Statistics {%- endcomment -%}
78
- <div class="archive-layout__stats">
79
- <div class="archive-stat">
80
- <span class="archive-stat__number" data-total-posts>{{ site.posts.size }}</span>
81
- <span class="archive-stat__label">Total Posts</span>
82
- </div>
83
- <div class="archive-stat">
84
- <span class="archive-stat__number" data-visible-posts>{{ site.posts.size }}</span>
85
- <span class="archive-stat__label">Showing</span>
86
- </div>
87
- <div class="archive-stat">
88
- <span class="archive-stat__number">{{ sorted_years.size }}</span>
89
- <span class="archive-stat__label">Years</span>
90
- </div>
91
- <div class="archive-stat">
92
- <span class="archive-stat__number">{{ unique_categories.size }}</span>
93
- <span class="archive-stat__label">Categories</span>
94
- </div>
95
- </div>
96
-
97
- {%- comment -%} Posts organized by year and month {%- endcomment -%}
98
- <div class="archive-layout__content">
99
- {%- for year in sorted_years -%}
100
- {%- assign year_posts = "" | split: "" -%}
101
- {%- for post in site.posts -%}
102
- {%- assign post_year = post.date | date: '%Y' -%}
103
- {%- if post_year == year -%}{%- assign year_posts = year_posts | push: post -%}{%- endif -%}
104
- {%- endfor -%}
105
-
106
- <section class="archive-year" data-year="{{ year }}">
107
- <h2 class="archive-year__heading">
108
- <span class="archive-year__number">{{ year }}</span>
109
- <span class="archive-year__count">({{ year_posts.size }} posts)</span>
110
- </h2>
111
-
112
- {%- comment -%} Group by month {%- endcomment -%}
113
- {%- assign months = "01,02,03,04,05,06,07,08,09,10,11,12" | split: "," -%}
114
- {%- for month_num in months -%}
115
- {%- assign month_posts = "" | split: "" -%}
116
- {%- for post in year_posts -%}
117
- {%- assign post_month = post.date | date: '%m' -%}
118
- {%- if post_month == month_num -%}{%- assign month_posts = month_posts | push: post -%}{%- endif -%}
119
- {%- endfor -%}
120
- {%- if month_posts.size > 0 -%}
121
- {%- assign month_name = month_num | prepend: year | append: "-01" | date: "%B" -%}
122
-
123
- <div class="archive-month">
124
- <h3 class="archive-month__heading">{{ month_name }}</h3>
125
-
126
- <ul class="archive-posts">
127
- {%- for post in month_posts -%}
128
- <li class="archive-post"
129
- data-post
130
- data-year="{{ year }}"
131
- data-month="{{ month_num }}"
132
- data-categories="{{ post.categories | join: ',' | slugify }}"
133
- data-tags="{{ post.tags | join: ',' | slugify }}"
134
- data-difficulty="{% if post.difficulty %}{{ post.difficulty | slugify }}{% endif %}">
135
-
136
- <article class="archive-post__article">
137
- <time class="archive-post__date" datetime="{{ post.date | date_to_xmlschema }}">
138
- {{ post.date | date: "%b %d" }}
139
- </time>
140
-
141
- <div class="archive-post__content">
142
- <h4 class="archive-post__title">
143
- <a href="{{ post.url | relative_url }}">{{ post.title }}</a>
144
- </h4>
145
-
146
- {% if post.excerpt %}
147
- <p class="archive-post__excerpt">{{ post.excerpt | strip_html | truncate: 150 }}</p>
148
- {% endif %}
149
-
150
- <div class="archive-post__meta">
151
- {% if post.difficulty %}
152
- {% include components/difficulty-badge.html level=post.difficulty %}
153
- {% endif %}
154
-
155
- {% if post.categories %}
156
- <span class="archive-post__categories">
157
- {% for category in post.categories limit: 2 %}
158
- <span class="archive-post__category">{{ category }}</span>
159
- {% endfor %}
160
- </span>
161
- {% endif %}
162
-
163
- {% if post.tags %}
164
- <span class="archive-post__tags">
165
- {% for tag in post.tags limit: 3 %}
166
- <span class="archive-post__tag">{{ tag }}</span>
167
- {% endfor %}
168
- </span>
169
- {% endif %}
170
- </div>
171
- </div>
172
- </article>
173
- </li>
174
- {%- endfor -%}
175
- </ul>
176
- </div>
177
- {%- endif -%}
178
- {%- endfor -%}
179
- </section>
180
- {%- endfor -%}
181
- </div>
182
-
183
- {%- comment -%} No results message {%- endcomment -%}
184
- <div class="archive-layout__empty" data-empty-state style="display: none;">
185
- <p>No posts found matching the selected filters.</p>
186
- <button type="button" class="archive-filter__reset" data-reset-filters>
187
- Reset Filters
188
- </button>
189
- </div>
190
- </div>
191
-
192
- <script>
193
- (function() {
194
- 'use strict';
195
-
196
- document.addEventListener('DOMContentLoaded', function() {
197
- const filters = document.querySelector('[data-archive-filters]');
198
- if (!filters) return;
199
-
200
- const yearFilter = filters.querySelector('[data-filter="year"]');
201
- const categoryFilter = filters.querySelector('[data-filter="category"]');
202
- const tagFilter = filters.querySelector('[data-filter="tag"]');
203
- const resetButtons = document.querySelectorAll('[data-reset-filters]');
204
- const posts = document.querySelectorAll('[data-post]');
205
- const visibleCount = document.querySelector('[data-visible-posts]');
206
- const emptyState = document.querySelector('[data-empty-state]');
207
- const yearSections = document.querySelectorAll('.archive-year');
208
-
209
- function applyFilters() {
210
- const selectedYear = yearFilter.value;
211
- const selectedCategory = categoryFilter.value;
212
- const selectedTag = tagFilter.value;
213
-
214
- let visible = 0;
215
- const visibleYears = new Set();
216
-
217
- posts.forEach(post => {
218
- let isVisible = true;
219
-
220
- // Year filter
221
- if (selectedYear !== 'all' && post.dataset.year !== selectedYear) {
222
- isVisible = false;
223
- }
224
-
225
- // Category filter
226
- if (selectedCategory !== 'all') {
227
- const categories = post.dataset.categories.split(',');
228
- if (!categories.includes(selectedCategory)) {
229
- isVisible = false;
230
- }
231
- }
232
-
233
- // Tag filter
234
- if (selectedTag !== 'all') {
235
- const tags = post.dataset.tags.split(',');
236
- if (!tags.includes(selectedTag)) {
237
- isVisible = false;
238
- }
239
- }
240
-
241
- post.style.display = isVisible ? '' : 'none';
242
- if (isVisible) {
243
- visible++;
244
- visibleYears.add(post.dataset.year);
245
- }
246
- });
247
-
248
- // Update count
249
- if (visibleCount) {
250
- visibleCount.textContent = visible;
251
- }
252
-
253
- // Show/hide year sections
254
- yearSections.forEach(section => {
255
- const year = section.dataset.year;
256
- section.style.display = visibleYears.has(year) ? '' : 'none';
257
- });
258
-
259
- // Show/hide empty state
260
- if (emptyState) {
261
- emptyState.style.display = visible === 0 ? 'block' : 'none';
262
- }
263
- }
264
-
265
- function resetFilters() {
266
- yearFilter.value = 'all';
267
- categoryFilter.value = 'all';
268
- tagFilter.value = 'all';
269
- applyFilters();
270
- }
271
-
272
- // Event listeners
273
- yearFilter.addEventListener('change', applyFilters);
274
- categoryFilter.addEventListener('change', applyFilters);
275
- tagFilter.addEventListener('change', applyFilters);
276
-
277
- resetButtons.forEach(button => {
278
- button.addEventListener('click', resetFilters);
279
- });
280
- });
281
- })();
282
- </script>
@@ -1,183 +0,0 @@
1
- ---
2
- layout: default
3
- schema_type: TechnicalArticle
4
- ---
5
-
6
- {%- comment -%}
7
- Sidebar layout variant for posts
8
- This layout provides an alternative post presentation with a sidebar containing:
9
- - Table of contents
10
- - Related posts
11
- - Author info
12
- - Quick actions
13
- {%- endcomment -%}
14
-
15
- {% assign localization_config = site.theme_options.localization %}
16
- {% assign date_format = page.date_format | default: localization_config.date_format | default: 'long' %}
17
- {% assign reading_minutes = page.reading_minutes | default: page.content | strip_html | reading_time %}
18
- {% if reading_minutes == 1 %}
19
- {% capture reading_label %}{% t 'post.reading_time.one' %}{% endcapture %}
20
- {% else %}
21
- {% capture reading_label %}{% t 'post.reading_time.many' minutes: reading_minutes %}{% endcapture %}
22
- {% endif %}
23
- {% assign reading_label = reading_label | strip %}
24
-
25
- {% capture difficulty_default %}{% t 'post.difficulty_default' %}{% endcapture %}
26
- {% assign difficulty = page.difficulty | default: site.post_defaults.difficulty | default: difficulty_default | strip %}
27
-
28
- {% capture toc_default_label %}{% t 'post.toc_heading' %}{% endcapture %}
29
- {% assign toc_heading = page.toc_label | default: toc_default_label | strip %}
30
- {% assign toc_min = page.toc_h_min | default: 2 %}
31
- {% assign toc_max = page.toc_h_max | default: 4 %}
32
-
33
- {% assign canonical_url = page.url | absolute_url %}
34
- {% assign author_name = page.author | default: site.author.name %}
35
- {% assign author_affiliation = page.author_affiliation | default: site.author.affiliation %}
36
-
37
- {% assign post_tags = page.tags %}
38
- {% assign has_tags = false %}
39
- {% if post_tags and post_tags.size > 0 %}{% assign has_tags = true %}{% endif %}
40
- {% assign has_categories = false %}
41
- {% if page.categories and page.categories.size > 0 %}{% assign has_categories = true %}{% endif %}
42
-
43
- {% assign time_required = 'PT' | append: reading_minutes | append: 'M' %}
44
-
45
- {%- comment -%} Breadcrumb navigation {%- endcomment -%}
46
- {% include components/breadcrumbs.html %}
47
-
48
- <div class="post-sidebar-layout">
49
- {%- comment -%} Main Content Area {%- endcomment -%}
50
- <main class="post-sidebar-layout__main" itemscope itemtype="https://schema.org/TechnicalArticle">
51
- <meta itemprop="url" content="{{ canonical_url }}" />
52
- <meta itemprop="datePublished" content="{{ page.date | date_to_xmlschema }}" />
53
- {% if page.last_modified_at or page.updated %}
54
- <meta itemprop="dateModified" content="{{ page.last_modified_at | default: page.updated | date_to_xmlschema }}" />
55
- {% endif %}
56
- <meta itemprop="author" content="{{ author_name }}" />
57
- <meta itemprop="publisher" content="{{ site.author.affiliation | default: site.title }}" />
58
- <meta itemprop="timeRequired" content="{{ time_required }}" />
59
- {% if difficulty %}<meta itemprop="learningResourceType" content="{{ difficulty }}" />{% endif %}
60
- {% if has_tags %}<meta itemprop="keywords" content="{{ post_tags | join: ', ' }}" />{% endif %}
61
-
62
- <article class="post-sidebar-layout__article">
63
- <header class="post-sidebar-layout__header">
64
- <h1 class="post-sidebar-layout__title">{{ page.title }}</h1>
65
-
66
- <div class="post-sidebar-layout__meta">
67
- <time datetime="{{ page.date | date_to_xmlschema }}" itemprop="datePublished">
68
- {{ page.date | localize_date: date_format }}
69
- </time>
70
- <span class="post-sidebar-layout__separator">•</span>
71
- <span>{{ reading_label }}</span>
72
- {% if difficulty %}
73
- <span class="post-sidebar-layout__separator">•</span>
74
- {% include components/difficulty-badge.html level=difficulty %}
75
- {% endif %}
76
- </div>
77
-
78
- {% if page.excerpt %}
79
- <p class="post-sidebar-layout__excerpt" itemprop="description">{{ page.excerpt }}</p>
80
- {% endif %}
81
-
82
- {% if has_tags or has_categories %}
83
- <div class="post-sidebar-layout__taxonomy">
84
- {% if has_tags %}
85
- {% for tag in post_tags %}
86
- {% assign tag_slug = tag | slugify %}
87
- <a class="post-sidebar-layout__tag" href="{{ site.tag_archive.path | default: '/tags/' | append: '#' | append: tag_slug | relative_url }}">{{ tag }}</a>
88
- {% endfor %}
89
- {% endif %}
90
- </div>
91
- {% endif %}
92
-
93
- {%- comment -%} Social sharing {%- endcomment -%}
94
- {% include components/social-share.html url=canonical_url title=page.title description=page.excerpt %}
95
- </header>
96
-
97
- <div class="post-sidebar-layout__content" itemprop="articleBody">
98
- {{ content }}
99
- </div>
100
-
101
- <footer class="post-sidebar-layout__footer">
102
- {%- comment -%} Author bio {%- endcomment -%}
103
- {% include components/author-bio.html author=author_name compact=true %}
104
-
105
- {%- comment -%} Series navigation if applicable {%- endcomment -%}
106
- {% if page.series %}
107
- {% include components/series-navigation.html series=page.series %}
108
- {% endif %}
109
- </footer>
110
- </article>
111
- </main>
112
-
113
- {%- comment -%} Sidebar {%- endcomment -%}
114
- <aside class="post-sidebar-layout__sidebar" aria-label="Sidebar content">
115
- {%- comment -%} Sticky sidebar container {%- endcomment -%}
116
- <div class="post-sidebar-layout__sidebar-sticky">
117
-
118
- {%- comment -%} Table of Contents {%- endcomment -%}
119
- {% if page.toc != false %}
120
- {% include components/enhanced-toc.html html=content h_min=toc_min h_max=toc_max heading=toc_heading %}
121
- {% endif %}
122
-
123
- {%- comment -%} Quick Info Card {%- endcomment -%}
124
- <div class="sidebar-card sidebar-card--info">
125
- <h3 class="sidebar-card__heading">Article Info</h3>
126
- <dl class="sidebar-card__list">
127
- <div class="sidebar-card__item">
128
- <dt>Published</dt>
129
- <dd>{{ page.date | date: "%B %d, %Y" }}</dd>
130
- </div>
131
- {% if page.last_modified_at %}
132
- <div class="sidebar-card__item">
133
- <dt>Updated</dt>
134
- <dd>{{ page.last_modified_at | date: "%B %d, %Y" }}</dd>
135
- </div>
136
- {% endif %}
137
- <div class="sidebar-card__item">
138
- <dt>Reading Time</dt>
139
- <dd>{{ reading_minutes }} min</dd>
140
- </div>
141
- {% if page.word_count %}
142
- <div class="sidebar-card__item">
143
- <dt>Word Count</dt>
144
- <dd>{{ page.word_count | number_with_delimiter }}</dd>
145
- </div>
146
- {% endif %}
147
- </dl>
148
- </div>
149
-
150
- {%- comment -%} Newsletter signup {%- endcomment -%}
151
- {% if site.phase2_features.newsletter.enabled %}
152
- {% include components/newsletter-signup.html compact=true %}
153
- {% endif %}
154
-
155
- {%- comment -%} Related posts (compact) {%- endcomment -%}
156
- <div class="sidebar-card sidebar-card--related">
157
- <h3 class="sidebar-card__heading">Related Articles</h3>
158
- {% include post/related-posts.html page=page limit=3 compact=true %}
159
- </div>
160
- </div>
161
- </aside>
162
- </div>
163
-
164
- {%- comment -%} Post navigation at bottom {%- endcomment -%}
165
- <nav class="post-navigation" aria-label="Post navigation">
166
- {% if page.previous %}
167
- <div class="post-navigation__prev">
168
- <span class="post-navigation__label">← Previous</span>
169
- <a href="{{ page.previous.url | relative_url }}" class="post-navigation__link">
170
- {{ page.previous.title }}
171
- </a>
172
- </div>
173
- {% endif %}
174
-
175
- {% if page.next %}
176
- <div class="post-navigation__next">
177
- <span class="post-navigation__label">Next →</span>
178
- <a href="{{ page.next.url | relative_url }}" class="post-navigation__link">
179
- {{ page.next.title }}
180
- </a>
181
- </div>
182
- {% endif %}
183
- </nav>