@quillmark/svelte 0.1.1 → 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.
- package/README.md +16 -12
- package/THEMING.md +48 -25
- package/dist/core/address.d.ts +42 -7
- package/dist/core/address.js +49 -21
- package/dist/core/bloom.d.ts +5 -5
- package/dist/core/bloom.js +8 -8
- package/dist/core/codec/anchor.d.ts +1 -1
- package/dist/core/codec/anchor.js +1 -1
- package/dist/core/codec/atoms.d.ts +10 -0
- package/dist/core/codec/atoms.js +78 -0
- package/dist/core/codec/clipboard.d.ts +59 -0
- package/dist/core/codec/clipboard.js +202 -0
- package/dist/core/codec/code.d.ts +1 -1
- package/dist/core/codec/code.js +4 -4
- package/dist/core/codec/decode.d.ts +1 -1
- package/dist/core/codec/decode.js +8 -8
- package/dist/core/codec/encode.d.ts +4 -4
- package/dist/core/codec/encode.js +14 -11
- package/dist/core/codec/field.d.ts +22 -27
- package/dist/core/codec/field.js +33 -32
- package/dist/core/codec/index.js +5 -8
- package/dist/core/codec/inputrules.js +56 -18
- package/dist/core/codec/islands.d.ts +11 -7
- package/dist/core/codec/islands.js +16 -10
- package/dist/core/codec/keymap.d.ts +5 -6
- package/dist/core/codec/keymap.js +8 -7
- package/dist/core/codec/lists.d.ts +3 -3
- package/dist/core/codec/lists.js +32 -13
- package/dist/core/codec/marks.d.ts +1 -1
- package/dist/core/codec/marks.js +1 -1
- package/dist/core/codec/positions.js +1 -1
- package/dist/core/codec/prose.css +266 -228
- package/dist/core/codec/schema.js +4 -4
- package/dist/core/codec/slash.d.ts +39 -41
- package/dist/core/codec/slash.js +0 -0
- package/dist/core/codec/table-view.d.ts +12 -16
- package/dist/core/codec/table-view.js +488 -292
- package/dist/core/codec/table.d.ts +42 -15
- package/dist/core/codec/table.js +73 -27
- package/dist/core/errors.d.ts +17 -7
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +6 -5
- package/dist/core/lifecycle.d.ts +21 -5
- package/dist/core/lifecycle.js +34 -8
- package/dist/core/rebind.svelte.d.ts +18 -4
- package/dist/core/rebind.svelte.js +30 -12
- package/dist/core/teardown.d.ts +1 -1
- package/dist/core/teardown.js +1 -1
- package/dist/core/theme.css +173 -58
- package/dist/preset/index.css +1 -1
- package/dist/preset/recipes.css +79 -30
- package/dist/preset/scale.css +40 -28
- package/dist/preview/Preview.svelte +22 -19
- package/dist/preview/Preview.svelte.d.ts +8 -8
- package/dist/preview/bridge.d.ts +6 -4
- package/dist/preview/bridge.js +19 -9
- package/dist/preview/controller.d.ts +13 -6
- package/dist/preview/controller.js +8 -5
- package/dist/preview/geometry.d.ts +17 -2
- package/dist/preview/geometry.js +21 -1
- package/dist/preview/index.d.ts +1 -0
- package/dist/preview/index.js +9 -2
- package/dist/preview/overlay.d.ts +2 -1
- package/dist/preview/overlay.js +26 -11
- package/dist/preview/paint.js +19 -17
- package/dist/visual/ArrayField.svelte +103 -83
- package/dist/visual/ArrayField.svelte.d.ts +5 -4
- package/dist/visual/BooleanField.svelte +8 -6
- package/dist/visual/BooleanField.svelte.d.ts +2 -2
- package/dist/visual/Card.svelte +161 -333
- package/dist/visual/Card.svelte.d.ts +5 -4
- package/dist/visual/CardControls.svelte +1 -1
- package/dist/visual/DateField.svelte +19 -19
- package/dist/visual/DateField.svelte.d.ts +3 -3
- package/dist/visual/DiagnosticList.svelte +2 -2
- package/dist/visual/EnumField.svelte +48 -28
- package/dist/visual/EnumField.svelte.d.ts +5 -4
- package/dist/visual/Field.svelte +207 -132
- package/dist/visual/Field.svelte.d.ts +11 -7
- package/dist/visual/FieldHint.svelte +79 -48
- package/dist/visual/FieldHint.svelte.d.ts +1 -1
- package/dist/visual/FieldLabel.svelte +8 -8
- package/dist/visual/FormatPopover.svelte +82 -35
- package/dist/visual/NumberField.svelte +5 -5
- package/dist/visual/NumberField.svelte.d.ts +1 -1
- package/dist/visual/ObjectField.svelte +28 -9
- package/dist/visual/ObjectField.svelte.d.ts +4 -2
- package/dist/visual/ProseArrayElement.svelte +12 -19
- package/dist/visual/ProseArrayElement.svelte.d.ts +1 -2
- package/dist/visual/ProseField.svelte +62 -85
- package/dist/visual/ProseField.svelte.d.ts +14 -17
- package/dist/visual/SlashMenu.svelte +42 -16
- package/dist/visual/TextField.svelte +5 -5
- package/dist/visual/TextField.svelte.d.ts +1 -1
- package/dist/visual/TipsCard.svelte +43 -28
- package/dist/visual/VisualEditor.svelte +18 -19
- package/dist/visual/VisualEditor.svelte.d.ts +2 -3
- package/dist/visual/VisualEditorInner.svelte +251 -184
- package/dist/visual/VisualEditorInner.svelte.d.ts +2 -3
- package/dist/visual/controls.css +85 -38
- package/dist/visual/diagnostics.d.ts +13 -21
- package/dist/visual/diagnostics.js +7 -19
- package/dist/visual/domid.js +3 -3
- package/dist/visual/ext.d.ts +1 -1
- package/dist/visual/ext.js +1 -1
- package/dist/visual/icons/nodes.d.ts +3 -0
- package/dist/visual/icons/nodes.js +2 -1
- package/dist/visual/index.d.ts +1 -0
- package/dist/visual/index.js +10 -3
- package/dist/visual/leaves.d.ts +47 -0
- package/dist/visual/leaves.js +31 -0
- package/dist/visual/links.d.ts +24 -0
- package/dist/visual/links.js +67 -0
- package/dist/visual/props.d.ts +33 -12
- package/dist/visual/signals.d.ts +6 -6
- package/dist/visual/strings.d.ts +14 -19
- package/dist/visual/strings.js +5 -7
- package/dist/visual/structure.d.ts +24 -17
- package/dist/visual/structure.js +8 -8
- package/dist/visual/synced.svelte.d.ts +1 -1
- package/dist/visual/synced.svelte.js +4 -4
- package/dist/visual/tips.d.ts +4 -2
- package/dist/visual/tips.js +7 -4
- package/package.json +2 -2
package/dist/core/theme.css
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
84
|
-
|
|
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,33 +93,103 @@
|
|
|
89
93
|
--_qm-font-mono: var(--qm-font-mono, ui-monospace, monospace);
|
|
90
94
|
|
|
91
95
|
/* ── Colour ──────────────────────────────────────────────────────────────
|
|
92
|
-
|
|
93
|
-
the mid-tones and the label/meta/border rungs are
|
|
94
|
-
inverting the poles inverts the scale.
|
|
95
|
-
the light-mode literals they stand in
|
|
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
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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-
|
|
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
|
|
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
|
-
than a
|
|
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. */
|
|
110
153
|
--_qm-border-faint: color-mix(in oklab, var(--_qm-bg), var(--_qm-fg) 9%);
|
|
154
|
+
/* A fourth step between `label` and `ghost` is a number with no fourth kind of
|
|
155
|
+
text under it. */
|
|
111
156
|
--_qm-ink: var(--_qm-fg);
|
|
112
157
|
--_qm-ink-label: color-mix(in oklab, var(--_qm-fg), var(--_qm-bg) 35%);
|
|
113
|
-
--_qm-ink-meta: color-mix(in oklab, var(--_qm-fg), var(--_qm-bg) 45%);
|
|
114
158
|
--_qm-ink-ghost: color-mix(in oklab, var(--_qm-fg), var(--_qm-bg) 60%);
|
|
115
|
-
/* The correlation wash (`core/bloom.ts`). Its alpha is a
|
|
159
|
+
/* The correlation wash (`core/bloom.ts`). Its alpha is a peak, not a tint: the
|
|
116
160
|
wash animates from and back to zero, never held, so it reads at pane scale
|
|
117
161
|
over the preview's paper while the paper rests clean. */
|
|
118
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);
|
|
119
193
|
|
|
120
194
|
/* ── Ratios and effects ──────────────────────────────────────────────────
|
|
121
195
|
No palette fixes these, so they are their own rungs. There is no shadow
|
|
@@ -135,13 +209,18 @@
|
|
|
135
209
|
--_qm-opacity-muted: 0.5;
|
|
136
210
|
|
|
137
211
|
/* ── Focus ───────────────────────────────────────────────────────────────
|
|
138
|
-
These fix the ring's
|
|
212
|
+
These fix the ring's value, so no control mints it. Which properties draw a
|
|
139
213
|
ring, and on what state, is the other half: a rule, `.qm-focus-ring` in
|
|
140
214
|
`visual/controls.css`, since a rung each control reassembles is a scale
|
|
141
|
-
only up to the point where it is assembled.
|
|
215
|
+
only up to the point where it is assembled. One width: focus is the only
|
|
142
216
|
state that draws a ring anywhere, so there is no held-back tier under it. */
|
|
143
217
|
--_qm-ring-width: 2px;
|
|
144
|
-
|
|
218
|
+
/* Every ring the surface draws, whatever the state under it: focus and selection
|
|
219
|
+
alike, which is why the name carries neither. Assembled here because the parts
|
|
220
|
+
spelled out at a use site pass every axis — each reads a rung — while drawing a
|
|
221
|
+
ring nothing else agrees with. The width stays separately reachable: a drop
|
|
222
|
+
indicator is the ring's thickness without being a ring. */
|
|
223
|
+
--_qm-ring: var(--_qm-ring-width) solid var(--_qm-accent);
|
|
145
224
|
--_qm-ring-offset: 1px;
|
|
146
225
|
|
|
147
226
|
/* ── Motion ──────────────────────────────────────────────────────────────
|
|
@@ -154,15 +233,18 @@
|
|
|
154
233
|
animates over WAAPI and reads it from here. */
|
|
155
234
|
--_qm-bloom-dwell: 1100ms;
|
|
156
235
|
|
|
157
|
-
/* One curve
|
|
158
|
-
|
|
159
|
-
|
|
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. */
|
|
160
239
|
--_qm-ease-reverse: cubic-bezier(0.4, 0, 0.6, 1);
|
|
161
|
-
|
|
162
|
-
|
|
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);
|
|
163
245
|
|
|
164
246
|
/* ── Geometry ──────────────────────────────────────────────────────────*/
|
|
165
|
-
/*
|
|
247
|
+
/* One stroke width for every edge the chrome draws: a card's, a control's,
|
|
166
248
|
and the metadata bracket's three rules alike. A threshold rather than a
|
|
167
249
|
rhythm choice, like the tap floor: a hairline is a hairline at any
|
|
168
250
|
`--qm-space`, so it does not derive from a dial. It exists as a rung because
|
|
@@ -171,6 +253,9 @@
|
|
|
171
253
|
against a token. */
|
|
172
254
|
--_qm-border-width: 1px;
|
|
173
255
|
--_qm-radius: var(--qm-radius, 8px);
|
|
256
|
+
/* The interior corner, and half is the relationship rather than the number: a
|
|
257
|
+
corner inside a corner reads as nested only while it is visibly tighter, and
|
|
258
|
+
halving holds that at every setting of the dial, zero included. */
|
|
174
259
|
--_qm-radius-inner: calc(var(--_qm-radius) / 2);
|
|
175
260
|
/* A fully-rounded end cap: a shape tier, not a step on the radius ramp, so
|
|
176
261
|
it does not derive from the dial: a pill stays a pill at any radius. */
|
|
@@ -180,8 +265,15 @@
|
|
|
180
265
|
--_qm-space-2: calc(var(--_qm-space) * 2);
|
|
181
266
|
--_qm-space-3: calc(var(--_qm-space) * 3);
|
|
182
267
|
--_qm-space-4: calc(var(--_qm-space) * 4);
|
|
183
|
-
/*
|
|
184
|
-
|
|
268
|
+
/* A rung because the two axes are two decisions and the ladder alone cannot hold
|
|
269
|
+
them together: `check:style`'s rhythm axis sees each box read a rung, never that
|
|
270
|
+
they read the same one, which is the drift `visual/controls.css` already names
|
|
271
|
+
for the type half. Asymmetric because the vertical is what leading leaves once
|
|
272
|
+
it has taken the line box, and the horizontal is how far in the text starts,
|
|
273
|
+
which nothing else fixes. */
|
|
274
|
+
--_qm-inset-control: var(--_qm-space) var(--_qm-space-3);
|
|
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
|
|
185
277
|
rather than a step on the ramp, because what it answers is how far the eye
|
|
186
278
|
sits from the bottom of the screen, which no spacing dial knows. Spent by
|
|
187
279
|
the editor alone (`.qm-pane`): a stack of cards is what has a last one to
|
|
@@ -193,7 +285,7 @@
|
|
|
193
285
|
floor is one number instead of one expression per control. */
|
|
194
286
|
--_qm-tap-min: 24px;
|
|
195
287
|
/* The reorder/delete glyph. A rung because the card header's
|
|
196
|
-
right hang is
|
|
288
|
+
right hang is half the difference between this and the tap floor: the glyph
|
|
197
289
|
centres in a target sized by the floor, so what stands between it and the
|
|
198
290
|
card's gutter is an arithmetic of the two, and a literal on either side is a
|
|
199
291
|
balance that silently breaks when the glyph moves. Sized in CSS rather than
|
|
@@ -203,26 +295,49 @@
|
|
|
203
295
|
--_qm-glyph-control: 14px;
|
|
204
296
|
|
|
205
297
|
/* ── Type ────────────────────────────────────────────────────────────────
|
|
206
|
-
`--qm-font-size` anchors the
|
|
207
|
-
rungs: a step up (title) and
|
|
208
|
-
|
|
209
|
-
ratio, and a dial nobody turns is a name every reader still holds.
|
|
298
|
+
`--qm-font-size` anchors the chrome rung; 1.125 is the ratio between adjacent
|
|
299
|
+
rungs: a step up (title) and one down (label). The ratio and the
|
|
300
|
+
weight are fixed conventions, not dials: no consumer tunes a typographic
|
|
301
|
+
ratio, and a dial nobody turns is a name every reader still holds. Three chrome
|
|
302
|
+
rungs: a second step below `label` lands near 11px, under a size anything here
|
|
303
|
+
wants to be read at, and the supporting text that would take it is what `label`
|
|
304
|
+
already is. */
|
|
210
305
|
--_qm-text-body: var(--qm-font-size, 0.875rem);
|
|
211
306
|
--_qm-text-title: calc(var(--_qm-text-body) * 1.125);
|
|
212
307
|
--_qm-text-label: calc(var(--_qm-text-body) / 1.125);
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
308
|
+
/* Paper: the document body answers to the preview's paper where every other
|
|
309
|
+
surface here answers to the control beside it, so a rung shared with the chrome
|
|
310
|
+
makes a consumer asking for larger prose take larger inputs with it. 16/15 where
|
|
311
|
+
the ramp steps at 9/8: small enough to read as a change of register rather than
|
|
312
|
+
a rung of hierarchy, and clear of the title rung, which one 9/8 step lands on
|
|
313
|
+
exactly. */
|
|
314
|
+
--_qm-text-paper: calc(var(--_qm-text-body) * 16 / 15);
|
|
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;
|
|
216
332
|
/* Leading: the ramp's third axis, and it does not track the sizes one for one:
|
|
217
333
|
two rungs, because a wrapped label and a wrapped paragraph want different
|
|
218
334
|
rhythms and nothing wants four. `body` is reading rhythm (both prose leaves,
|
|
219
335
|
every control beside them, the tips card's guidance); `tight` is a line that is
|
|
220
|
-
a label rather than a passage. Unitless, so a rung inherits
|
|
336
|
+
a label rather than a passage. Unitless, so a rung inherits multiplicatively
|
|
221
337
|
and holds against whichever size rung the surface reads: a `rem` leading
|
|
222
|
-
would freeze at one size and disagree with the rest of the ramp.
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
size rung over it. `line-height: 1` is outside the axis: it collapses the
|
|
338
|
+
would freeze at one size and disagree with the rest of the ramp. It is the
|
|
339
|
+
axis paper and chrome share: both read `body`, and the size rung is what
|
|
340
|
+
separates them. `line-height: 1` is outside the axis: it collapses the
|
|
226
341
|
line box onto its content, a glyph or a button's one-line label. */
|
|
227
342
|
--_qm-leading-body: 1.5;
|
|
228
343
|
--_qm-leading-tight: 1.3;
|
|
@@ -235,12 +350,12 @@
|
|
|
235
350
|
picker, the caret) lands on the same pole the poles above resolve to.
|
|
236
351
|
Declaring it here would break that lockstep in the one direction that
|
|
237
352
|
matters: a host that declares `dark` would get light native chrome under
|
|
238
|
-
a dark surface. A consumer that
|
|
353
|
+
a dark surface. A consumer that pins a palette against its own scheme
|
|
239
354
|
declares `color-scheme` with it, on the root (THEMING.md).
|
|
240
355
|
|
|
241
|
-
Face, ink and
|
|
356
|
+
Face, ink and leading are the three axes a root carries this way. Leading
|
|
242
357
|
belongs with the other two because a unitless ratio inherits
|
|
243
|
-
|
|
358
|
+
multiplicatively: it holds against whatever size rung each surface reads, so
|
|
244
359
|
it imposes less than the ink beside it, and the reason `font-size` stays off
|
|
245
360
|
does not transfer: a ratio has no size to sweep a consumer's content with.
|
|
246
361
|
What it buys is that `normal` (the UA figure near 1.14, varying by font) is
|
|
@@ -248,13 +363,13 @@
|
|
|
248
363
|
whether or not it remembers to say so, and a per-surface
|
|
249
364
|
`--_qm-leading-tight` reads as the deliberate override it is.
|
|
250
365
|
|
|
251
|
-
Deliberately
|
|
366
|
+
Deliberately not `font-size`, and the reason is about the root rule rather
|
|
252
367
|
than about size: a root-level body size sweeps every descendant a consumer
|
|
253
368
|
may have put inside the marker, which is a reach the derivation does not
|
|
254
369
|
have. The rung is not withheld from the surfaces: every control and every
|
|
255
370
|
prose leaf reads `--_qm-text-body` in its own recipe, which is
|
|
256
371
|
what closes the ramp and makes `--qm-font-size` move an input. What would
|
|
257
|
-
break a mounted leaf is a size that
|
|
372
|
+
break a mounted leaf is a size that changes under it; a rung is fixed at
|
|
258
373
|
mount unless the consumer turns the dial, and a consumer turning a dial is
|
|
259
374
|
entitled to the reflow. So: the root imposes no size, each surface reads the
|
|
260
375
|
rung it wants. */
|
|
@@ -263,10 +378,10 @@
|
|
|
263
378
|
line-height: var(--_qm-leading-body);
|
|
264
379
|
}
|
|
265
380
|
|
|
266
|
-
/* Reduced motion collapses the
|
|
381
|
+
/* Reduced motion collapses the scale, never a list of selectors.
|
|
267
382
|
Two values here are not the rung they look like:
|
|
268
383
|
|
|
269
|
-
`1ms` rather than `none`, because a collapsed transition still
|
|
384
|
+
`1ms` rather than `none`, because a collapsed transition still fires: a surface
|
|
270
385
|
waiting on `transitionend` keeps its event, where `transition: none` would strand
|
|
271
386
|
it. The beat is under perception either way.
|
|
272
387
|
|
package/dist/preset/index.css
CHANGED
|
@@ -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
|
|
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. */
|
package/dist/preset/recipes.css
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
/*
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
71
|
-
the whole of it. What a band is made
|
|
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,18 +79,14 @@ html:has(.qm-workspace) {
|
|
|
79
79
|
gap: var(--qmh-space-2) var(--qmh-space-4);
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
/*
|
|
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
|
|
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
|
-
hairline on one pane instead: one property, and the tracks are untouched.
|
|
90
|
-
|
|
91
|
-
Below the width that fits two mounts abreast the split stops being one: the tracks
|
|
92
|
-
stack and each takes a pane's height. WHICH element scrolls then is the host's, since
|
|
93
|
-
it is the host that knows where the room comes from. */
|
|
89
|
+
hairline on one pane instead: one property, and the tracks are untouched. */
|
|
94
90
|
.qm-split {
|
|
95
91
|
display: grid;
|
|
96
92
|
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
|
@@ -99,26 +95,77 @@ html:has(.qm-workspace) {
|
|
|
99
95
|
min-height: 0;
|
|
100
96
|
}
|
|
101
97
|
|
|
102
|
-
|
|
98
|
+
/* The band that switches them, and nothing at the widths where both tracks are showing
|
|
99
|
+
and there is nothing to switch. Where it stands is the host's, like any other band; what
|
|
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
|
|
102
|
+
its own tab row writes this file's number a second time, which is the one thing the
|
|
103
|
+
single source is for. */
|
|
104
|
+
.qm-switch {
|
|
105
|
+
display: none;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* One mount at A time under the threshold, rather than two of them abreast. Half a narrow
|
|
109
|
+
viewport is under the width either surface reads at, so the split stops being one and
|
|
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
|
|
112
|
+
from a preview. No attribute is the first track.
|
|
113
|
+
|
|
114
|
+
The other track is `display: none` and not a clip, which is the whole of the hiding: it
|
|
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
|
|
117
|
+
preview binds its handle once, an editor holds a caret, a history and a scroll), so
|
|
118
|
+
the switch is presentational, never conditional. A pane hidden this way keeps the
|
|
119
|
+
pixels it had (the paint loop's band sweep no-ops on an empty visible set) and repaints
|
|
120
|
+
from its live box when it comes back, which its resize observer sees as a width moving
|
|
121
|
+
off zero.
|
|
122
|
+
|
|
123
|
+
Height is the second clause because a landscape phone passes the first one: it clears
|
|
124
|
+
the width with room for two tracks and has no body left to put them in. A desktop window
|
|
125
|
+
that short wants one mount for the same reason. */
|
|
126
|
+
@media (width < 50rem), (height < 30rem) {
|
|
127
|
+
.qm-switch {
|
|
128
|
+
display: flex;
|
|
129
|
+
gap: var(--qmh-space);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* Even halves of the band, at the height a thumb needs. The floor is the recipe's and
|
|
133
|
+
not the host's, because the band exists only at the sizes where the pointer is a
|
|
134
|
+
finger: a host is free to stand the band deeper, and has nothing to gain from
|
|
135
|
+
standing it shallower than the thing it is tapping. */
|
|
136
|
+
.qm-switch > * {
|
|
137
|
+
flex: 1 1 0;
|
|
138
|
+
min-height: var(--qmh-tap);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/* Centred, which is what a control filling half a band reads as; `.qm-control` itself
|
|
142
|
+
reads left, for the menus it also dresses. */
|
|
143
|
+
.qm-switch > .qm-control {
|
|
144
|
+
text-align: center;
|
|
145
|
+
}
|
|
146
|
+
|
|
103
147
|
.qm-split {
|
|
104
148
|
grid-template-columns: minmax(0, 1fr);
|
|
105
|
-
|
|
106
|
-
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.qm-split:not([data-qm-show='2']) > :nth-child(2),
|
|
152
|
+
.qm-split[data-qm-show='2'] > :nth-child(1) {
|
|
153
|
+
display: none;
|
|
107
154
|
}
|
|
108
155
|
}
|
|
109
156
|
|
|
110
|
-
/*
|
|
157
|
+
/* The mounting site: an edge, a corner, and the clip that holds a surface to them, which
|
|
111
158
|
is all a surface painting its own column needs. No tone and no gutter: those are the
|
|
112
159
|
surface's own (THEMING §"Drop it in"). `border-box`, so a stated height is the height
|
|
113
160
|
it draws.
|
|
114
161
|
|
|
115
|
-
|
|
162
|
+
Positioned, because a clip reaches only what it is the containing block for: a
|
|
116
163
|
surface's out-of-flow parts (a parked description, an overlay) resolve against the
|
|
117
164
|
nearest positioned ancestor, and with none between them and the document they land at
|
|
118
|
-
their static position
|
|
165
|
+
their static position unclipped, leaving the page to scroll past its own foot by
|
|
119
166
|
however far the frame's contents run over.
|
|
120
167
|
|
|
121
|
-
The two minimums are what let a frame in a track
|
|
168
|
+
The two minimums are what let a frame in a track clip rather than push: a grid or flex
|
|
122
169
|
item floors at its content, so a mount that paints wider than its column widens the
|
|
123
170
|
column instead. They ride the frame rather than the split's children, which keeps every
|
|
124
171
|
rule in this file landing where the host put a class. Outside a track they are the
|
|
@@ -161,7 +208,7 @@ html:has(.qm-workspace) {
|
|
|
161
208
|
}
|
|
162
209
|
|
|
163
210
|
/* The block form: a dump, or a snippet. `pre` keeps the wrapping the value came with;
|
|
164
|
-
the plate is the page's own, one rung under whatever it sits in. How
|
|
211
|
+
the plate is the page's own, one rung under whatever it sits in. How tall such a
|
|
165
212
|
block may grow before it scrolls is the host's policy rather than the look, so no
|
|
166
213
|
height is stated here. */
|
|
167
214
|
pre.qm-readout {
|
|
@@ -206,10 +253,12 @@ pre.qm-readout {
|
|
|
206
253
|
|
|
207
254
|
/* ── Surfaces ──────────────────────────────────────────────────────────────── */
|
|
208
255
|
|
|
209
|
-
/* The instrument plate: what a host puts its controls and readouts on.
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
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. */
|
|
213
262
|
.qm-panel {
|
|
214
263
|
box-sizing: border-box;
|
|
215
264
|
background: var(--qmh-surface);
|
|
@@ -220,7 +269,7 @@ pre.qm-readout {
|
|
|
220
269
|
|
|
221
270
|
/* ── Controls ──────────────────────────────────────────────────────────────── */
|
|
222
271
|
|
|
223
|
-
/* A host's controls
|
|
272
|
+
/* A host's controls are boxed, where the package's buttons are not: inside a card a
|
|
224
273
|
button sits beside typing and a box would read as a field, and out here there is no
|
|
225
274
|
typing to be confused with, so the box is what says "this is a control".
|
|
226
275
|
`font: inherit` first, since the shorthand resets whatever precedes it. */
|
|
@@ -262,7 +311,7 @@ pre.qm-readout {
|
|
|
262
311
|
/* ── Focus ─────────────────────────────────────────────────────────────────── */
|
|
263
312
|
|
|
264
313
|
/* One visible indicator for the whole host, since none of these controls draws a ring
|
|
265
|
-
of its own. It reads the
|
|
314
|
+
of its own. It reads the ink rung rather than a hue: the page is monochrome, and a
|
|
266
315
|
focus ring is a position, not a destination. */
|
|
267
316
|
:focus-visible {
|
|
268
317
|
outline: var(--qmh-ring-width) solid var(--qmh-ink);
|