@railway/inkwell 1.2.0 → 1.3.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.
- package/package.json +1 -1
- package/src/styles.css +127 -80
package/package.json
CHANGED
package/src/styles.css
CHANGED
|
@@ -4,6 +4,19 @@
|
|
|
4
4
|
* consumer can drop in and either keep or override. Light by default,
|
|
5
5
|
* dark via `prefers-color-scheme: dark`. No saturated brand colors.
|
|
6
6
|
*
|
|
7
|
+
* Specificity strategy:
|
|
8
|
+
* Visual-chrome defaults (color, background, border, padding, typography)
|
|
9
|
+
* are wrapped in `:where()` so they carry 0,0,0 specificity. Any single-class
|
|
10
|
+
* consumer rule — Tailwind utilities, `classNames` slot styling, `components`
|
|
11
|
+
* overrides on the renderer — wins automatically by specificity tie-break.
|
|
12
|
+
* No `!important`, no descendant scoping, no inline-style hacks needed.
|
|
13
|
+
*
|
|
14
|
+
* Layout-critical rules (position, z-index, structural width/height/overflow,
|
|
15
|
+
* picker flip math) deliberately stay at normal specificity. Consumers should
|
|
16
|
+
* not silently break editor or picker geometry by adding a class — when they
|
|
17
|
+
* want to override layout, they can with descendant or `!important` rules
|
|
18
|
+
* applied intentionally.
|
|
19
|
+
*
|
|
7
20
|
* Import with: `import "@railway/inkwell/styles.css";`
|
|
8
21
|
*/
|
|
9
22
|
|
|
@@ -72,14 +85,16 @@
|
|
|
72
85
|
|
|
73
86
|
/* ── Editor surface ──────────────────────────────────────────────── */
|
|
74
87
|
|
|
88
|
+
/* Wrapper position is structural — plugin pickers, bubble menus, and the
|
|
89
|
+
character-count overlay all absolutely position against it. Stays at
|
|
90
|
+
normal specificity. */
|
|
75
91
|
.inkwell-editor-wrapper {
|
|
76
92
|
position: relative;
|
|
77
93
|
}
|
|
78
94
|
|
|
79
|
-
/* Visual-chrome defaults
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
automatically — no `!important` or selector gymnastics needed.
|
|
95
|
+
/* Visual-chrome defaults on the editable surface live inside `:where()`
|
|
96
|
+
so a single-class consumer rule (Tailwind utilities, `classNames.editor`,
|
|
97
|
+
etc.) wins automatically.
|
|
83
98
|
|
|
84
99
|
Container size (min-height, max-height, height) is deliberately NOT
|
|
85
100
|
defaulted here. Inkwell sits inside the consumer's layout and the right
|
|
@@ -88,10 +103,12 @@
|
|
|
88
103
|
container. Set it on the editor via `styles.editor`, `classNames.editor`,
|
|
89
104
|
or your own CSS. */
|
|
90
105
|
:where(.inkwell-editor) {
|
|
106
|
+
outline: none;
|
|
91
107
|
padding: 1rem 1.25rem;
|
|
92
108
|
border: 1px solid var(--inkwell-border);
|
|
93
109
|
border-radius: var(--inkwell-radius);
|
|
94
110
|
background: var(--inkwell-bg);
|
|
111
|
+
color: var(--inkwell-text);
|
|
95
112
|
line-height: 1.6;
|
|
96
113
|
font-size: 0.95rem;
|
|
97
114
|
transition: border-color 0.15s ease;
|
|
@@ -99,27 +116,28 @@
|
|
|
99
116
|
:where(.inkwell-editor:focus-within) {
|
|
100
117
|
border-color: var(--inkwell-border-strong);
|
|
101
118
|
}
|
|
102
|
-
.inkwell-editor {
|
|
103
|
-
outline: none;
|
|
104
|
-
color: var(--inkwell-text);
|
|
105
|
-
}
|
|
106
119
|
|
|
120
|
+
/* `position: relative` on paragraphs is structural — Slate decorations and
|
|
121
|
+
inline children position against it. Margin is theming and goes through
|
|
122
|
+
`:where()` so a consumer paragraph-spacing utility wins. */
|
|
107
123
|
.inkwell-editor p {
|
|
108
|
-
margin: 0;
|
|
109
124
|
position: relative;
|
|
110
125
|
}
|
|
111
|
-
.inkwell-editor
|
|
126
|
+
:where(.inkwell-editor p) {
|
|
127
|
+
margin: 0;
|
|
128
|
+
}
|
|
129
|
+
:where(.inkwell-editor strong) {
|
|
112
130
|
font-weight: 600;
|
|
113
131
|
color: var(--inkwell-text);
|
|
114
132
|
}
|
|
115
|
-
.inkwell-editor em {
|
|
133
|
+
:where(.inkwell-editor em) {
|
|
116
134
|
font-style: italic;
|
|
117
135
|
}
|
|
118
|
-
.inkwell-editor del {
|
|
136
|
+
:where(.inkwell-editor del) {
|
|
119
137
|
text-decoration: line-through;
|
|
120
138
|
color: var(--inkwell-text-muted);
|
|
121
139
|
}
|
|
122
|
-
.inkwell-editor code {
|
|
140
|
+
:where(.inkwell-editor code) {
|
|
123
141
|
background: var(--inkwell-code-bg);
|
|
124
142
|
color: var(--inkwell-code-fg);
|
|
125
143
|
padding: 0.1em 0.35em;
|
|
@@ -128,38 +146,38 @@
|
|
|
128
146
|
font-size: 0.85em;
|
|
129
147
|
}
|
|
130
148
|
|
|
131
|
-
.inkwell-editor-blockquote {
|
|
149
|
+
:where(.inkwell-editor-blockquote) {
|
|
132
150
|
border-left: 3px solid var(--inkwell-border-strong);
|
|
133
151
|
padding-left: 0.85em;
|
|
134
152
|
margin: 0.5em 0;
|
|
135
153
|
color: var(--inkwell-text-muted);
|
|
136
154
|
}
|
|
137
155
|
|
|
138
|
-
.inkwell-editor-heading {
|
|
156
|
+
:where(.inkwell-editor-heading) {
|
|
139
157
|
font-weight: 600;
|
|
140
158
|
line-height: 1.3;
|
|
141
159
|
color: var(--inkwell-text);
|
|
142
160
|
}
|
|
143
|
-
.inkwell-editor-heading-1 {
|
|
161
|
+
:where(.inkwell-editor-heading-1) {
|
|
144
162
|
font-size: 1.75em;
|
|
145
163
|
}
|
|
146
|
-
.inkwell-editor-heading-2 {
|
|
164
|
+
:where(.inkwell-editor-heading-2) {
|
|
147
165
|
font-size: 1.4em;
|
|
148
166
|
}
|
|
149
|
-
.inkwell-editor-heading-3 {
|
|
167
|
+
:where(.inkwell-editor-heading-3) {
|
|
150
168
|
font-size: 1.2em;
|
|
151
169
|
}
|
|
152
|
-
.inkwell-editor-heading-4 {
|
|
170
|
+
:where(.inkwell-editor-heading-4) {
|
|
153
171
|
font-size: 1em;
|
|
154
172
|
}
|
|
155
|
-
.inkwell-editor-heading-5 {
|
|
173
|
+
:where(.inkwell-editor-heading-5) {
|
|
156
174
|
font-size: 0.9em;
|
|
157
175
|
}
|
|
158
|
-
.inkwell-editor-heading-6 {
|
|
176
|
+
:where(.inkwell-editor-heading-6) {
|
|
159
177
|
font-size: 0.8em;
|
|
160
178
|
}
|
|
161
179
|
|
|
162
|
-
.inkwell-editor-image {
|
|
180
|
+
:where(.inkwell-editor-image) {
|
|
163
181
|
margin: 0.75em 0;
|
|
164
182
|
border-radius: var(--inkwell-radius);
|
|
165
183
|
overflow: hidden;
|
|
@@ -168,10 +186,14 @@
|
|
|
168
186
|
border-color 0.15s ease,
|
|
169
187
|
box-shadow 0.15s ease;
|
|
170
188
|
}
|
|
171
|
-
.inkwell-editor-image[data-selected] {
|
|
189
|
+
:where(.inkwell-editor-image[data-selected]) {
|
|
172
190
|
border-color: var(--inkwell-accent);
|
|
173
191
|
box-shadow: 0 0 0 3px var(--inkwell-accent-soft);
|
|
174
192
|
}
|
|
193
|
+
/* Image fitting stays structural — `max-width: 100%` and `height: auto`
|
|
194
|
+
are the only sensible defaults for keeping aspect ratio inside a
|
|
195
|
+
variable-width editor. Consumers who want a different sizing model
|
|
196
|
+
should opt in with a descendant or higher-specificity rule. */
|
|
175
197
|
.inkwell-editor-image img {
|
|
176
198
|
display: block;
|
|
177
199
|
max-width: 100%;
|
|
@@ -185,44 +207,53 @@
|
|
|
185
207
|
limit is a soft hint — typing past it is allowed; the count then
|
|
186
208
|
turns red and the wrapper picks up `.inkwell-editor-over-limit`,
|
|
187
209
|
which paints a soft red halo on the editor surface so it's visually
|
|
188
|
-
obvious the document is over budget.
|
|
210
|
+
obvious the document is over budget.
|
|
211
|
+
|
|
212
|
+
Positioning stays at normal specificity — the overlay only works
|
|
213
|
+
from the top-right corner of the wrapper. Chrome (color, font-weight,
|
|
214
|
+
etc.) lives below in `:where()`. */
|
|
189
215
|
.inkwell-editor-character-count {
|
|
190
216
|
position: absolute;
|
|
191
217
|
top: 0.5rem;
|
|
192
218
|
right: 0.5rem;
|
|
193
219
|
z-index: 10;
|
|
220
|
+
pointer-events: none;
|
|
221
|
+
user-select: none;
|
|
222
|
+
}
|
|
223
|
+
:where(.inkwell-editor-character-count) {
|
|
194
224
|
padding: 0.1rem 0.4rem;
|
|
195
225
|
font-size: 0.72rem;
|
|
196
226
|
font-variant-numeric: tabular-nums;
|
|
197
227
|
color: var(--inkwell-text-dim);
|
|
198
228
|
background: var(--inkwell-bg);
|
|
199
229
|
border-radius: calc(var(--inkwell-radius) - 2px);
|
|
200
|
-
pointer-events: none;
|
|
201
|
-
user-select: none;
|
|
202
230
|
}
|
|
203
|
-
.inkwell-editor-character-count-over {
|
|
231
|
+
:where(.inkwell-editor-character-count-over) {
|
|
204
232
|
color: var(--inkwell-danger);
|
|
205
233
|
font-weight: 500;
|
|
206
234
|
}
|
|
207
|
-
.inkwell-editor-wrapper.inkwell-editor-over-limit .inkwell-editor {
|
|
235
|
+
:where(.inkwell-editor-wrapper.inkwell-editor-over-limit .inkwell-editor) {
|
|
208
236
|
border-color: var(--inkwell-danger-soft);
|
|
209
237
|
box-shadow: 0 0 0 3px var(--inkwell-danger-soft);
|
|
210
238
|
}
|
|
211
239
|
|
|
212
|
-
.inkwell-editor-backtick,
|
|
213
|
-
.inkwell-editor-marker {
|
|
240
|
+
:where(.inkwell-editor-backtick),
|
|
241
|
+
:where(.inkwell-editor-marker) {
|
|
214
242
|
color: var(--inkwell-text-dim);
|
|
215
243
|
}
|
|
216
|
-
.inkwell-editor .inkwell-editor-code-fence {
|
|
244
|
+
:where(.inkwell-editor .inkwell-editor-code-fence) {
|
|
217
245
|
color: var(--inkwell-text-dim);
|
|
218
246
|
}
|
|
219
|
-
.inkwell-editor .inkwell-editor-code-line,
|
|
220
|
-
.inkwell-editor .inkwell-editor-code-fence,
|
|
221
|
-
.inkwell-renderer pre code {
|
|
247
|
+
:where(.inkwell-editor .inkwell-editor-code-line),
|
|
248
|
+
:where(.inkwell-editor .inkwell-editor-code-fence),
|
|
249
|
+
:where(.inkwell-renderer pre code) {
|
|
222
250
|
font-family: var(--inkwell-font-mono);
|
|
223
251
|
font-size: 0.85em;
|
|
224
252
|
line-height: 1.55;
|
|
225
253
|
}
|
|
254
|
+
/* Wrapping behavior for code lines stays structural — Slate emits one
|
|
255
|
+
contenteditable line per node and depends on `white-space: pre-wrap`
|
|
256
|
+
for correct caret placement. */
|
|
226
257
|
.inkwell-editor .inkwell-editor-code-line {
|
|
227
258
|
white-space: pre-wrap;
|
|
228
259
|
word-wrap: break-word;
|
|
@@ -241,11 +272,13 @@
|
|
|
241
272
|
}
|
|
242
273
|
}
|
|
243
274
|
|
|
275
|
+
/* Container positioning is layout-critical — the bubble menu is JS-
|
|
276
|
+
positioned against the selection. Keep at normal specificity. */
|
|
244
277
|
.inkwell-plugin-bubble-menu-container {
|
|
245
278
|
position: absolute;
|
|
246
279
|
z-index: 9999;
|
|
247
280
|
}
|
|
248
|
-
.inkwell-plugin-bubble-menu-inner {
|
|
281
|
+
:where(.inkwell-plugin-bubble-menu-inner) {
|
|
249
282
|
display: flex;
|
|
250
283
|
gap: 2px;
|
|
251
284
|
background: var(--inkwell-bg-elevated);
|
|
@@ -255,7 +288,7 @@
|
|
|
255
288
|
box-shadow: 0 6px 20px hsla(220, 20%, 10%, 0.12);
|
|
256
289
|
animation: inkwell-fade-in 0.12s ease-out;
|
|
257
290
|
}
|
|
258
|
-
.inkwell-plugin-bubble-menu-btn {
|
|
291
|
+
:where(.inkwell-plugin-bubble-menu-btn) {
|
|
259
292
|
display: flex;
|
|
260
293
|
align-items: center;
|
|
261
294
|
justify-content: center;
|
|
@@ -270,35 +303,38 @@
|
|
|
270
303
|
background 0.1s ease,
|
|
271
304
|
color 0.1s ease;
|
|
272
305
|
}
|
|
273
|
-
.inkwell-plugin-bubble-menu-btn:hover {
|
|
306
|
+
:where(.inkwell-plugin-bubble-menu-btn:hover) {
|
|
274
307
|
background: var(--inkwell-bg-subtle);
|
|
275
308
|
color: var(--inkwell-text);
|
|
276
309
|
}
|
|
277
|
-
.inkwell-plugin-bubble-menu-btn-active {
|
|
310
|
+
:where(.inkwell-plugin-bubble-menu-btn-active) {
|
|
278
311
|
background: var(--inkwell-bg-subtle);
|
|
279
312
|
color: var(--inkwell-text);
|
|
280
313
|
}
|
|
281
|
-
.inkwell-plugin-bubble-menu-item-bold {
|
|
314
|
+
:where(.inkwell-plugin-bubble-menu-item-bold) {
|
|
282
315
|
font-weight: 700;
|
|
283
316
|
font-size: 14px;
|
|
284
317
|
}
|
|
285
|
-
.inkwell-plugin-bubble-menu-item-italic {
|
|
318
|
+
:where(.inkwell-plugin-bubble-menu-item-italic) {
|
|
286
319
|
font-style: italic;
|
|
287
320
|
font-size: 14px;
|
|
288
321
|
font-family: Georgia, "Times New Roman", serif;
|
|
289
322
|
}
|
|
290
|
-
.inkwell-plugin-bubble-menu-item-strike {
|
|
323
|
+
:where(.inkwell-plugin-bubble-menu-item-strike) {
|
|
291
324
|
text-decoration: line-through;
|
|
292
325
|
font-size: 14px;
|
|
293
326
|
}
|
|
294
327
|
|
|
295
328
|
/* ── Shared plugin picker (snippets, mentions, etc.) ─────────────── */
|
|
296
329
|
|
|
330
|
+
/* Popup positioning is layout-critical — the picker reads
|
|
331
|
+
`popupEl.offsetParent` for flip math, so it must remain absolutely
|
|
332
|
+
positioned inside the editor wrapper. */
|
|
297
333
|
.inkwell-plugin-picker-popup {
|
|
298
334
|
position: absolute;
|
|
299
335
|
z-index: 1001;
|
|
300
336
|
}
|
|
301
|
-
.inkwell-plugin-picker {
|
|
337
|
+
:where(.inkwell-plugin-picker) {
|
|
302
338
|
background: var(--inkwell-bg-elevated);
|
|
303
339
|
border: 1px solid var(--inkwell-border);
|
|
304
340
|
border-radius: var(--inkwell-radius);
|
|
@@ -307,7 +343,7 @@
|
|
|
307
343
|
max-width: 320px;
|
|
308
344
|
box-shadow: 0 6px 24px hsla(220, 20%, 10%, 0.14);
|
|
309
345
|
}
|
|
310
|
-
.inkwell-plugin-picker-search {
|
|
346
|
+
:where(.inkwell-plugin-picker-search) {
|
|
311
347
|
width: 100%;
|
|
312
348
|
padding: 7px 10px;
|
|
313
349
|
background: var(--inkwell-bg);
|
|
@@ -317,9 +353,12 @@
|
|
|
317
353
|
font-size: 0.85rem;
|
|
318
354
|
outline: none;
|
|
319
355
|
}
|
|
320
|
-
.inkwell-plugin-picker-search::placeholder {
|
|
356
|
+
:where(.inkwell-plugin-picker-search::placeholder) {
|
|
321
357
|
color: var(--inkwell-text-dim);
|
|
322
358
|
}
|
|
359
|
+
/* List `max-height` is structural — prevents the picker from blowing out
|
|
360
|
+
the viewport with long item lists. Scroll behavior and scrollbar
|
|
361
|
+
styling stay alongside it for a single source of truth. */
|
|
323
362
|
.inkwell-plugin-picker-list {
|
|
324
363
|
max-height: 240px;
|
|
325
364
|
overflow-y: auto;
|
|
@@ -342,27 +381,27 @@
|
|
|
342
381
|
.inkwell-plugin-picker-list::-webkit-scrollbar-thumb:hover {
|
|
343
382
|
background-color: var(--inkwell-text-dim);
|
|
344
383
|
}
|
|
345
|
-
.inkwell-plugin-picker-item {
|
|
384
|
+
:where(.inkwell-plugin-picker-item) {
|
|
346
385
|
padding: 7px 10px;
|
|
347
386
|
cursor: pointer;
|
|
348
387
|
transition: background 0.1s ease;
|
|
349
388
|
}
|
|
350
|
-
.inkwell-plugin-picker-item:hover,
|
|
351
|
-
.inkwell-plugin-picker-item-active {
|
|
389
|
+
:where(.inkwell-plugin-picker-item:hover),
|
|
390
|
+
:where(.inkwell-plugin-picker-item-active) {
|
|
352
391
|
background: var(--inkwell-bg-subtle);
|
|
353
392
|
}
|
|
354
|
-
.inkwell-plugin-picker-title {
|
|
393
|
+
:where(.inkwell-plugin-picker-title) {
|
|
355
394
|
font-size: 0.85rem;
|
|
356
395
|
font-weight: 500;
|
|
357
396
|
color: var(--inkwell-text);
|
|
358
397
|
margin-right: 0.5rem;
|
|
359
398
|
}
|
|
360
|
-
.inkwell-plugin-picker-subtitle {
|
|
399
|
+
:where(.inkwell-plugin-picker-subtitle) {
|
|
361
400
|
font-size: 0.75rem;
|
|
362
401
|
color: var(--inkwell-text-muted);
|
|
363
402
|
margin-top: 2px;
|
|
364
403
|
}
|
|
365
|
-
.inkwell-plugin-picker-preview {
|
|
404
|
+
:where(.inkwell-plugin-picker-preview) {
|
|
366
405
|
font-size: 0.75rem;
|
|
367
406
|
color: var(--inkwell-text-muted);
|
|
368
407
|
margin-top: 2px;
|
|
@@ -370,14 +409,14 @@
|
|
|
370
409
|
text-overflow: ellipsis;
|
|
371
410
|
white-space: nowrap;
|
|
372
411
|
}
|
|
373
|
-
.inkwell-plugin-picker-empty {
|
|
412
|
+
:where(.inkwell-plugin-picker-empty) {
|
|
374
413
|
padding: 12px;
|
|
375
414
|
text-align: center;
|
|
376
415
|
color: var(--inkwell-text-dim);
|
|
377
416
|
font-size: 0.85rem;
|
|
378
417
|
}
|
|
379
418
|
|
|
380
|
-
.inkwell-plugin-slash-commands-execute {
|
|
419
|
+
:where(.inkwell-plugin-slash-commands-execute) {
|
|
381
420
|
padding: 8px 10px;
|
|
382
421
|
color: var(--inkwell-text);
|
|
383
422
|
font-size: 0.85rem;
|
|
@@ -387,57 +426,58 @@
|
|
|
387
426
|
|
|
388
427
|
/* ── Renderer ────────────────────────────────────────────────────── */
|
|
389
428
|
|
|
390
|
-
/*
|
|
391
|
-
|
|
429
|
+
/* Every rule below targets a rendered HTML element (`a`, `h1`, `p`, ...)
|
|
430
|
+
that consumers customize through the `components` prop on
|
|
431
|
+
`<InkwellRenderer />` or by adding a class on the rendered element. All
|
|
432
|
+
chrome lives inside `:where()` so those overrides win without
|
|
433
|
+
`!important`. */
|
|
392
434
|
:where(.inkwell-renderer) {
|
|
435
|
+
color: var(--inkwell-text);
|
|
393
436
|
line-height: 1.65;
|
|
394
437
|
font-size: 0.95rem;
|
|
395
438
|
}
|
|
396
|
-
.inkwell-renderer {
|
|
397
|
-
color: var(--inkwell-text);
|
|
398
|
-
}
|
|
399
|
-
.inkwell-renderer :first-child {
|
|
439
|
+
:where(.inkwell-renderer :first-child) {
|
|
400
440
|
margin-top: 0;
|
|
401
441
|
}
|
|
402
|
-
.inkwell-renderer h1 {
|
|
442
|
+
:where(.inkwell-renderer h1) {
|
|
403
443
|
font-size: 1.75em;
|
|
404
444
|
font-weight: 600;
|
|
405
445
|
margin: 0.67em 0;
|
|
406
446
|
}
|
|
407
|
-
.inkwell-renderer h2 {
|
|
447
|
+
:where(.inkwell-renderer h2) {
|
|
408
448
|
font-size: 1.4em;
|
|
409
449
|
font-weight: 600;
|
|
410
450
|
margin: 0.75em 0;
|
|
411
451
|
}
|
|
412
|
-
.inkwell-renderer h3 {
|
|
452
|
+
:where(.inkwell-renderer h3) {
|
|
413
453
|
font-size: 1.2em;
|
|
414
454
|
font-weight: 600;
|
|
415
455
|
margin: 0.8em 0;
|
|
416
456
|
}
|
|
417
|
-
.inkwell-renderer p {
|
|
457
|
+
:where(.inkwell-renderer p) {
|
|
418
458
|
margin: 0.5em 0;
|
|
419
459
|
}
|
|
420
|
-
.inkwell-renderer blockquote {
|
|
460
|
+
:where(.inkwell-renderer blockquote) {
|
|
421
461
|
border-left: 3px solid var(--inkwell-border-strong);
|
|
422
462
|
padding-left: 0.85em;
|
|
423
463
|
margin: 1em 0;
|
|
424
464
|
color: var(--inkwell-text-muted);
|
|
425
465
|
}
|
|
426
|
-
.inkwell-renderer ul,
|
|
427
|
-
.inkwell-renderer ol {
|
|
466
|
+
:where(.inkwell-renderer ul),
|
|
467
|
+
:where(.inkwell-renderer ol) {
|
|
428
468
|
padding-left: 1.5em;
|
|
429
469
|
margin: 1em 0;
|
|
430
470
|
}
|
|
431
|
-
.inkwell-renderer ul {
|
|
471
|
+
:where(.inkwell-renderer ul) {
|
|
432
472
|
list-style: disc;
|
|
433
473
|
}
|
|
434
|
-
.inkwell-renderer ol {
|
|
474
|
+
:where(.inkwell-renderer ol) {
|
|
435
475
|
list-style: decimal;
|
|
436
476
|
}
|
|
437
|
-
.inkwell-renderer li {
|
|
477
|
+
:where(.inkwell-renderer li) {
|
|
438
478
|
margin: 0.25em 0;
|
|
439
479
|
}
|
|
440
|
-
.inkwell-renderer code {
|
|
480
|
+
:where(.inkwell-renderer code) {
|
|
441
481
|
background: var(--inkwell-code-bg);
|
|
442
482
|
color: var(--inkwell-code-fg);
|
|
443
483
|
padding: 0.1em 0.35em;
|
|
@@ -445,13 +485,21 @@
|
|
|
445
485
|
font-family: var(--inkwell-font-mono);
|
|
446
486
|
font-size: 0.85em;
|
|
447
487
|
}
|
|
488
|
+
/* Code-block wrapper position is structural — the copy button absolutely
|
|
489
|
+
positions inside it. */
|
|
448
490
|
.inkwell-renderer-code-block {
|
|
449
491
|
position: relative;
|
|
450
492
|
}
|
|
493
|
+
/* Copy button positioning is layout-critical (top-right inside the code
|
|
494
|
+
block); its chrome lives in `:where()` so consumers can restyle without
|
|
495
|
+
breaking placement. */
|
|
451
496
|
.inkwell-renderer-copy-btn {
|
|
452
497
|
position: absolute;
|
|
453
498
|
top: 0.5rem;
|
|
454
499
|
right: 0.5rem;
|
|
500
|
+
z-index: 1;
|
|
501
|
+
}
|
|
502
|
+
:where(.inkwell-renderer-copy-btn) {
|
|
455
503
|
display: flex;
|
|
456
504
|
align-items: center;
|
|
457
505
|
justify-content: center;
|
|
@@ -467,49 +515,48 @@
|
|
|
467
515
|
opacity 0.15s ease,
|
|
468
516
|
color 0.15s ease,
|
|
469
517
|
background 0.15s ease;
|
|
470
|
-
z-index: 1;
|
|
471
518
|
}
|
|
472
|
-
.inkwell-renderer-code-block:hover .inkwell-renderer-copy-btn {
|
|
519
|
+
:where(.inkwell-renderer-code-block:hover .inkwell-renderer-copy-btn) {
|
|
473
520
|
opacity: 1;
|
|
474
521
|
}
|
|
475
|
-
.inkwell-renderer-copy-btn:hover {
|
|
522
|
+
:where(.inkwell-renderer-copy-btn:hover) {
|
|
476
523
|
background: var(--inkwell-bg-subtle);
|
|
477
524
|
color: var(--inkwell-text);
|
|
478
525
|
}
|
|
479
|
-
.inkwell-renderer pre {
|
|
526
|
+
:where(.inkwell-renderer pre) {
|
|
480
527
|
margin: 1em 0;
|
|
481
528
|
border-radius: var(--inkwell-radius);
|
|
482
529
|
overflow: auto;
|
|
483
530
|
border: 1px solid var(--inkwell-border);
|
|
484
531
|
background: var(--inkwell-bg-subtle);
|
|
485
532
|
}
|
|
486
|
-
.inkwell-renderer pre code {
|
|
533
|
+
:where(.inkwell-renderer pre code) {
|
|
487
534
|
display: block;
|
|
488
535
|
padding: 0.85em 1em;
|
|
489
536
|
background: transparent;
|
|
490
537
|
color: var(--inkwell-text);
|
|
491
538
|
font-size: 0.82em;
|
|
492
539
|
}
|
|
493
|
-
.inkwell-renderer a {
|
|
540
|
+
:where(.inkwell-renderer a) {
|
|
494
541
|
color: var(--inkwell-accent);
|
|
495
542
|
text-decoration: underline;
|
|
496
543
|
text-underline-offset: 2px;
|
|
497
544
|
}
|
|
498
|
-
.inkwell-renderer hr {
|
|
545
|
+
:where(.inkwell-renderer hr) {
|
|
499
546
|
border: none;
|
|
500
547
|
border-top: 1px solid var(--inkwell-border);
|
|
501
548
|
margin: 2em 0;
|
|
502
549
|
}
|
|
503
|
-
.inkwell-renderer strong {
|
|
550
|
+
:where(.inkwell-renderer strong) {
|
|
504
551
|
font-weight: 600;
|
|
505
552
|
}
|
|
506
|
-
.inkwell-renderer em {
|
|
553
|
+
:where(.inkwell-renderer em) {
|
|
507
554
|
font-style: italic;
|
|
508
555
|
}
|
|
509
|
-
.inkwell-renderer del {
|
|
556
|
+
:where(.inkwell-renderer del) {
|
|
510
557
|
text-decoration: line-through;
|
|
511
558
|
}
|
|
512
|
-
.inkwell-renderer img {
|
|
559
|
+
:where(.inkwell-renderer img) {
|
|
513
560
|
max-width: 100%;
|
|
514
561
|
height: auto;
|
|
515
562
|
border-radius: var(--inkwell-radius);
|