@quillmark/svelte 0.2.0 → 0.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.
Files changed (116) hide show
  1. package/README.md +2 -2
  2. package/THEMING.md +11 -7
  3. package/dist/core/address.d.ts +7 -7
  4. package/dist/core/address.js +6 -6
  5. package/dist/core/bloom.d.ts +5 -5
  6. package/dist/core/bloom.js +8 -8
  7. package/dist/core/codec/anchor.d.ts +1 -1
  8. package/dist/core/codec/anchor.js +1 -1
  9. package/dist/core/codec/atoms.d.ts +10 -0
  10. package/dist/core/codec/atoms.js +78 -0
  11. package/dist/core/codec/clipboard.d.ts +59 -0
  12. package/dist/core/codec/clipboard.js +202 -0
  13. package/dist/core/codec/code.d.ts +1 -1
  14. package/dist/core/codec/code.js +4 -4
  15. package/dist/core/codec/decode.d.ts +1 -1
  16. package/dist/core/codec/decode.js +8 -8
  17. package/dist/core/codec/encode.d.ts +4 -4
  18. package/dist/core/codec/encode.js +10 -10
  19. package/dist/core/codec/field.d.ts +21 -26
  20. package/dist/core/codec/field.js +33 -32
  21. package/dist/core/codec/index.js +5 -8
  22. package/dist/core/codec/inputrules.js +56 -18
  23. package/dist/core/codec/islands.d.ts +11 -7
  24. package/dist/core/codec/islands.js +16 -10
  25. package/dist/core/codec/keymap.d.ts +5 -6
  26. package/dist/core/codec/keymap.js +8 -7
  27. package/dist/core/codec/lists.d.ts +3 -3
  28. package/dist/core/codec/lists.js +32 -13
  29. package/dist/core/codec/marks.d.ts +1 -1
  30. package/dist/core/codec/marks.js +1 -1
  31. package/dist/core/codec/positions.js +1 -1
  32. package/dist/core/codec/prose.css +230 -215
  33. package/dist/core/codec/schema.js +4 -4
  34. package/dist/core/codec/slash.d.ts +39 -41
  35. package/dist/core/codec/slash.js +0 -0
  36. package/dist/core/codec/table-view.d.ts +12 -16
  37. package/dist/core/codec/table-view.js +488 -292
  38. package/dist/core/codec/table.d.ts +42 -15
  39. package/dist/core/codec/table.js +70 -26
  40. package/dist/core/errors.d.ts +5 -5
  41. package/dist/core/index.js +2 -2
  42. package/dist/core/lifecycle.js +1 -1
  43. package/dist/core/rebind.svelte.d.ts +2 -2
  44. package/dist/core/rebind.svelte.js +4 -4
  45. package/dist/core/teardown.d.ts +1 -1
  46. package/dist/core/teardown.js +1 -1
  47. package/dist/core/theme.css +144 -54
  48. package/dist/preset/index.css +1 -1
  49. package/dist/preset/recipes.css +31 -29
  50. package/dist/preset/scale.css +36 -25
  51. package/dist/preview/Preview.svelte +12 -10
  52. package/dist/preview/Preview.svelte.d.ts +3 -3
  53. package/dist/preview/bridge.js +4 -4
  54. package/dist/preview/controller.js +3 -3
  55. package/dist/preview/geometry.d.ts +2 -2
  56. package/dist/preview/geometry.js +2 -2
  57. package/dist/preview/index.js +3 -3
  58. package/dist/preview/overlay.d.ts +1 -1
  59. package/dist/preview/overlay.js +3 -3
  60. package/dist/preview/paint.js +15 -17
  61. package/dist/visual/ArrayField.svelte +80 -66
  62. package/dist/visual/ArrayField.svelte.d.ts +1 -1
  63. package/dist/visual/BooleanField.svelte +8 -6
  64. package/dist/visual/BooleanField.svelte.d.ts +2 -2
  65. package/dist/visual/Card.svelte +151 -325
  66. package/dist/visual/Card.svelte.d.ts +2 -6
  67. package/dist/visual/CardControls.svelte +1 -1
  68. package/dist/visual/DateField.svelte +19 -19
  69. package/dist/visual/DateField.svelte.d.ts +3 -3
  70. package/dist/visual/DiagnosticList.svelte +1 -1
  71. package/dist/visual/EnumField.svelte +16 -16
  72. package/dist/visual/EnumField.svelte.d.ts +2 -2
  73. package/dist/visual/Field.svelte +128 -115
  74. package/dist/visual/Field.svelte.d.ts +1 -1
  75. package/dist/visual/FieldHint.svelte +24 -42
  76. package/dist/visual/FieldHint.svelte.d.ts +1 -1
  77. package/dist/visual/FieldLabel.svelte +8 -8
  78. package/dist/visual/FormatPopover.svelte +80 -35
  79. package/dist/visual/NumberField.svelte +5 -5
  80. package/dist/visual/NumberField.svelte.d.ts +1 -1
  81. package/dist/visual/ObjectField.svelte +9 -9
  82. package/dist/visual/ObjectField.svelte.d.ts +1 -1
  83. package/dist/visual/ProseArrayElement.svelte +11 -13
  84. package/dist/visual/ProseArrayElement.svelte.d.ts +1 -1
  85. package/dist/visual/ProseField.svelte +53 -84
  86. package/dist/visual/ProseField.svelte.d.ts +12 -17
  87. package/dist/visual/SlashMenu.svelte +42 -16
  88. package/dist/visual/TextField.svelte +5 -5
  89. package/dist/visual/TextField.svelte.d.ts +1 -1
  90. package/dist/visual/TipsCard.svelte +43 -28
  91. package/dist/visual/VisualEditor.svelte +6 -6
  92. package/dist/visual/VisualEditorInner.svelte +122 -129
  93. package/dist/visual/controls.css +74 -30
  94. package/dist/visual/diagnostics.d.ts +5 -5
  95. package/dist/visual/diagnostics.js +3 -3
  96. package/dist/visual/domid.js +3 -3
  97. package/dist/visual/ext.d.ts +1 -1
  98. package/dist/visual/ext.js +1 -1
  99. package/dist/visual/icons/nodes.d.ts +3 -0
  100. package/dist/visual/icons/nodes.js +2 -1
  101. package/dist/visual/index.js +4 -4
  102. package/dist/visual/leaves.d.ts +3 -3
  103. package/dist/visual/leaves.js +1 -1
  104. package/dist/visual/links.d.ts +24 -0
  105. package/dist/visual/links.js +67 -0
  106. package/dist/visual/props.d.ts +8 -8
  107. package/dist/visual/signals.d.ts +6 -6
  108. package/dist/visual/strings.d.ts +14 -19
  109. package/dist/visual/strings.js +5 -7
  110. package/dist/visual/structure.d.ts +24 -17
  111. package/dist/visual/structure.js +8 -8
  112. package/dist/visual/synced.svelte.d.ts +1 -1
  113. package/dist/visual/synced.svelte.js +4 -4
  114. package/dist/visual/tips.d.ts +2 -2
  115. package/dist/visual/tips.js +3 -3
  116. package/package.json +1 -1
@@ -1,10 +1,10 @@
1
1
  /* The one derivation: public dials in, a closed private scale out (THEMING.md).
2
2
  Everything below reads a rung rather than minting a value, which is this file's
3
3
  whole reason for existing and what `check:style` holds everywhere else. Colour,
4
- geometry, type and motion are all derived here, so each is minted in ONE place
4
+ geometry, type and motion are all derived here, so each is minted in one place
5
5
  instead of once per detached root.
6
6
 
7
- TRANSPORT: a stylesheet, side-effect imported by `core/index.ts` and applied to
7
+ Transport: a stylesheet, side-effect imported by `core/index.ts` and applied to
8
8
  every element marked `data-qm-root`. The package imports it itself, so there is
9
9
  no `import './theme.css'` for a consumer to forget. A stylesheet rather than an
10
10
  inline `style` attribute is what buys the three things an attribute cannot
@@ -19,21 +19,21 @@
19
19
  chrome that still reads as intact. `check:bundle` holds both ends, the claim and
20
20
  the built bytes.
21
21
 
22
- Every value stays a `var()` reference, so the dials resolve against the CASCADE
22
+ Every value stays a `var()` reference, so the dials resolve against the cascade
23
23
  at each root: a consumer's `[data-theme="dark"]` ancestor rule flows in
24
24
  unchanged, the light/dark default follows the `color-scheme` the host declares
25
25
  with no JS and no media query, and `color-mix` runs at paint time. The rungs are
26
- declared ON the root, so they are reachable only by a rule targeting it:
26
+ declared on the root, so they are reachable only by a rule targeting it:
27
27
  THEMING.md §"What is deliberately not public" states the terms.
28
28
 
29
- LAYERS: `qm` is the top-level layer name, and it is contract — a consumer
29
+ Layers: `qm` is the top-level layer name, and it is contract — a consumer
30
30
  pins the order against it with `@layer qm, app;` in their own CSS, which wins
31
31
  in both bundler orders (THEMING §"Your CSS beats ours"). Unlayered consumer
32
32
  CSS beats every layer here for free.
33
33
 
34
- `@property` registers the three ENTRY rungs, the ones reading a dial, and
34
+ `@property` registers the three entry rungs, the ones reading a dial, and
35
35
  nothing below them. An `initial-value` must be computationally independent,
36
- which `rem` is not, so the DIALS cannot be registered: their defaults are
36
+ which `rem` is not, so the dials cannot be registered: their defaults are
37
37
  `rem`. A rung can, because registration reads the initial value and never the
38
38
  declared one, so a `px` initial sits under a `calc()` chain over a `rem` dial
39
39
  without contradiction. What it buys is the poison case: `--qm-space: 4` is a
@@ -69,19 +69,23 @@
69
69
  @layer qm.scale {
70
70
  :where([data-qm-root]) {
71
71
  /* ── Poles ───────────────────────────────────────────────────────────────
72
- Each dial's default, stated ONCE. Every rung below reads a pole, never a
72
+ Each dial's default, stated once. Every rung below reads a pole, never a
73
73
  dial, so both schemes cost two declarations rather than fifteen; and the
74
- dial sits in FRONT of the default, so a consumer's ancestor value wins in
74
+ dial sits in front of the default, so a consumer's ancestor value wins in
75
75
  either scheme, which it would not if a scheme rule set `--qm-bg` instead.
76
76
 
77
- `light-dark()` keys the default off the `color-scheme` this root INHERITS,
77
+ `light-dark()` keys the default off the `color-scheme` this root inherits,
78
78
  which is the host's: an app that declares `dark` gets a dark surface
79
79
  whatever the OS says, and one that declares nothing gets light, matching
80
80
  its own unstyled text. So the package owns no mode logic at all: light or
81
81
  dark is the mounting site's, like every other value here (THEMING.md
82
- §"The surface follows your colour scheme"). */
83
- --_qm-bg: var(--qm-bg, light-dark(#fff, #14171c));
84
- --_qm-fg: var(--qm-fg, light-dark(#1a1a1a, #e8eaed));
82
+ §"The surface follows your colour scheme").
83
+
84
+ `--qm-bg` is the card, not the column behind it: the plane content is
85
+ written on, which is also the preview's paper. Everything else is a step
86
+ off it, and the column is a step down. */
87
+ --_qm-bg: var(--qm-bg, light-dark(#fff, #272729));
88
+ --_qm-fg: var(--qm-fg, light-dark(#1c1c1c, #d7dadc));
85
89
  --_qm-accent: var(--qm-accent, #2563eb);
86
90
  --_qm-danger: var(--qm-danger, #c5221f);
87
91
  --_qm-warning: var(--qm-warning, #b25000);
@@ -89,21 +93,60 @@
89
93
  --_qm-font-mono: var(--qm-font-mono, ui-monospace, monospace);
90
94
 
91
95
  /* ── Colour ──────────────────────────────────────────────────────────────
92
- Surfaces step bg → fg, ink steps fg → bg, mixed in oklab; sRGB muddies
93
- the mid-tones and the label/meta/border rungs are exactly mid-tone. So
94
- inverting the poles inverts the scale. The percentages are calibrated to
95
- the light-mode literals they stand in for (17% ≈ #d4d4d4, 35% ≈ #555).
96
+ Ink steps fg → bg, the border and hover rungs step bg → fg, all mixed in
97
+ oklab; sRGB muddies the mid-tones and the label/meta/border rungs are
98
+ exactly mid-tone. So inverting the poles inverts that half of the scale.
99
+ The percentages are calibrated to the light-mode literals they stand in
100
+ for (17% ≈ #d4d4d4, 35% ≈ #555).
101
+
102
+ Planes are the half that does not read the ink pole, because what makes a
103
+ card read as a card is that it is the brighter plane, in both schemes
104
+ alike (ARCHITECTURE §Styling). A plane stepped toward the ink is right in
105
+ dark and inverted in light, where it darkens the card below the page it
106
+ floats on. So `sunken` and `well` step toward shadow and `raised` toward
107
+ light, and the base plane — a card, the preview's paper — is the pole
108
+ itself.
109
+
110
+ Two planes sink. `sunken` is the ground — the column behind the cards, the
111
+ desk behind the sheets — and lifting the plane above it takes very little
112
+ at the light pole. `well` is the hole cut into a card: a field, a table's
113
+ header band, the one native select, none of which draw an edge, so the
114
+ step is the whole of what says a value is typed there. The order at the
115
+ light pole is card, ground, well; at the dark pole the two sink to within
116
+ a channel of each other, which is where a card with little light left to
117
+ give up leaves them.
118
+
119
+ Each takes two arms, because one figure cannot serve both poles: a dark
120
+ surface has to spend more of what little it has before the card above it
121
+ reads as lifted. Pinning a dark palette under a light `color-scheme` takes
122
+ the light arm with it
123
+ (THEMING §"The surface follows your colour scheme"), which is a step you
124
+ can barely see, so a host that pins declares the scheme with it.
96
125
 
97
- The three surface rungs sit EVENLY 4pp apart, which is what keeps them three
98
- distinguishable steps: uneven spacing spends one rung to buy another:
99
- widening `raised` alone would leave `hover` 1pp above it. `raised` steps
100
- toward the INK pole rather than away from it, so a card is darker than the
101
- page in light and lighter in dark. */
126
+ The ground steps by subtraction where every other rung mixes: a mix toward
127
+ black is a ratio, so it scales what it takes and pulls the result toward
128
+ neutral, and a ground is a fixed distance that keeps the pole's hue. Its
129
+ arms are 0.0214 of oklab L in light and 0.0553 in dark, with a/b terms
130
+ carrying a cool cast a mix toward black would strip, so the default lands
131
+ on `#f7f8f9` and `#1a1a1b` exactly and a turned `--qm-bg` tints the plane
132
+ under it.
133
+
134
+ `raised` is a no-op at the light pole, where the card is already white
135
+ and there is nowhere further to go, so a floating surface separates on
136
+ its hairline in light and on the step in dark. */
102
137
  --_qm-surface: var(--_qm-bg);
103
- --_qm-surface-raised: color-mix(in oklab, var(--_qm-bg), var(--_qm-fg) 4%);
138
+ --_qm-surface-sunken: light-dark(
139
+ oklab(from var(--_qm-bg) calc(l - 0.0214) calc(a - 0.00065) calc(b - 0.00158)),
140
+ oklab(from var(--_qm-bg) calc(l - 0.0553) calc(a - 0.00048) calc(b + 0.00165))
141
+ );
142
+ --_qm-surface-well: light-dark(
143
+ color-mix(in oklab, var(--_qm-bg), #000 4%),
144
+ color-mix(in oklab, var(--_qm-bg), #000 20%)
145
+ );
146
+ --_qm-surface-raised: color-mix(in oklab, var(--_qm-bg), #fff 8%);
104
147
  --_qm-surface-hover: color-mix(in oklab, var(--_qm-bg), var(--_qm-fg) 8%);
105
148
  --_qm-border: color-mix(in oklab, var(--_qm-bg), var(--_qm-fg) 17%);
106
- /* A rule that separates without structuring: the lines BETWEEN a table's cells,
149
+ /* A rule that separates without structuring: the lines between a table's cells,
107
150
  where the frame around them is the structure. Half the border's mix rather
108
151
  than a surface rung of its own, because it is a stroke and reads against the
109
152
  surface behind it, not a fill stacked on one. */
@@ -113,10 +156,40 @@
113
156
  --_qm-ink: var(--_qm-fg);
114
157
  --_qm-ink-label: color-mix(in oklab, var(--_qm-fg), var(--_qm-bg) 35%);
115
158
  --_qm-ink-ghost: color-mix(in oklab, var(--_qm-fg), var(--_qm-bg) 60%);
116
- /* The correlation wash (`core/bloom.ts`). Its alpha is a PEAK, not a tint: the
159
+ /* The correlation wash (`core/bloom.ts`). Its alpha is a peak, not a tint: the
117
160
  wash animates from and back to zero, never held, so it reads at pane scale
118
161
  over the preview's paper while the paper rests clean. */
119
162
  --_qm-accent-wash: color-mix(in oklab, var(--_qm-accent) 18%, transparent);
163
+ /* The accent held: what a selected line of a table is tinted with, and what its
164
+ grip is filled with, so the two ends of one gesture are one colour. A second
165
+ name rather than the wash reused, because the two answer different questions
166
+ and the numbers follow: a peak passes over paper and can be strong, where a
167
+ tint is held under body text and cannot. Translucent, so it
168
+ stacks over whichever surface rung the cell already draws instead of replacing
169
+ it. */
170
+ --_qm-accent-tint: color-mix(in oklab, var(--_qm-accent) 12%, transparent);
171
+ /* The danger hue held: what a destructive control fills with where the family's
172
+ neutral hover rung would read as one more button. Mixed at the accent tint's
173
+ strength, so a held tint is a held tint whichever hue it carries. */
174
+ --_qm-danger-tint: color-mix(in oklab, var(--_qm-danger) 12%, transparent);
175
+ /* The label ink held: what a trigger fills with whose own ink never steps, so
176
+ the fill arriving under it is that tone at a strength a surface reads
177
+ through. */
178
+ --_qm-add-fill: color-mix(in oklab, var(--_qm-ink-label) 15%, transparent);
179
+
180
+ /* The tips card'S hue: the surface's one exit from the greyscale that is not
181
+ a status, and what the amber and the typewriter face say together is
182
+ draft (VISUAL_EDITOR §"Card operations"). A literal rather than a dial
183
+ because there is nothing left to turn: the three rungs under it mix over
184
+ the surface and the ink a consumer already tuned, so the card follows a
185
+ brand untold. The mixes are faint on purpose: a warmth, not a badge. */
186
+ --_qm-tips: #e88c0a;
187
+ --_qm-tips-surface: color-mix(in oklab, var(--_qm-surface), var(--_qm-tips) 4%);
188
+ --_qm-tips-ink: color-mix(in oklab, var(--_qm-ink), var(--_qm-tips) 24%);
189
+ /* The chip behind a token in a tip. The card's own face is already
190
+ monospace, so a `code` run needs a fill to read as literal text rather
191
+ than as the sentence around it. */
192
+ --_qm-tips-chip: color-mix(in oklab, var(--_qm-tips) 12%, transparent);
120
193
 
121
194
  /* ── Ratios and effects ──────────────────────────────────────────────────
122
195
  No palette fixes these, so they are their own rungs. There is no shadow
@@ -136,10 +209,10 @@
136
209
  --_qm-opacity-muted: 0.5;
137
210
 
138
211
  /* ── Focus ───────────────────────────────────────────────────────────────
139
- These fix the ring's VALUE, so no control mints it. Which properties draw a
212
+ These fix the ring's value, so no control mints it. Which properties draw a
140
213
  ring, and on what state, is the other half: a rule, `.qm-focus-ring` in
141
214
  `visual/controls.css`, since a rung each control reassembles is a scale
142
- only up to the point where it is assembled. ONE width: focus is the only
215
+ only up to the point where it is assembled. One width: focus is the only
143
216
  state that draws a ring anywhere, so there is no held-back tier under it. */
144
217
  --_qm-ring-width: 2px;
145
218
  /* Every ring the surface draws, whatever the state under it: focus and selection
@@ -160,14 +233,18 @@
160
233
  animates over WAAPI and reads it from here. */
161
234
  --_qm-bloom-dwell: 1100ms;
162
235
 
163
- /* ONE curve, symmetric because an interruption turns these trips around: a hover
164
- leaves before it arrives, a card collapses mid-expand. The one-way pair a scale
165
- like this often carries is minted when a trip long enough to read one arrives;
166
- the popover's pop is the nearest and at `fast` it is under that threshold. */
236
+ /* One curve, symmetric because an interruption turns these trips around: a hover
237
+ leaves before it arrives, a card collapses mid-expand. Every trip at `fast` or
238
+ `slow` takes it; a one-way shape is legible only over a longer one. */
167
239
  --_qm-ease-reverse: cubic-bezier(0.4, 0, 0.6, 1);
240
+ /* A trip rather than a rung, duration and curve composed the way `--_qm-ring`
241
+ composes its three: neither half is reachable alone. Weighted to its end, so an
242
+ arrival settles into its rest instead of stopping at it, and long enough that a
243
+ control resting at nothing reads as arriving rather than as switching. */
244
+ --_qm-reveal: 500ms cubic-bezier(0.4, 0, 0.2, 1);
168
245
 
169
246
  /* ── Geometry ──────────────────────────────────────────────────────────*/
170
- /* ONE stroke width for every edge the chrome draws: a card's, a control's,
247
+ /* One stroke width for every edge the chrome draws: a card's, a control's,
171
248
  and the metadata bracket's three rules alike. A threshold rather than a
172
249
  rhythm choice, like the tap floor: a hairline is a hairline at any
173
250
  `--qm-space`, so it does not derive from a dial. It exists as a rung because
@@ -176,7 +253,7 @@
176
253
  against a token. */
177
254
  --_qm-border-width: 1px;
178
255
  --_qm-radius: var(--qm-radius, 8px);
179
- /* The INTERIOR corner, and HALF is the relationship rather than the number: a
256
+ /* The interior corner, and half is the relationship rather than the number: a
180
257
  corner inside a corner reads as nested only while it is visibly tighter, and
181
258
  halving holds that at every setting of the dial, zero included. */
182
259
  --_qm-radius-inner: calc(var(--_qm-radius) / 2);
@@ -190,13 +267,13 @@
190
267
  --_qm-space-4: calc(var(--_qm-space) * 4);
191
268
  /* A rung because the two axes are two decisions and the ladder alone cannot hold
192
269
  them together: `check:style`'s rhythm axis sees each box read a rung, never that
193
- they read the SAME one, which is the drift `visual/controls.css` already names
270
+ they read the same one, which is the drift `visual/controls.css` already names
194
271
  for the type half. Asymmetric because the vertical is what leading leaves once
195
272
  it has taken the line box, and the horizontal is how far in the text starts,
196
273
  which nothing else fixes. */
197
274
  --_qm-inset-control: var(--_qm-space) var(--_qm-space-3);
198
- /* The scroll TAIL: dead space under the last card, so it can be read at the
199
- middle of a pane rather than at its bottom edge. A fraction of the VIEWPORT
275
+ /* The scroll tail: dead space under the last card, so it can be read at the
276
+ middle of a pane rather than at its bottom edge. A fraction of the viewport
200
277
  rather than a step on the ramp, because what it answers is how far the eye
201
278
  sits from the bottom of the screen, which no spacing dial knows. Spent by
202
279
  the editor alone (`.qm-pane`): a stack of cards is what has a last one to
@@ -208,7 +285,7 @@
208
285
  floor is one number instead of one expression per control. */
209
286
  --_qm-tap-min: 24px;
210
287
  /* The reorder/delete glyph. A rung because the card header's
211
- right hang is HALF the difference between this and the tap floor: the glyph
288
+ right hang is half the difference between this and the tap floor: the glyph
212
289
  centres in a target sized by the floor, so what stands between it and the
213
290
  card's gutter is an arithmetic of the two, and a literal on either side is a
214
291
  balance that silently breaks when the glyph moves. Sized in CSS rather than
@@ -218,35 +295,48 @@
218
295
  --_qm-glyph-control: 14px;
219
296
 
220
297
  /* ── Type ────────────────────────────────────────────────────────────────
221
- `--qm-font-size` anchors the CHROME rung; 1.125 is the ratio between adjacent
298
+ `--qm-font-size` anchors the chrome rung; 1.125 is the ratio between adjacent
222
299
  rungs: a step up (title) and one down (label). The ratio and the
223
300
  weight are fixed conventions, not dials: no consumer tunes a typographic
224
- ratio, and a dial nobody turns is a name every reader still holds. THREE chrome
301
+ ratio, and a dial nobody turns is a name every reader still holds. Three chrome
225
302
  rungs: a second step below `label` lands near 11px, under a size anything here
226
303
  wants to be read at, and the supporting text that would take it is what `label`
227
304
  already is. */
228
305
  --_qm-text-body: var(--qm-font-size, 0.875rem);
229
306
  --_qm-text-title: calc(var(--_qm-text-body) * 1.125);
230
307
  --_qm-text-label: calc(var(--_qm-text-body) / 1.125);
231
- /* PAPER: the document body answers to the preview's paper where every other
308
+ /* Paper: the document body answers to the preview's paper where every other
232
309
  surface here answers to the control beside it, so a rung shared with the chrome
233
310
  makes a consumer asking for larger prose take larger inputs with it. 16/15 where
234
- the ramp steps at 9/8: small enough to read as a change of REGISTER rather than
311
+ the ramp steps at 9/8: small enough to read as a change of register rather than
235
312
  a rung of hierarchy, and clear of the title rung, which one 9/8 step lands on
236
313
  exactly. */
237
314
  --_qm-text-paper: calc(var(--_qm-text-body) * 16 / 15);
238
- /* ONE weight over the regular: every heading here is a name over the value under
239
- it, so a second is a rung with no register beneath it. Hierarchy is the size
240
- ramp's. */
241
- --_qm-weight-label: 600;
315
+ /* Two weights over the regular, and only one of them is chrome. `mid` names
316
+ everything the surface names — a card title, a section header, a field
317
+ label, a nested property — so a stack of them reads as one register and
318
+ hierarchy stays the size ramp's, which is the axis that can carry it.
319
+ 500 rather than 600 because the family dial resolves to the platform UI
320
+ face, whose 600 is heavier at the same number than the webfont a surface
321
+ is usually drawn against: at the label rung it goes smudgy, and one
322
+ number across three sizes does not read as one weight.
323
+
324
+ `strong` is not a rung of that ramp. It is the mark a run wears where
325
+ weight is the only signal it has: a heading inside a prose leaf, drawn at
326
+ no size step of its own because the quill sets the paper's; a table
327
+ island's header row; the stored value in an enum listbox. Reaching for it
328
+ where a size or a tone could speak is the drift the split exists to
329
+ stop. */
330
+ --_qm-weight-strong: 600;
331
+ --_qm-weight-mid: 500;
242
332
  /* Leading: the ramp's third axis, and it does not track the sizes one for one:
243
333
  two rungs, because a wrapped label and a wrapped paragraph want different
244
334
  rhythms and nothing wants four. `body` is reading rhythm (both prose leaves,
245
335
  every control beside them, the tips card's guidance); `tight` is a line that is
246
- a label rather than a passage. Unitless, so a rung inherits MULTIPLICATIVELY
336
+ a label rather than a passage. Unitless, so a rung inherits multiplicatively
247
337
  and holds against whichever size rung the surface reads: a `rem` leading
248
338
  would freeze at one size and disagree with the rest of the ramp. It is the
249
- axis paper and chrome SHARE: both read `body`, and the size rung is what
339
+ axis paper and chrome share: both read `body`, and the size rung is what
250
340
  separates them. `line-height: 1` is outside the axis: it collapses the
251
341
  line box onto its content, a glyph or a button's one-line label. */
252
342
  --_qm-leading-body: 1.5;
@@ -260,12 +350,12 @@
260
350
  picker, the caret) lands on the same pole the poles above resolve to.
261
351
  Declaring it here would break that lockstep in the one direction that
262
352
  matters: a host that declares `dark` would get light native chrome under
263
- a dark surface. A consumer that PINS a palette against its own scheme
353
+ a dark surface. A consumer that pins a palette against its own scheme
264
354
  declares `color-scheme` with it, on the root (THEMING.md).
265
355
 
266
- Face, ink and LEADING are the three axes a root carries this way. Leading
356
+ Face, ink and leading are the three axes a root carries this way. Leading
267
357
  belongs with the other two because a unitless ratio inherits
268
- MULTIPLICATIVELY: it holds against whatever size rung each surface reads, so
358
+ multiplicatively: it holds against whatever size rung each surface reads, so
269
359
  it imposes less than the ink beside it, and the reason `font-size` stays off
270
360
  does not transfer: a ratio has no size to sweep a consumer's content with.
271
361
  What it buys is that `normal` (the UA figure near 1.14, varying by font) is
@@ -273,13 +363,13 @@
273
363
  whether or not it remembers to say so, and a per-surface
274
364
  `--_qm-leading-tight` reads as the deliberate override it is.
275
365
 
276
- Deliberately NOT `font-size`, and the reason is about the ROOT rule rather
366
+ Deliberately not `font-size`, and the reason is about the root rule rather
277
367
  than about size: a root-level body size sweeps every descendant a consumer
278
368
  may have put inside the marker, which is a reach the derivation does not
279
369
  have. The rung is not withheld from the surfaces: every control and every
280
370
  prose leaf reads `--_qm-text-body` in its own recipe, which is
281
371
  what closes the ramp and makes `--qm-font-size` move an input. What would
282
- break a mounted leaf is a size that CHANGES under it; a rung is fixed at
372
+ break a mounted leaf is a size that changes under it; a rung is fixed at
283
373
  mount unless the consumer turns the dial, and a consumer turning a dial is
284
374
  entitled to the reflow. So: the root imposes no size, each surface reads the
285
375
  rung it wants. */
@@ -288,10 +378,10 @@
288
378
  line-height: var(--_qm-leading-body);
289
379
  }
290
380
 
291
- /* Reduced motion collapses the SCALE, never a list of selectors.
381
+ /* Reduced motion collapses the scale, never a list of selectors.
292
382
  Two values here are not the rung they look like:
293
383
 
294
- `1ms` rather than `none`, because a collapsed transition still FIRES: a surface
384
+ `1ms` rather than `none`, because a collapsed transition still fires: a surface
295
385
  waiting on `transitionend` keeps its event, where `transition: none` would strand
296
386
  it. The beat is under perception either way.
297
387
 
@@ -1,7 +1,7 @@
1
1
  /* `@quillmark/svelte/preset`, the package's one CSS entry point: the endorsed look for
2
2
  the page a surface is mounted on. Opt-in and side-effect free until imported:
3
3
  `core/index.ts` pulls `core/theme.css` for the surfaces and never this, because this
4
- styles the DOCUMENT and nothing may put that in a consumer's page uninvited.
4
+ styles the document and nothing may put that in a consumer's page uninvited.
5
5
 
6
6
  Two files because one of them is exempt: `scale.css` is where the literals are
7
7
  minted, `recipes.css` is held to reading them. */
@@ -1,14 +1,14 @@
1
- /* THE ENDORSED LOOK: the rules a host draws around a mounted surface AND the shell it
1
+ /* The endorsed look: the rules a host draws around a mounted surface and the shell it
2
2
  mounts one in, as classes it puts on its own elements. The rungs beside this in
3
3
  `scale.css` are the invisible half (a scale alone still leaves a consumer writing
4
4
  every declaration before anything on the page looks like anything), so the recipes
5
5
  are what the preset is for. This file mints nothing; `check:style` runs its axes here.
6
6
 
7
- These are HOST classes. They land on the consumer's DOM, never on a mounted root, so
7
+ These are host classes. They land on the consumer's DOM, never on a mounted root, so
8
8
  they freeze nothing about the surfaces' interior: the reason the package withholds
9
9
  its own internal classes does not reach them.
10
10
 
11
- UNLAYERED, deliberately. `@layer qm` exists so consumer CSS beats the surfaces
11
+ Unlayered, deliberately. `@layer qm` exists so consumer CSS beats the surfaces
12
12
  without `!important`, and the same has to be true here; a layer of the preset's own
13
13
  would put a second name in the contract and change what `revert-layer` at the foot
14
14
  of this file resolves against. Unlayered, a consumer's own rules win by ordinary
@@ -16,12 +16,12 @@
16
16
 
17
17
  /* ── The page ──────────────────────────────────────────────────────────────── */
18
18
 
19
- /* The baseline, on a CLASS rather than `body`: a preset that restyled the document
19
+ /* The baseline, on a class rather than `body`: a preset that restyled the document
20
20
  root would land on an app that already has a page and change it out from under
21
21
  whatever was there. The host puts this where its own layout starts: `body`, or the
22
22
  element the app mounts into.
23
23
 
24
- `color-scheme` is declared HERE and not by the package: light or dark is the
24
+ `color-scheme` is declared here and not by the package: light or dark is the
25
25
  mounting site's, and this file is the mounting site. `light dark` follows the OS;
26
26
  a host pinning one declares it on the same element and wins by source order. */
27
27
  .qm-page {
@@ -43,11 +43,11 @@
43
43
 
44
44
  /* ── The workspace ─────────────────────────────────────────────────────────── */
45
45
 
46
- /* The rules above dress the page a surface sits ON; these four are the SHELL it is
46
+ /* The rules above dress the page a surface sits on; these four are the shell it is
47
47
  mounted in, a tool where `.qm-page` is a document: the screen an app that mounts two
48
48
  surfaces over one session is, drawn once (ARCHITECTURE §Styling).
49
49
 
50
- PINNED to the viewport rather than sized to it: a page-height box still leaves the
50
+ Pinned to the viewport rather than sized to it: a page-height box still leaves the
51
51
  root scroller counting the overflow its panes clip, and a wheel over the chrome drags
52
52
  the whole app off the top. Three bands (a head, the body, an optional foot), and the
53
53
  body takes what is left and may shrink below its content, so the panes in it own
@@ -67,8 +67,8 @@ html:has(.qm-workspace) {
67
67
  overscroll-behavior: none;
68
68
  }
69
69
 
70
- /* A band's LINE: the row a head or a foot puts its parts on, wrapping, centred. That is
71
- the whole of it. What a band is made OF is the host's: the rule under it, the gutter
70
+ /* A band's line: the row a head or a foot puts its parts on, wrapping, centred. That is
71
+ the whole of it. What a band is made of is the host's: the rule under it, the gutter
72
72
  beside it, and the depth of it, because where a band ends and how tall it stands are
73
73
  page-shell decisions: a site holding its content to a maximum runs the rule past it at
74
74
  its own rhythm, and a one-screen tool has no maximum to hold to. */
@@ -79,11 +79,11 @@ html:has(.qm-workspace) {
79
79
  gap: var(--qmh-space-2) var(--qmh-space-4);
80
80
  }
81
81
 
82
- /* TWO EVEN TRACKS for two surfaces, and no resizer, since a divider that can be dragged
82
+ /* Two even tracks for two surfaces, and no resizer, since a divider that can be dragged
83
83
  is a control competing with what it divides. Each track may shrink below its content,
84
84
  which is what lets the frame in it clip rather than grow.
85
85
 
86
- The GAP is the endorsed default and not a fact about splitting: two surfaces standing
86
+ The gap is the endorsed default and not a fact about splitting: two surfaces standing
87
87
  apart on a page read as two things, which is what a host showing its instruments wants.
88
88
  A host that spends the whole screen on the mounts closes it to nothing and carries a
89
89
  hairline on one pane instead: one property, and the tracks are untouched. */
@@ -95,32 +95,32 @@ html:has(.qm-workspace) {
95
95
  min-height: 0;
96
96
  }
97
97
 
98
- /* THE BAND THAT SWITCHES THEM, and nothing at the widths where both tracks are showing
98
+ /* The band that switches them, and nothing at the widths where both tracks are showing
99
99
  and there is nothing to switch. Where it stands is the host's, like any other band; what
100
100
  goes in it is a pair of `.qm-control`s, which already carry the on-state a pressed
101
- control takes. Its visibility is the PRESET's because the threshold is: a host hiding
101
+ control takes. Its visibility is the preset's because the threshold is: a host hiding
102
102
  its own tab row writes this file's number a second time, which is the one thing the
103
103
  single source is for. */
104
104
  .qm-switch {
105
105
  display: none;
106
106
  }
107
107
 
108
- /* ONE MOUNT AT A TIME under the threshold, rather than two of them abreast. Half a narrow
108
+ /* One mount at A time under the threshold, rather than two of them abreast. Half a narrow
109
109
  viewport is under the width either surface reads at, so the split stops being one and
110
110
  the tracks become views of the same room: the host says which with `data-qm-show`, and
111
- the attribute names the TRACK rather than what is in it, so nothing here knows an editor
111
+ the attribute names the track rather than what is in it, so nothing here knows an editor
112
112
  from a preview. No attribute is the first track.
113
113
 
114
114
  The other track is `display: none` and not a clip, which is the whole of the hiding: it
115
115
  leaves the tab order, hit-testing and the accessibility tree in one property, so the
116
- pane needs no `inert` and the host needs no breakpoint in JS. Both stay MOUNTED (a
116
+ pane needs no `inert` and the host needs no breakpoint in JS. Both stay mounted (a
117
117
  preview binds its handle once, an editor holds a caret, a history and a scroll), so
118
118
  the switch is presentational, never conditional. A pane hidden this way keeps the
119
119
  pixels it had (the paint loop's band sweep no-ops on an empty visible set) and repaints
120
120
  from its live box when it comes back, which its resize observer sees as a width moving
121
121
  off zero.
122
122
 
123
- HEIGHT is the second clause because a landscape phone passes the first one: it clears
123
+ Height is the second clause because a landscape phone passes the first one: it clears
124
124
  the width with room for two tracks and has no body left to put them in. A desktop window
125
125
  that short wants one mount for the same reason. */
126
126
  @media (width < 50rem), (height < 30rem) {
@@ -129,7 +129,7 @@ html:has(.qm-workspace) {
129
129
  gap: var(--qmh-space);
130
130
  }
131
131
 
132
- /* Even halves of the band, at the height a THUMB needs. The floor is the recipe's and
132
+ /* Even halves of the band, at the height a thumb needs. The floor is the recipe's and
133
133
  not the host's, because the band exists only at the sizes where the pointer is a
134
134
  finger: a host is free to stand the band deeper, and has nothing to gain from
135
135
  standing it shallower than the thing it is tapping. */
@@ -154,18 +154,18 @@ html:has(.qm-workspace) {
154
154
  }
155
155
  }
156
156
 
157
- /* THE MOUNTING SITE: an edge, a corner, and the clip that holds a surface to them, which
157
+ /* The mounting site: an edge, a corner, and the clip that holds a surface to them, which
158
158
  is all a surface painting its own column needs. No tone and no gutter: those are the
159
159
  surface's own (THEMING §"Drop it in"). `border-box`, so a stated height is the height
160
160
  it draws.
161
161
 
162
- POSITIONED, because a clip reaches only what it is the containing block for: a
162
+ Positioned, because a clip reaches only what it is the containing block for: a
163
163
  surface's out-of-flow parts (a parked description, an overlay) resolve against the
164
164
  nearest positioned ancestor, and with none between them and the document they land at
165
- their static position UNCLIPPED, leaving the page to scroll past its own foot by
165
+ their static position unclipped, leaving the page to scroll past its own foot by
166
166
  however far the frame's contents run over.
167
167
 
168
- The two minimums are what let a frame in a track CLIP rather than push: a grid or flex
168
+ The two minimums are what let a frame in a track clip rather than push: a grid or flex
169
169
  item floors at its content, so a mount that paints wider than its column widens the
170
170
  column instead. They ride the frame rather than the split's children, which keeps every
171
171
  rule in this file landing where the host put a class. Outside a track they are the
@@ -208,7 +208,7 @@ html:has(.qm-workspace) {
208
208
  }
209
209
 
210
210
  /* The block form: a dump, or a snippet. `pre` keeps the wrapping the value came with;
211
- the plate is the page's own, one rung under whatever it sits in. How TALL such a
211
+ the plate is the page's own, one rung under whatever it sits in. How tall such a
212
212
  block may grow before it scrolls is the host's policy rather than the look, so no
213
213
  height is stated here. */
214
214
  pre.qm-readout {
@@ -253,10 +253,12 @@ pre.qm-readout {
253
253
 
254
254
  /* ── Surfaces ──────────────────────────────────────────────────────────────── */
255
255
 
256
- /* The instrument plate: what a host puts its controls and readouts on. One rung off the
257
- page and a hairline, which is the same way a card steps off the base surface, so a
258
- panel beside a mounted editor reads as the same material. `border-box`, so a height
259
- from the caller is the height it draws. */
256
+ /* The instrument plate: what a host puts its controls and readouts on. The same plane a
257
+ card is, so a panel beside a mounted editor reads as the same material. It keeps a
258
+ hairline where a card drops one: a card sits in a column the surface itself paints and
259
+ a plate sits wherever the host put it, which is the floating case's argument on a
260
+ block that happens to be in flow. `border-box`, so a height from the caller is the
261
+ height it draws. */
260
262
  .qm-panel {
261
263
  box-sizing: border-box;
262
264
  background: var(--qmh-surface);
@@ -267,7 +269,7 @@ pre.qm-readout {
267
269
 
268
270
  /* ── Controls ──────────────────────────────────────────────────────────────── */
269
271
 
270
- /* A host's controls ARE boxed, where the package's buttons are not: inside a card a
272
+ /* A host's controls are boxed, where the package's buttons are not: inside a card a
271
273
  button sits beside typing and a box would read as a field, and out here there is no
272
274
  typing to be confused with, so the box is what says "this is a control".
273
275
  `font: inherit` first, since the shorthand resets whatever precedes it. */
@@ -309,7 +311,7 @@ pre.qm-readout {
309
311
  /* ── Focus ─────────────────────────────────────────────────────────────────── */
310
312
 
311
313
  /* One visible indicator for the whole host, since none of these controls draws a ring
312
- of its own. It reads the INK rung rather than a hue: the page is monochrome, and a
314
+ of its own. It reads the ink rung rather than a hue: the page is monochrome, and a
313
315
  focus ring is a position, not a destination. */
314
316
  :focus-visible {
315
317
  outline: var(--qmh-ring-width) solid var(--qmh-ink);