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