@lullabot/eleventy-decision-records 1.0.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 (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +65 -0
  3. package/package.json +94 -0
  4. package/src/YYYYMMDD-decision-template.md +41 -0
  5. package/src/about.md +36 -0
  6. package/src/assets/fonts/OFL.txt +93 -0
  7. package/src/assets/fonts/gabarito-v9-latin-500.woff2 +0 -0
  8. package/src/assets/fonts/gabarito-v9-latin-700.woff2 +0 -0
  9. package/src/assets/fonts/gabarito-v9-latin-regular.woff2 +0 -0
  10. package/src/assets/icons/facebook.svg +1 -0
  11. package/src/assets/icons/github.svg +1 -0
  12. package/src/assets/icons/linkedin.svg +1 -0
  13. package/src/assets/icons/mastodon.svg +1 -0
  14. package/src/assets/icons/x.svg +1 -0
  15. package/src/assets/icons/youtube.svg +1 -0
  16. package/src/assets/images/horizontal.jpg +0 -0
  17. package/src/assets/images/vertical.jpg +0 -0
  18. package/src/assets/js/scrollable.js +49 -0
  19. package/src/assets/js/search.js +189 -0
  20. package/src/assets/js/time-since.js +31 -0
  21. package/src/assets/styles/content.css +149 -0
  22. package/src/assets/styles/fonts.css +33 -0
  23. package/src/assets/styles/footer.css +65 -0
  24. package/src/assets/styles/layout.css +483 -0
  25. package/src/assets/styles/pages.css +348 -0
  26. package/src/assets/styles/recent-decisions.css +104 -0
  27. package/src/assets/styles/reset.css +107 -0
  28. package/src/assets/styles/search-dialog.css +196 -0
  29. package/src/assets/styles/tags.css +16 -0
  30. package/src/assets/styles/tokens.css +181 -0
  31. package/src/assets/styles/typography.css +182 -0
  32. package/src/assets/styles/view-transitions.css +67 -0
  33. package/src/config.js +38 -0
  34. package/src/defaultConfig.json +99 -0
  35. package/src/index.js +227 -0
  36. package/src/index.md +28 -0
  37. package/src/lib/collections/adrs.js +10 -0
  38. package/src/lib/collections/contributors.js +15 -0
  39. package/src/lib/collections/index.js +14 -0
  40. package/src/lib/collections/topics.js +18 -0
  41. package/src/lib/data/index.js +19 -0
  42. package/src/lib/filters/collections.js +63 -0
  43. package/src/lib/filters/dates.js +68 -0
  44. package/src/lib/filters/index.js +26 -0
  45. package/src/lib/filters/strings.js +23 -0
  46. package/src/lib/plugins/bundle.js +23 -0
  47. package/src/lib/plugins/index.js +16 -0
  48. package/src/lib/plugins/markdown.js +10 -0
  49. package/src/lib/plugins/rss.js +24 -0
  50. package/src/lib/plugins/syntax-highlight.js +8 -0
  51. package/src/lib/plugins/toc.js +11 -0
  52. package/src/lib/shortcodes/icons.js +91 -0
  53. package/src/lib/shortcodes/index.js +11 -0
  54. package/src/lib/shortcodes/search.js +32 -0
  55. package/src/templates/assets/favicon.njk +7 -0
  56. package/src/templates/assets/search_index.njk +13 -0
  57. package/src/templates/layouts/adr.njk +59 -0
  58. package/src/templates/layouts/page.njk +136 -0
  59. package/src/templates/pages/contributor.njk +51 -0
  60. package/src/templates/pages/contributors.njk +46 -0
  61. package/src/templates/pages/decisions.njk +41 -0
  62. package/src/templates/pages/practice-areas.njk +48 -0
  63. package/src/templates/pages/topics.njk +50 -0
  64. package/src/templates/partials/footer.njk +12 -0
  65. package/src/templates/partials/recent-decisions.njk +33 -0
  66. package/src/templates/partials/site-nav.njk +61 -0
@@ -0,0 +1,196 @@
1
+ /* ==========================================================================
2
+ Search Dialog
3
+ ========================================================================== */
4
+
5
+ @scope (#search-dialog) {
6
+ :scope {
7
+ width: min(800px, 90vw);
8
+ margin-top: 10vh;
9
+ margin-bottom: auto;
10
+ padding: 0;
11
+ border: 1px solid var(--color-border-default);
12
+ border-radius: var(--radius-lg);
13
+ background-color: var(--color-bg-primary);
14
+ box-shadow: var(--shadow-panel);
15
+ font-family: var(--font-family-base);
16
+ color: var(--color-text-primary);
17
+ interpolate-size: allow-keywords;
18
+ transition: height 0.3s ease;
19
+ }
20
+
21
+ :scope::backdrop {
22
+ background-color: rgba(1, 7, 11, 0.6);
23
+ }
24
+
25
+ header {
26
+ display: flex;
27
+ align-items: center;
28
+ justify-content: space-between;
29
+ padding: var(--space-3) var(--space-4);
30
+ border-bottom: 1px solid var(--color-border-default);
31
+ }
32
+
33
+ h2 {
34
+ font-size: var(--font-size-base);
35
+ font-weight: var(--font-weight-bold);
36
+ line-height: var(--line-height-sm);
37
+ letter-spacing: var(--letter-spacing-wide);
38
+ text-transform: uppercase;
39
+ color: var(--color-text-muted);
40
+ }
41
+
42
+ form button {
43
+ display: flex;
44
+ align-items: center;
45
+ justify-content: center;
46
+ width: 32px;
47
+ height: 32px;
48
+ border-radius: var(--radius-md);
49
+ color: var(--color-text-muted);
50
+ transition:
51
+ background-color 0.15s ease,
52
+ color 0.15s ease;
53
+ }
54
+
55
+ form button:hover,
56
+ form button:focus-visible {
57
+ background-color: var(--color-bg-secondary);
58
+ color: var(--color-text-primary);
59
+ }
60
+
61
+ form button svg {
62
+ width: 20px;
63
+ height: 20px;
64
+ }
65
+
66
+ input[type='search'] {
67
+ display: block;
68
+ width: 100%;
69
+ padding: var(--space-6) var(--space-8);
70
+ border: none;
71
+ background: transparent;
72
+ font-family: var(--font-family-base);
73
+ font-size: var(--font-size-2xl);
74
+ font-weight: var(--font-weight-regular);
75
+ line-height: var(--line-height-md);
76
+ color: var(--color-text-primary);
77
+ outline: none;
78
+ }
79
+
80
+ input[type='search']::placeholder {
81
+ color: var(--color-text-muted);
82
+ }
83
+
84
+ .results-summary {
85
+ padding: 0 var(--space-8) var(--space-3);
86
+ font-size: var(--font-size-base);
87
+ line-height: var(--line-height-sm);
88
+ color: var(--color-text-muted);
89
+ }
90
+
91
+ .results-summary:empty {
92
+ display: none;
93
+ }
94
+
95
+ /* Results list */
96
+ ol {
97
+ max-height: 50vh;
98
+ overflow-y: auto;
99
+ border-top: 1px solid var(--color-border-default);
100
+ }
101
+
102
+ ol:empty {
103
+ max-height: 0;
104
+ border-top: none;
105
+ }
106
+
107
+ li {
108
+ padding: var(--space-4) var(--space-8);
109
+ margin: 0;
110
+ border-bottom: 1px solid var(--color-border-default);
111
+ animation: fade-in 0.25s ease both;
112
+ transition: background-color 0.15s ease;
113
+ }
114
+
115
+ li:hover {
116
+ background-color: var(--color-bg-secondary);
117
+ }
118
+
119
+ li:has(a:focus-visible) {
120
+ background-color: var(--color-bg-secondary);
121
+ outline: 2px solid var(--color-link);
122
+ outline-offset: -2px;
123
+ }
124
+
125
+ @keyframes fade-in {
126
+ from {
127
+ opacity: 0;
128
+ translate: 0 4px;
129
+ }
130
+ }
131
+
132
+ li h3 {
133
+ margin-block: 0;
134
+ font-size: inherit;
135
+ line-height: inherit;
136
+ letter-spacing: inherit;
137
+ }
138
+
139
+ li a {
140
+ font-weight: var(--font-weight-bold);
141
+ font-size: var(--font-size-lg);
142
+ line-height: var(--line-height-base);
143
+ color: var(--color-link);
144
+ text-decoration: none;
145
+ }
146
+
147
+ li a:hover {
148
+ text-decoration: underline;
149
+ }
150
+
151
+ li a:focus-visible {
152
+ text-decoration: underline;
153
+ outline: none;
154
+ }
155
+
156
+ .snippet {
157
+ font-size: var(--font-size-base);
158
+ line-height: var(--line-height-base);
159
+ color: var(--color-text-secondary);
160
+ margin-top: var(--space-1);
161
+ }
162
+
163
+ mark {
164
+ background-color: var(--gold-200);
165
+ color: inherit;
166
+ border-radius: var(--radius-sm);
167
+ padding-inline: 2px;
168
+ }
169
+
170
+ article > footer {
171
+ display: flex;
172
+ flex-wrap: wrap;
173
+ align-items: center;
174
+ gap: var(--space-1) var(--space-3);
175
+ margin-top: var(--space-2);
176
+ font-size: var(--font-size-base);
177
+ line-height: var(--line-height-sm);
178
+ color: var(--color-text-tertiary);
179
+ }
180
+
181
+ .status {
182
+ text-transform: capitalize;
183
+ }
184
+
185
+ .tags span {
186
+ padding: var(--space-1) var(--space-2);
187
+ background-color: var(--color-bg-secondary);
188
+ border-radius: var(--radius-md);
189
+ font-size: var(--font-size-sm);
190
+ }
191
+
192
+ .age::before {
193
+ content: '\00b7';
194
+ margin-right: var(--space-3);
195
+ }
196
+ }
@@ -0,0 +1,16 @@
1
+ /* Prism also marks up HTML tags in code blocks as .token.tag. */
2
+ .tag:not(.token) {
3
+ display: inline-flex;
4
+ align-items: center;
5
+ padding: var(--space-1) var(--space-2);
6
+ background-color: var(--color-bg-secondary);
7
+ border-left: 1px solid var(--color-border-default);
8
+ border-radius: 0 var(--radius-md) var(--radius-md) 0;
9
+ box-shadow: var(--shadow-subtle);
10
+ font-weight: var(--font-weight-medium);
11
+ font-size: var(--font-size-base);
12
+ line-height: var(--line-height-sm);
13
+ letter-spacing: var(--letter-spacing-sm);
14
+ color: var(--color-text-tertiary);
15
+ white-space: nowrap;
16
+ }
@@ -0,0 +1,181 @@
1
+ /* ==========================================================================
2
+ Design Tokens
3
+ Extracted from Figma: Architecture.Lullabot.com
4
+ ========================================================================== */
5
+
6
+ :root {
7
+ /* ---------------------------------------------------------------------------
8
+ Colors
9
+ --------------------------------------------------------------------------- */
10
+
11
+ /* Red */
12
+ --red-1000: #a51400;
13
+ --red-900: #cf1900;
14
+ --red-800: #f81e00;
15
+ --red-700: #f9442b;
16
+ --red-600: #fa6955;
17
+ --red-500: #fb8e80;
18
+ --red-400: #fdb4aa;
19
+ --red-300: #fed2cc;
20
+ --red-200: #fee0dc;
21
+ --red-100: #fee9e6;
22
+
23
+ /* Gray (Figma "Black" scale) */
24
+ --gray-1000: #01070b;
25
+ --gray-900: #171d21;
26
+ --gray-800: #272f35;
27
+ --gray-700: #323c43;
28
+ --gray-600: #434e56;
29
+ --gray-500: #5d686f;
30
+ --gray-400: #75818a;
31
+ --gray-300: #909ba2;
32
+ --gray-200: #b1b9be;
33
+ --gray-100: #d6d9dc;
34
+ --gray-50: #f4f5f6;
35
+ --gray-0: #fff;
36
+
37
+ /* Sky */
38
+ --sky-999: #046595;
39
+ --sky-900: #0974aa;
40
+ --sky-800: #1d8fc9;
41
+ --sky-700: #38a5dc;
42
+ --sky-600: #4eb6eb;
43
+ --sky-500: #6bc3ef;
44
+ --sky-400: #86d0f5;
45
+ --sky-300: #a2dcf9;
46
+ --sky-200: #bfe8fd;
47
+ --sky-100: #d8f2ff;
48
+
49
+ /* Ocean */
50
+ --ocean-1000: #12212b;
51
+ --ocean-950: #1b303f;
52
+ --ocean-900: #20394b;
53
+ --ocean-800: #445a6a;
54
+ --ocean-700: #5e798d;
55
+ --ocean-600: #869eae;
56
+ --ocean-500: #aebec9;
57
+ --ocean-400: #c7d3db;
58
+ --ocean-300: #d7dfe5;
59
+ --ocean-200: #e0e6eb;
60
+ --ocean-100: #edf0f2;
61
+ --ocean-50: #f9fafb;
62
+
63
+ /* Gold */
64
+ --gold-800: #fac12e;
65
+ --gold-700: #ffcc47;
66
+ --gold-600: #ffd25d;
67
+ --gold-500: #ffdc80;
68
+ --gold-400: #ffe399;
69
+ --gold-300: #ffebb8;
70
+ --gold-200: #fff1cc;
71
+ --gold-100: #fff6df;
72
+
73
+ /* ---------------------------------------------------------------------------
74
+ Semantic Color Aliases
75
+ --------------------------------------------------------------------------- */
76
+ --color-brand-primary: var(--red-800);
77
+ --color-brand-primary-dark: var(--red-900);
78
+ --color-text-primary: var(--gray-1000);
79
+ --color-text-secondary: var(--gray-700);
80
+ --color-text-tertiary: var(--gray-600);
81
+ --color-text-muted: var(--gray-500);
82
+ --color-text-inverse: var(--gray-0);
83
+ --color-bg-primary: var(--gray-0);
84
+ --color-bg-secondary: var(--gray-50);
85
+ --color-bg-dark: var(--gray-1000);
86
+ --color-bg-dark-secondary: var(--gray-800);
87
+ --color-border-default: var(--gray-100);
88
+ --color-border-dark: var(--gray-800);
89
+ --color-link: var(--sky-999);
90
+
91
+ /* ---------------------------------------------------------------------------
92
+ Typography — Font Family
93
+ --------------------------------------------------------------------------- */
94
+ --font-family-base: 'Gabarito', verdana, sans-serif;
95
+ --font-family-mono:
96
+ ui-monospace, 'SFMono-Regular', 'Cascadia Code', menlo, consolas, monospace;
97
+
98
+ /* ---------------------------------------------------------------------------
99
+ Typography — Font Weights
100
+ Figma uses CircularXX (Book 450 / Medium 500 / Bold 700).
101
+ Gabarito maps to: Regular 400 / Medium 500 / Bold 700.
102
+ --------------------------------------------------------------------------- */
103
+ --font-weight-regular: 400;
104
+ --font-weight-medium: 500;
105
+ --font-weight-bold: 700;
106
+
107
+ /* ---------------------------------------------------------------------------
108
+ Typography — Font Sizes
109
+ --------------------------------------------------------------------------- */
110
+ --font-size-xs: 0.625rem; /* 10px — count badges */
111
+ --font-size-sm: 0.75rem; /* 12px */
112
+ --font-size-base: 0.875rem; /* 14px — labels, info */
113
+ --font-size-md: 1rem; /* 16px */
114
+ --font-size-lg: 1.125rem; /* 18px — body md, heading 2xs, info md */
115
+ --font-size-xl: 1.25rem; /* 20px — heading xs */
116
+ --font-size-2xl: 1.5rem; /* 24px */
117
+ --font-size-3xl: 2rem; /* 32px */
118
+ --font-size-4xl: 3rem; /* 48px — heading xl */
119
+
120
+ /* ---------------------------------------------------------------------------
121
+ Typography — Line Heights
122
+ --------------------------------------------------------------------------- */
123
+ --line-height-xs: 0.75rem; /* 12px */
124
+ --line-height-sm: 1rem; /* 16px */
125
+ --line-height-base: 1.5rem; /* 24px */
126
+ --line-height-md: 2rem; /* 32px */
127
+ --line-height-lg: 2.5rem; /* 40px */
128
+ --line-height-xl: 3.5rem; /* 56px */
129
+
130
+ /* ---------------------------------------------------------------------------
131
+ Typography — Letter Spacing
132
+ --------------------------------------------------------------------------- */
133
+ --letter-spacing-tight: -0.02em; /* headings xl */
134
+ --letter-spacing-normal: 0;
135
+ --letter-spacing-sm: 0.01em; /* info sm, body */
136
+ --letter-spacing-wide: 0.1em; /* labels, eyebrows */
137
+
138
+ /* ---------------------------------------------------------------------------
139
+ Spacing
140
+ --------------------------------------------------------------------------- */
141
+ --space-1: 0.25rem; /* 4px */
142
+ --space-2: 0.5rem; /* 8px */
143
+ --space-3: 0.75rem; /* 12px */
144
+ --space-4: 1rem; /* 16px */
145
+ --space-5: 1.25rem; /* 20px */
146
+ --space-6: 1.5rem; /* 24px */
147
+ --space-8: 2rem; /* 32px */
148
+ --space-10: 2.5rem; /* 40px */
149
+ --space-12: 3rem; /* 48px */
150
+ --space-16: 4rem; /* 64px */
151
+ --space-18: 4.5rem; /* 72px */
152
+ --space-22: 5.5rem; /* 88px */
153
+
154
+ /* ---------------------------------------------------------------------------
155
+ Border Radius
156
+ --------------------------------------------------------------------------- */
157
+ --radius-sm: 2px;
158
+ --radius-md: 6px;
159
+ --radius-lg: 12px;
160
+
161
+ /* ---------------------------------------------------------------------------
162
+ Border Widths
163
+ --------------------------------------------------------------------------- */
164
+ --border-width-default: 1px;
165
+ --border-width-medium: 1.5px;
166
+ --border-width-thick: 4px;
167
+
168
+ /* ---------------------------------------------------------------------------
169
+ Shadows
170
+ --------------------------------------------------------------------------- */
171
+ --shadow-subtle: 0px 2px 2px 0px rgba(0, 0, 0, 0.02);
172
+ --shadow-panel:
173
+ 0px 0px 48px 0px rgba(0, 0, 0, 0.04), 0px 0px 16px 0px rgba(0, 0, 0, 0.02);
174
+ --shadow-icon: 0px 1px 2px 0px rgba(0, 0, 0, 0.3);
175
+
176
+ /* ---------------------------------------------------------------------------
177
+ Layout
178
+ --------------------------------------------------------------------------- */
179
+ --sidebar-width-collapsed: 56px;
180
+ --decisions-list-width: 400px;
181
+ }
@@ -0,0 +1,182 @@
1
+ /* ==========================================================================
2
+ Typography
3
+ ========================================================================== */
4
+
5
+ :root {
6
+ font-family: var(--font-family-base);
7
+ text-rendering: optimizeLegibility;
8
+ font-size: 16px;
9
+ }
10
+
11
+ /* Headings */
12
+ :where(h1) {
13
+ font-weight: var(--font-weight-bold);
14
+ font-size: var(--font-size-4xl);
15
+ line-height: var(--line-height-xl);
16
+ letter-spacing: var(--letter-spacing-tight);
17
+ }
18
+
19
+ :where(h2) {
20
+ font-weight: var(--font-weight-bold);
21
+ font-size: 2.5rem;
22
+ line-height: 3rem;
23
+ letter-spacing: var(--letter-spacing-tight);
24
+ }
25
+
26
+ :where(h3) {
27
+ font-weight: var(--font-weight-bold);
28
+ font-size: 2rem;
29
+ line-height: 2.5rem;
30
+ letter-spacing: var(--letter-spacing-tight);
31
+ }
32
+
33
+ :where(h4) {
34
+ font-weight: var(--font-weight-bold);
35
+ font-size: 1.5rem;
36
+ line-height: 2rem;
37
+ letter-spacing: var(--letter-spacing-tight);
38
+ }
39
+
40
+ :where(h5) {
41
+ font-weight: var(--font-weight-bold);
42
+ font-size: var(--font-size-xl);
43
+ line-height: var(--line-height-base);
44
+ }
45
+
46
+ :where(h6) {
47
+ font-weight: var(--font-weight-bold);
48
+ font-size: var(--font-size-lg);
49
+ line-height: var(--line-height-base);
50
+ }
51
+
52
+ /* Body text */
53
+ body {
54
+ font-weight: var(--font-weight-regular);
55
+ font-size: var(--font-size-lg);
56
+ line-height: var(--line-height-md);
57
+ }
58
+
59
+ /* Links */
60
+ :where(a) {
61
+ color: var(--color-text-primary);
62
+ text-decoration: underline;
63
+ }
64
+
65
+ :where(a:hover) {
66
+ color: var(--color-brand-primary-dark);
67
+ }
68
+
69
+ /* Block spacing */
70
+ :where(h2, h3, h4, h5, h6) {
71
+ margin-top: var(--space-10);
72
+ margin-bottom: var(--space-4);
73
+ }
74
+
75
+ :where(p) {
76
+ margin-bottom: var(--space-4);
77
+ }
78
+
79
+ :where(.site-main ul, .site-main ol) {
80
+ margin-bottom: var(--space-4);
81
+ padding-left: var(--space-6);
82
+ }
83
+
84
+ :where(li + li) {
85
+ margin-top: var(--space-2);
86
+ }
87
+
88
+ /* Strong / emphasis */
89
+ :where(strong, b) {
90
+ font-weight: var(--font-weight-bold);
91
+ }
92
+
93
+ :where(em, i) {
94
+ font-style: italic;
95
+ }
96
+
97
+ /* Code and keyboard input */
98
+ :where(code, kbd, samp) {
99
+ font-family: var(--font-family-mono);
100
+ font-size: 0.875em;
101
+ }
102
+
103
+ :where(:not(pre) > code) {
104
+ padding: 0.1em 0.35em;
105
+ background-color: var(--color-bg-secondary);
106
+ border: var(--border-width-default) solid var(--color-border-default);
107
+ border-radius: var(--radius-sm);
108
+ overflow-wrap: anywhere;
109
+ }
110
+
111
+ :where(kbd) {
112
+ padding: 0.1em 0.4em;
113
+ background-color: var(--color-bg-primary);
114
+ border: var(--border-width-default) solid var(--gray-200);
115
+ border-bottom-width: 2px;
116
+ border-radius: var(--radius-sm);
117
+ }
118
+
119
+ /* Other inline semantics */
120
+ :where(var, cite, dfn) {
121
+ font-style: italic;
122
+ }
123
+
124
+ :where(mark) {
125
+ padding-inline: 0.15em;
126
+ background-color: var(--gold-300);
127
+ color: inherit;
128
+ }
129
+
130
+ :where(s, del) {
131
+ text-decoration: line-through;
132
+ }
133
+
134
+ :where(u, ins) {
135
+ text-decoration: underline;
136
+ }
137
+
138
+ :where(ins) {
139
+ text-decoration-color: var(--color-link);
140
+ }
141
+
142
+ :where(abbr[title]) {
143
+ text-decoration: underline dotted;
144
+ cursor: help;
145
+ }
146
+
147
+ :where(small) {
148
+ font-size: var(--font-size-base);
149
+ }
150
+
151
+ :where(sub, sup) {
152
+ font-size: 0.75em;
153
+ line-height: 0;
154
+ position: relative;
155
+ }
156
+
157
+ :where(sub) {
158
+ bottom: -0.25em;
159
+ }
160
+
161
+ :where(sup) {
162
+ top: -0.5em;
163
+ }
164
+
165
+ /* Quotes and rules */
166
+ :where(blockquote) {
167
+ margin-block: 0 var(--space-4);
168
+ padding: var(--space-2) var(--space-5);
169
+ border-left: var(--border-width-thick) solid var(--color-brand-primary);
170
+ background-color: var(--color-bg-secondary);
171
+ color: var(--color-text-secondary);
172
+ }
173
+
174
+ :where(blockquote > :last-child) {
175
+ margin-bottom: 0;
176
+ }
177
+
178
+ :where(hr) {
179
+ display: block;
180
+ margin-block: var(--space-10);
181
+ border-top: var(--border-width-default) solid var(--color-border-default);
182
+ }
@@ -0,0 +1,67 @@
1
+ /* ==========================================================================
2
+ Cross-Document View Transitions (MPA)
3
+ ========================================================================== */
4
+
5
+ /* View transition opt-in is via <meta name="view-transition"> in page.njk
6
+ because lightningcss strips the @view-transition at-rule. */
7
+
8
+ /* Persistent elements get named transitions so they morph in place */
9
+ .site-nav {
10
+ view-transition-name: site-nav;
11
+ }
12
+
13
+ .site-main {
14
+ view-transition-name: main-content;
15
+ }
16
+
17
+ .recent-decisions {
18
+ view-transition-name: recent-decisions;
19
+ }
20
+
21
+ /* Main content: true fade-out-then-in (not a crossfade) */
22
+ ::view-transition-group(main-content) {
23
+ animation-duration: 0.3s;
24
+ }
25
+
26
+ ::view-transition-old(main-content) {
27
+ animation: 0.15s ease-out both vt-fade-out;
28
+ }
29
+
30
+ ::view-transition-new(main-content) {
31
+ animation: 0.15s ease-in 0.15s both vt-fade-in;
32
+ }
33
+
34
+ /* Keep nav and sidebar stable (no animation) */
35
+ ::view-transition-old(site-nav),
36
+ ::view-transition-new(site-nav),
37
+ ::view-transition-old(recent-decisions),
38
+ ::view-transition-new(recent-decisions) {
39
+ animation: none;
40
+ mix-blend-mode: normal;
41
+ }
42
+
43
+ @keyframes vt-fade-out {
44
+ from {
45
+ opacity: 1;
46
+ }
47
+ to {
48
+ opacity: 0;
49
+ }
50
+ }
51
+
52
+ @keyframes vt-fade-in {
53
+ from {
54
+ opacity: 0;
55
+ }
56
+ to {
57
+ opacity: 1;
58
+ }
59
+ }
60
+
61
+ /* Respect user motion preferences */
62
+ @media (prefers-reduced-motion: reduce) {
63
+ ::view-transition-old(main-content),
64
+ ::view-transition-new(main-content) {
65
+ animation-duration: 0.01s;
66
+ }
67
+ }
package/src/config.js ADDED
@@ -0,0 +1,38 @@
1
+ import { Merge } from '@11ty/eleventy-utils';
2
+ import defaultConfig from './defaultConfig.json' with { type: 'json' };
3
+
4
+ const RESOLVED = Symbol.for('eleventy-decision-records.config.resolved');
5
+
6
+ /**
7
+ * Rewrites `{decisions}` in navigation URLs to the configured decisions
8
+ * directory, so moving the records with `dirs.decisions` also moves the
9
+ * links pointing at them. Projects writing their own navigation can use
10
+ * the same token or hardcode a path.
11
+ */
12
+ function resolveNavigationTokens(config) {
13
+ for (const group of Object.values(config.navigation ?? {})) {
14
+ for (const item of group) {
15
+ if (typeof item.url === 'string') {
16
+ item.url = item.url.replace('{decisions}', config.dirs.decisions);
17
+ }
18
+ }
19
+ }
20
+ }
21
+
22
+ /**
23
+ * Merges a partial project config over the theme defaults. Merge semantics
24
+ * come from @11ty/eleventy-utils: objects merge deep, arrays concatenate,
25
+ * and an `override:` key prefix replaces instead of merging.
26
+ *
27
+ * Safe to call on an already-resolved config (returns it unchanged), so the
28
+ * plugin can accept either raw options or the result of this function.
29
+ */
30
+ export default function themeConfig(config = {}) {
31
+ if (config[RESOLVED]) {
32
+ return config;
33
+ }
34
+ const resolved = Merge(structuredClone(defaultConfig), config);
35
+ resolveNavigationTokens(resolved);
36
+ Object.defineProperty(resolved, RESOLVED, { value: true });
37
+ return resolved;
38
+ }