vantage-md 0.7.1 → 0.8.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/styles.css CHANGED
@@ -2,7 +2,8 @@
2
2
  *
3
3
  * Import this file to get the line-anchor highlight styles, the theme layer for
4
4
  * the `data-vantage-*` directive attributes, the chrome chips
5
- * (`FrontmatterDisplay`'s document status chip), and the task-list treatment.
5
+ * (`FrontmatterDisplay`'s document status chip), the task-list treatment, and
6
+ * the sizing for inline SVG a document writes.
6
7
  * Usage: import "vantage-md/styles";
7
8
  *
8
9
  * Both halves of the directive wiring are load-bearing. Without this re-export
@@ -16,3 +17,4 @@
16
17
  @import "./directives.css";
17
18
  /* After directives.css, which declares the tone palette this reads. */
18
19
  @import "./task-list.css";
20
+ @import "./inline-svg.css";
@@ -0,0 +1,157 @@
1
+ /* vantage-md/styles/task-list.css
2
+ *
3
+ * GFM task lists — `- [ ]` and `- [x]` — styled so the *status* of a checklist
4
+ * reads while scrolling past it, not only when you stop and look.
5
+ *
6
+ * Until this file existed they had no styling at all: `remark-gfm` emits
7
+ * `<input type="checkbox" disabled>` inside `li.task-list-item`, the sanitizer
8
+ * passes it, and the browser drew its default 13px square. A roadmap or an Open
9
+ * Questions checklist is one of the densest status surfaces a document has, and
10
+ * it was rendering as the least legible thing on the page.
11
+ *
12
+ * **The design goal is asymmetric on purpose: open items should be loud and done
13
+ * items should recede.** "What still needs me" is the question a reader brings
14
+ * to a checklist, so a done item is de-emphasized — nothing is hidden, and the
15
+ * text stays fully legible, but it stops competing. That is the same reasoning
16
+ * `emphasis=quiet` follows, and the same limit: quiet, never invisible.
17
+ *
18
+ * Like `directives.css` this file must stay UNLAYERED, and for the same reason:
19
+ * `@tailwindcss/typography`'s `prose` utilities sit in `@layer utilities`, and
20
+ * unlayered declarations outrank every layer regardless of specificity. That is
21
+ * the only thing letting these plain class selectors override the list styling
22
+ * typography applies in the app.
23
+ *
24
+ * It targets `.task-list-item` directly rather than `.prose` or
25
+ * `.vantage-prose`, because the two viewers use different container classes —
26
+ * Tailwind typography in the app, `.vantage-prose` for an external consumer of
27
+ * the package — and one selector has to reach both (D5).
28
+ *
29
+ * Colors come from the tone palette in `directives.css`, so a checklist and a
30
+ * `tone=tip` section agree about what "done" looks like and a new theme is still
31
+ * one custom-property block. It therefore depends on `directives.css` having
32
+ * been imported; `styles/index.css` imports both, in that order.
33
+ */
34
+
35
+ .contains-task-list {
36
+ /* The marker would sit beside the checkbox and say the same thing twice. */
37
+ list-style: none;
38
+ padding-left: 0;
39
+ }
40
+ /* Nested task lists keep an indent — losing it flattens the hierarchy the
41
+ author wrote, which for a roadmap is the difference between a sub-task and a
42
+ sibling. */
43
+ .contains-task-list .contains-task-list {
44
+ padding-left: 1.5em;
45
+ }
46
+
47
+ .task-list-item {
48
+ padding-left: 1.75em;
49
+ list-style: none;
50
+ }
51
+ /* `::marker` is suppressed explicitly as well as by `list-style`: Safari has
52
+ drawn one from the parent's computed value in the past, and a stray bullet
53
+ beside a checkbox is exactly the clutter this file exists to remove. */
54
+ .task-list-item::marker {
55
+ content: none;
56
+ }
57
+
58
+ /* ── The box ────────────────────────────────────────────────────────────── */
59
+ /* `appearance: none` and drawn by hand. The platform checkbox cannot be sized
60
+ or colored reliably across browsers, and — measured — renders at 13px
61
+ regardless of the surrounding font size, so it shrank to illegibility in a
62
+ nested list and looked wrong beside 16px text everywhere else.
63
+ It stays `disabled`, as `remark-gfm` emits it: a document is not a form, and a
64
+ clickable box that cannot persist anything is the "control that lies" D4
65
+ forbids. `cursor: default` says so rather than leaving the platform's
66
+ not-allowed cursor to imply a fault.
67
+
68
+ **Floated into the item's padding, never positioned absolutely.** An
69
+ absolutely positioned box is placed against its nearest positioned ancestor,
70
+ and a document decides which one that is: an item it writes with
71
+ `display: contents` generates no box, so it is no containing block. When
72
+ this box was `position: absolute` in a `position: relative` item, such an
73
+ item put its checkbox against an ancestor outside the scroll container, which
74
+ neither clips it nor scrolls it; with the item's `font-size` at 600px it was a
75
+ 630px square over the content pane that stayed put when the document
76
+ scrolled. A float stays in the scroll container whatever the item does. The
77
+ negative margin takes it into the padding, and its margin box then ends left
78
+ of the text, so the text does not wrap around it and the next item's
79
+ checkbox is not pushed aside by it. Out of the inline flow, it also leaves
80
+ the space GFM writes after it at the start of the line, where it collapses.
81
+ `position: relative` offsets nothing; it makes the box the containing block
82
+ of the tick below. `frontend/e2e/task_list.spec.ts` measures where the box
83
+ lands and that it stays in the scroll container. */
84
+ .task-list-item > input[type="checkbox"] {
85
+ appearance: none;
86
+ -webkit-appearance: none;
87
+ float: left;
88
+ position: relative;
89
+ /* The item's, so that the margin below, in this box's em, matches the
90
+ item's padding, in the item's. Tailwind's preflight already does this in
91
+ the app; a host without it left the box at the UA's 13.33px. */
92
+ font-size: inherit;
93
+ width: 1.05em;
94
+ height: 1.05em;
95
+ /* Optically centered on the first line rather than aligned to its top: the box
96
+ is square and the line box is not. */
97
+ margin: 0.2em 0 0 -1.75em;
98
+ border: 2px solid var(--vantage-tone-muted-accent);
99
+ border-radius: 4px;
100
+ background-color: transparent;
101
+ cursor: default;
102
+ flex-shrink: 0;
103
+ }
104
+
105
+ /* ── Done ───────────────────────────────────────────────────────────────── */
106
+ /* Filled, in the tip tone — the same green a `badge=done` chip and a
107
+ `tone=tip` section use. */
108
+ .task-list-item > input[type="checkbox"]:checked {
109
+ border-color: var(--vantage-tone-tip-accent);
110
+ background-color: var(--vantage-tone-tip-accent);
111
+ }
112
+ /* The tick is drawn as a rotated border pair rather than as a glyph, so it does
113
+ not depend on a font having the character and cannot be selected or copied as
114
+ text — a checkbox's state belongs to the input, not to the document's text. */
115
+ .task-list-item > input[type="checkbox"]:checked::after {
116
+ content: "";
117
+ position: absolute;
118
+ left: 0.22em;
119
+ top: 0.04em;
120
+ width: 0.3em;
121
+ height: 0.55em;
122
+ border: solid var(--vantage-task-tick, #fff);
123
+ border-width: 0 2px 2px 0;
124
+ transform: rotate(40deg);
125
+ }
126
+ /* The dark theme's tip accent is a *light* green, so a white tick on it is the
127
+ low-contrast pairing rather than the safe one. Invert: the tick has to read
128
+ against the fill in both themes, which is the whole job of a tick. */
129
+ .dark .task-list-item > input[type="checkbox"]:checked {
130
+ --vantage-task-tick: #052e16;
131
+ }
132
+ /* A done item recedes. `--vantage-task-done-fade` is a variable rather than a
133
+ literal so the one judgment call in this file is tunable in one place, and
134
+ 0.62 is deliberately further down than `emphasis=quiet`'s 0.88: a checklist
135
+ is scanned for what is left, and this text has already been read. */
136
+ .task-list-item:has(> input[type="checkbox"]:checked) {
137
+ opacity: var(--vantage-task-done-fade, 0.62);
138
+ }
139
+
140
+ /* ── Print ──────────────────────────────────────────────────────────────── */
141
+ /* The fade goes: on paper a faint line is a legibility loss with no scrolling
142
+ reader to serve, and the same restoration `emphasis=quiet` gets. The box
143
+ keeps its shape in monochrome, because *which* items are done is information
144
+ and must survive printing. #57606a is the gray the rest of the print block
145
+ uses. */
146
+ @media print {
147
+ .task-list-item:has(> input[type="checkbox"]:checked) {
148
+ opacity: 1;
149
+ }
150
+ .task-list-item > input[type="checkbox"] {
151
+ border-color: #57606a;
152
+ }
153
+ .task-list-item > input[type="checkbox"]:checked {
154
+ border-color: #57606a;
155
+ background-color: #57606a;
156
+ }
157
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vantage-md",
3
- "version": "0.7.1",
3
+ "version": "0.8.0",
4
4
  "description": "Markdown rendering pipeline with GitHub-style line anchors, mermaid diagrams, KaTeX math, and syntax highlighting",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",