@docpensieve/theme 0.1.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.
@@ -0,0 +1,280 @@
1
+ /*
2
+ * Skin of the CustomProvider — DocPensieve's custom theme.
3
+ *
4
+ * The grid, the sticky columns and accessibility live in structure.css,
5
+ * shared by every provider. Here, only the visual decisions: colours,
6
+ * typography, look of the menu and of the content.
7
+ *
8
+ * The article typography lives in prose.css, shared with Tailwind.
9
+ *
10
+ * The light palette lives in the provider's tokens, which the ThemeEngine
11
+ * writes first, in a :root block.
12
+ */
13
+
14
+ /* --- Dark mode ----------------------------------------------------------- */
15
+
16
+ /*
17
+ * Two blocks, on purpose. The first follows the system preference; the second
18
+ * wins when a class is set on <html>, which theme.darkMode allows. The
19
+ * :not(.light) selector lets an explicit "light" choice win over the system
20
+ * preference.
21
+ */
22
+ @media (prefers-color-scheme: dark) {
23
+ :root:not(.light) {
24
+ --dp-bg: #0f1115;
25
+ --dp-bg-soft: #171a21;
26
+ --dp-text: #e8eaed;
27
+ --dp-text-soft: #9aa2ae;
28
+ --dp-border: #272b33;
29
+ --dp-rule: #262a32;
30
+ --dp-accent: #9b97f0;
31
+ --dp-accent-soft: #1e1d33;
32
+ --dp-shadow: rgba(0, 0, 0, 0.45);
33
+ }
34
+ }
35
+
36
+ :root.dark {
37
+ --dp-bg: #0f1115;
38
+ --dp-bg-soft: #171a21;
39
+ --dp-text: #e8eaed;
40
+ --dp-text-soft: #9aa2ae;
41
+ --dp-border: #272b33;
42
+ --dp-rule: #262a32;
43
+ --dp-accent: #9b97f0;
44
+ --dp-accent-soft: #1e1d33;
45
+ --dp-shadow: rgba(0, 0, 0, 0.45);
46
+ }
47
+
48
+ /* --- Base ---------------------------------------------------------------- */
49
+
50
+ body {
51
+ background: var(--dp-bg);
52
+ color: var(--dp-text);
53
+ font-family: var(--dp-font);
54
+ font-size: 16px;
55
+ line-height: 1.7;
56
+ -webkit-font-smoothing: antialiased;
57
+ }
58
+
59
+ a {
60
+ color: var(--dp-accent);
61
+ text-decoration-thickness: 1px;
62
+ text-underline-offset: 2px;
63
+ }
64
+
65
+ :focus-visible {
66
+ outline: 2px solid var(--dp-accent);
67
+ outline-offset: 2px;
68
+ border-radius: 3px;
69
+ }
70
+
71
+ .dp-skip:focus {
72
+ background: var(--dp-bg);
73
+ border: 1px solid var(--dp-border);
74
+ box-shadow: 0 4px 16px var(--dp-shadow);
75
+ }
76
+
77
+ /* --- Header -------------------------------------------------------------- */
78
+
79
+ .dp-header {
80
+ background: color-mix(in srgb, var(--dp-bg) 88%, transparent);
81
+ backdrop-filter: blur(8px);
82
+ border-bottom: 1px solid var(--dp-border);
83
+ }
84
+
85
+ .dp-brand {
86
+ font-weight: 620;
87
+ font-size: 1.02rem;
88
+ letter-spacing: -0.01em;
89
+ color: var(--dp-text);
90
+ text-decoration: none;
91
+ }
92
+
93
+ /* --- Version switcher ---------------------------------------------------- */
94
+
95
+ .dp-versions > summary {
96
+ display: inline-flex;
97
+ align-items: center;
98
+ gap: 0.35rem;
99
+ padding: 0.2rem 0.6rem;
100
+ border: 1px solid var(--dp-border);
101
+ border-radius: 999px;
102
+ font-size: 0.82rem;
103
+ color: var(--dp-text-soft);
104
+ }
105
+ .dp-versions > summary::after {
106
+ content: '';
107
+ width: 0.4rem;
108
+ height: 0.4rem;
109
+ margin-top: -0.2rem;
110
+ border-right: 1.5px solid currentColor;
111
+ border-bottom: 1.5px solid currentColor;
112
+ transform: rotate(45deg);
113
+ }
114
+ .dp-versions[open] > summary::after {
115
+ transform: rotate(-135deg);
116
+ margin-top: 0.15rem;
117
+ }
118
+ .dp-versions > summary:hover {
119
+ color: var(--dp-text);
120
+ border-color: var(--dp-text-soft);
121
+ }
122
+
123
+ .dp-versions-list {
124
+ padding: 0.3rem;
125
+ background: var(--dp-bg);
126
+ border: 1px solid var(--dp-border);
127
+ border-radius: var(--dp-radius);
128
+ box-shadow: 0 8px 24px var(--dp-shadow);
129
+ }
130
+ .dp-versions-list a {
131
+ display: block;
132
+ padding: 0.3rem 0.55rem;
133
+ border-radius: 4px;
134
+ font-size: 0.86rem;
135
+ color: var(--dp-text);
136
+ text-decoration: none;
137
+ }
138
+ .dp-versions-list a:hover {
139
+ background: var(--dp-bg-soft);
140
+ }
141
+ .dp-versions-list a[aria-current] {
142
+ color: var(--dp-accent);
143
+ font-weight: 560;
144
+ }
145
+
146
+ /* --- Side columns -------------------------------------------------------- */
147
+
148
+ .dp-sidebar,
149
+ .dp-toc {
150
+ font-size: 0.885rem;
151
+ }
152
+
153
+ /* --- Tree-shaped side menu ----------------------------------------------- */
154
+
155
+ .dp-nav {
156
+ margin: 0;
157
+ padding: 0;
158
+ list-style: none;
159
+ }
160
+
161
+ /*
162
+ * The vertical rule links children to their parent. It only applies to
163
+ * nested levels: the root of the menu has nothing to link.
164
+ */
165
+ .dp-nav .dp-nav {
166
+ margin: 0.1rem 0 0.35rem 0.35rem;
167
+ padding-left: 0.85rem;
168
+ border-left: 1px solid var(--dp-rule);
169
+ }
170
+
171
+ .dp-nav-item {
172
+ margin: 0;
173
+ }
174
+
175
+ .dp-nav-link,
176
+ .dp-nav-label {
177
+ display: block;
178
+ padding: 0.24rem 0.5rem 0.24rem 0.35rem;
179
+ border-radius: 5px;
180
+ text-decoration: none;
181
+ color: var(--dp-text-soft);
182
+ }
183
+
184
+ .dp-nav-link:hover {
185
+ color: var(--dp-text);
186
+ background: var(--dp-bg-soft);
187
+ }
188
+
189
+ /* A category without an index page is not clickable: it reads as a heading. */
190
+ .dp-nav-label {
191
+ font-weight: 600;
192
+ font-size: 0.78rem;
193
+ letter-spacing: 0.05em;
194
+ text-transform: uppercase;
195
+ padding-top: 0.7rem;
196
+ }
197
+
198
+ /* A clickable category keeps the weight of a heading, without the capitals. */
199
+ .dp-nav-item--parent > .dp-nav-link {
200
+ font-weight: 600;
201
+ color: var(--dp-text);
202
+ margin-top: 0.55rem;
203
+ }
204
+
205
+ .dp-nav-link[aria-current='page'] {
206
+ position: relative;
207
+ color: var(--dp-accent);
208
+ font-weight: 560;
209
+ background: var(--dp-accent-soft);
210
+ }
211
+
212
+ /*
213
+ * The bar of the current page sits exactly on the parent's rule, in place of
214
+ * the grey line: the eye follows a single vertical line.
215
+ */
216
+ .dp-nav .dp-nav .dp-nav-link[aria-current='page']::before {
217
+ content: '';
218
+ position: absolute;
219
+ left: calc(-0.85rem - 1px);
220
+ top: 0;
221
+ bottom: 0;
222
+ width: 2px;
223
+ background: var(--dp-accent);
224
+ border-radius: 2px;
225
+ }
226
+
227
+ /* --- Table of contents --------------------------------------------------- */
228
+
229
+ .dp-toc-title {
230
+ margin: 0 0 0.5rem;
231
+ font-size: 0.74rem;
232
+ font-weight: 600;
233
+ letter-spacing: 0.06em;
234
+ text-transform: uppercase;
235
+ color: var(--dp-text-soft);
236
+ }
237
+
238
+ .dp-toc-list {
239
+ margin: 0;
240
+ padding: 0;
241
+ list-style: none;
242
+ border-left: 1px solid var(--dp-rule);
243
+ }
244
+ .dp-toc-list .dp-toc-list {
245
+ border: 0;
246
+ padding-left: 0.8rem;
247
+ }
248
+
249
+ .dp-toc-item a {
250
+ display: block;
251
+ padding: 0.18rem 0 0.18rem 0.8rem;
252
+ margin-left: -1px;
253
+ border-left: 1px solid transparent;
254
+ color: var(--dp-text-soft);
255
+ text-decoration: none;
256
+ line-height: 1.45;
257
+ }
258
+ .dp-toc-item a:hover {
259
+ color: var(--dp-accent);
260
+ border-left-color: var(--dp-accent);
261
+ }
262
+
263
+ /* --- Footer -------------------------------------------------------------- */
264
+
265
+ .dp-footer {
266
+ padding: 1.5rem;
267
+ border-top: 1px solid var(--dp-border);
268
+ font-size: 0.85rem;
269
+ color: var(--dp-text-soft);
270
+ text-align: center;
271
+ }
272
+ .dp-footer p {
273
+ margin: 0;
274
+ }
275
+
276
+ @media (max-width: 56rem) {
277
+ .dp-sidebar {
278
+ border-bottom: 1px solid var(--dp-border);
279
+ }
280
+ }
@@ -0,0 +1,109 @@
1
+ /*
2
+ * Prose typography, shared by the providers that bring none.
3
+ *
4
+ * CustomProvider uses it for lack of a framework, TailwindProvider because its
5
+ * Preflight resets headings, lists and quotes: without this stylesheet, a
6
+ * Tailwind article would come out entirely bare.
7
+ *
8
+ * Everything is expressed in --dp-* tokens, which every provider defines in
9
+ * its own way.
10
+ */
11
+
12
+ /* --- Article ------------------------------------------------------------- */
13
+
14
+ .dp-article h1 {
15
+ font-size: 2.1rem;
16
+ line-height: 1.2;
17
+ letter-spacing: -0.02em;
18
+ margin: 0 0 0.6rem;
19
+ }
20
+
21
+ .dp-article h2 {
22
+ font-size: 1.4rem;
23
+ letter-spacing: -0.01em;
24
+ margin: 2.75rem 0 0.9rem;
25
+ padding-bottom: 0.35rem;
26
+ border-bottom: 1px solid var(--dp-border);
27
+ }
28
+
29
+ .dp-article h3 {
30
+ font-size: 1.12rem;
31
+ margin: 2rem 0 0.6rem;
32
+ }
33
+
34
+ .dp-article p,
35
+ .dp-article ul,
36
+ .dp-article ol {
37
+ margin: 0 0 1.1rem;
38
+ }
39
+
40
+ .dp-article li + li {
41
+ margin-top: 0.3rem;
42
+ }
43
+
44
+ .dp-article img {
45
+ border-radius: var(--dp-radius);
46
+ }
47
+
48
+ .dp-article blockquote {
49
+ margin: 1.4rem 0;
50
+ padding: 0.1rem 1.1rem;
51
+ border-left: 3px solid var(--dp-accent);
52
+ background: var(--dp-bg-soft);
53
+ border-radius: 0 var(--dp-radius) var(--dp-radius) 0;
54
+ /*
55
+ * Full-strength text, not softened: on the recessed background, the soft
56
+ * grey fell below readable contrast. The border is enough to say it is a
57
+ * quote.
58
+ */
59
+ color: var(--dp-text);
60
+ }
61
+
62
+ .dp-article hr {
63
+ margin: 2.5rem 0;
64
+ border: 0;
65
+ border-top: 1px solid var(--dp-border);
66
+ }
67
+
68
+ .dp-article table {
69
+ border-collapse: collapse;
70
+ margin: 0 0 1.3rem;
71
+ font-size: 0.93rem;
72
+ }
73
+ .dp-article th,
74
+ .dp-article td {
75
+ padding: 0.45rem 0.85rem;
76
+ border: 1px solid var(--dp-border);
77
+ text-align: left;
78
+ }
79
+ .dp-article th {
80
+ background: var(--dp-bg-soft);
81
+ font-weight: 600;
82
+ }
83
+
84
+ /* --- Code ---------------------------------------------------------------- */
85
+
86
+ .dp-article code {
87
+ padding: 0.12em 0.38em;
88
+ background: var(--dp-bg-soft);
89
+ border: 1px solid var(--dp-border);
90
+ border-radius: 4px;
91
+ font-family: var(--dp-font-mono);
92
+ font-size: 0.86em;
93
+ }
94
+
95
+ .dp-article pre {
96
+ margin: 0 0 1.3rem;
97
+ padding: 0.95rem 1.1rem;
98
+ border: 1px solid var(--dp-border);
99
+ border-radius: var(--dp-radius);
100
+ font-size: 0.87rem;
101
+ line-height: 1.6;
102
+ }
103
+
104
+ .dp-article pre code {
105
+ padding: 0;
106
+ background: none;
107
+ border: 0;
108
+ font-size: inherit;
109
+ }
@@ -0,0 +1,235 @@
1
+ /*
2
+ * Skeleton shared by every provider.
3
+ *
4
+ * This file decides no colour and no font: it lays out the grid, the sticky
5
+ * columns and accessibility. Every provider includes it, then adds its skin.
6
+ * Without this sharing, the layout would have to be rewritten — and
7
+ * maintained — in each theme.
8
+ *
9
+ * The measures come from the --dp-*-width variables, which every provider
10
+ * must define.
11
+ */
12
+
13
+ *,
14
+ *::before,
15
+ *::after {
16
+ box-sizing: border-box;
17
+ }
18
+
19
+ html {
20
+ scroll-behavior: smooth;
21
+ /* A clicked anchor must not slide under the sticky header. */
22
+ scroll-padding-top: 4.5rem;
23
+ }
24
+
25
+ body {
26
+ margin: 0;
27
+ }
28
+
29
+ /* The skip link stays off screen until it has the focus. */
30
+ .dp-skip {
31
+ position: absolute;
32
+ left: -100vw;
33
+ }
34
+ .dp-skip:focus {
35
+ position: fixed;
36
+ left: 0.75rem;
37
+ top: 0.75rem;
38
+ z-index: 30;
39
+ padding: 0.55rem 0.9rem;
40
+ border-radius: 6px;
41
+ text-decoration: none;
42
+ }
43
+
44
+ .dp-header {
45
+ position: sticky;
46
+ top: 0;
47
+ z-index: 20;
48
+ display: flex;
49
+ align-items: center;
50
+ gap: 0.85rem;
51
+ height: 3.5rem;
52
+ padding: 0 1.5rem;
53
+ }
54
+
55
+ /* The version switcher is a <details>: it opens without JavaScript. */
56
+ .dp-versions {
57
+ position: relative;
58
+ }
59
+ .dp-versions > summary {
60
+ cursor: pointer;
61
+ list-style: none;
62
+ user-select: none;
63
+ }
64
+ .dp-versions > summary::-webkit-details-marker {
65
+ display: none;
66
+ }
67
+ .dp-versions-list {
68
+ position: absolute;
69
+ top: calc(100% + 0.4rem);
70
+ left: 0;
71
+ min-width: 8rem;
72
+ margin: 0;
73
+ list-style: none;
74
+ }
75
+
76
+ /*
77
+ * A documentation page takes the whole available width, 25 pixels short of
78
+ * each edge. Three columns share the space — menu, content, table of
79
+ * contents — and capping it would shrink the content for no gain.
80
+ */
81
+ .dp-shell {
82
+ display: grid;
83
+ grid-template-columns: var(--dp-sidebar-width) minmax(0, 1fr) var(--dp-toc-width);
84
+ gap: 2.5rem;
85
+ align-items: start;
86
+ max-width: none;
87
+ margin: 0 auto;
88
+ padding: 2rem 25px 5rem;
89
+ }
90
+
91
+ /*
92
+ * Entrance hall: neither menu nor table of contents, and the content is no
93
+ * longer held to reading width. Its width stays bounded, unlike documentation
94
+ * pages: nothing shares the space with it, and a line crossing a whole wide
95
+ * screen would become unreadable.
96
+ */
97
+ .dp-shell--wide {
98
+ grid-template-columns: minmax(0, 1fr);
99
+ max-width: 76rem;
100
+ padding-top: 3rem;
101
+ }
102
+
103
+ /*
104
+ * The entrance hall is not held to reading width, even when a project sets
105
+ * one: nothing shares the space with it.
106
+ */
107
+ .dp-shell--wide .dp-article {
108
+ max-width: none;
109
+ }
110
+
111
+ /*
112
+ * Notice of the versions that are not the current one. It comes before the
113
+ * content rather than floating: someone arriving from a search engine must
114
+ * read it before the text, not after believing it.
115
+ */
116
+ .dp-notice {
117
+ display: block;
118
+ margin: 0 0 1.75rem;
119
+ padding: 0.75rem 1rem;
120
+ border: 1px solid var(--dp-accent);
121
+ border-radius: var(--dp-radius);
122
+ background: var(--dp-accent-soft);
123
+ color: var(--dp-text);
124
+ font-size: 0.92rem;
125
+ line-height: 1.5;
126
+ }
127
+
128
+ .dp-notice a {
129
+ color: inherit;
130
+ font-weight: 600;
131
+ }
132
+
133
+ .dp-sidebar,
134
+ .dp-toc {
135
+ position: sticky;
136
+ top: 4.5rem;
137
+ max-height: calc(100vh - 6rem);
138
+ overflow-y: auto;
139
+ }
140
+
141
+ /* Without min-width, a wide code block would make the whole grid overflow. */
142
+ .dp-main {
143
+ min-width: 0;
144
+ }
145
+
146
+ /*
147
+ * Targets of in-page jumps — skip link, back to top. The focus is moved there
148
+ * without them being controls: an outline around the whole area would tell
149
+ * nothing.
150
+ */
151
+ #top:focus,
152
+ #content:focus {
153
+ outline: none;
154
+ }
155
+
156
+ /*
157
+ * The content fills its column. `--dp-content-width` is `none` by default: a
158
+ * project that prefers a narrow reading column gives it a length, for
159
+ * instance `44rem`.
160
+ */
161
+ .dp-article {
162
+ max-width: var(--dp-content-width, none);
163
+ }
164
+ .dp-article > *:first-child {
165
+ margin-top: 0;
166
+ }
167
+ .dp-article img {
168
+ max-width: 100%;
169
+ height: auto;
170
+ }
171
+
172
+ /*
173
+ * Wide tables and code blocks scroll on their own rather than widen the page.
174
+ * A wide table scrolls inside its wrapper, not the table itself: a
175
+ * `display: block` set on a <table> stripped its table role, and a screen
176
+ * reader no longer announced rows or columns. The wrapper is added by the
177
+ * compiler.
178
+ */
179
+ .dp-table-scroll {
180
+ max-width: 100%;
181
+ overflow-x: auto;
182
+ }
183
+ .dp-article pre {
184
+ overflow-x: auto;
185
+ }
186
+
187
+ /*
188
+ * Shiki writes both themes at once: the light colour in `color`, the dark one
189
+ * in the `--shiki-dark` variable. These two blocks switch between them without
190
+ * a line of JavaScript or an extra stylesheet to ship.
191
+ */
192
+ @media (prefers-color-scheme: dark) {
193
+ :root:not(.light) .shiki,
194
+ :root:not(.light) .shiki span {
195
+ color: var(--shiki-dark) !important;
196
+ background-color: var(--shiki-dark-bg) !important;
197
+ }
198
+ }
199
+ :root.dark .shiki,
200
+ :root.dark .shiki span {
201
+ color: var(--shiki-dark) !important;
202
+ background-color: var(--shiki-dark-bg) !important;
203
+ }
204
+
205
+ @media (max-width: 82rem) {
206
+ .dp-shell {
207
+ grid-template-columns: var(--dp-sidebar-width) minmax(0, 1fr);
208
+ }
209
+ .dp-toc {
210
+ display: none;
211
+ }
212
+ }
213
+
214
+ @media (max-width: 56rem) {
215
+ .dp-shell {
216
+ grid-template-columns: minmax(0, 1fr);
217
+ gap: 1.5rem;
218
+ padding: 1.5rem 25px 4rem;
219
+ }
220
+ /*
221
+ * On a small screen the menu moves above the content and stops being
222
+ * sticky: a fixed column would eat half of the useful surface.
223
+ */
224
+ .dp-sidebar {
225
+ position: static;
226
+ max-height: none;
227
+ padding-bottom: 1.25rem;
228
+ }
229
+ }
230
+
231
+ @media (prefers-reduced-motion: reduce) {
232
+ html {
233
+ scroll-behavior: auto;
234
+ }
235
+ }