Task tag marks¶
This guide is the authoritative display contract for task tag marks,
in the style of docs/date-marks.md. The JavaScript mirror lives in
bob-ledger-tools (src/138-task-tag-marks.js and
src/138-checklist-task-marks.js pure core plus
src/264-plugin-task-tag-marks.js Live Preview, rendered views, and
toggle); its tests run the conformance vectors below verbatim. There
is no api namespace (the top-level api stays v3; add one only
when a consumer exists).
What you see¶
#task is the Tasks global filter (globalFilter: "#task",
removeGlobalFilter: false), so about 3,400 task lines start with an
accent-colored #task tag pill. That pill repeats on almost every
line and adds the most visual noise. Every exact #task tag on a
task line renders as one small teal identity hash glyph instead:
before: - [ ] #task Rename the queue input โฎโฎโฎ + Sep 29 โง today
after: - [ ] โ Rename the queue input โฎโฎโฎ + Sep 29 โง today (โ โ the teal identity hash glyph)
- [ ] Pack charger (plain checklist: no glyph, unchanged)
dash.md Tasks results: - [ ] Rename the queue input โฎโฎโฎ + Sep 29 (tasks_results = hide: tag dropped)
Hovering the glyph shows #task ยท tracked task plus the demote hint.
Moving the cursor into the glyph, or clicking it, reveals #task
for editing.
Principles¶
Display-only: the text #task stays the only stored form, and
nothing writes the mark. Tasks, Dataview, bob-cli, and capture
semantics are unchanged. Small but distinct: it repeats on every
task line, so it uses no pill or resting background, and one
constant identity ink that never encodes state. It
is truthful, never guessing: a mark appears only on exact, whole
#task tags on task lines; anything else stays Obsidian's normal tag
pill. It is reversible: the cursor or a click reveals the raw tag,
source mode shows raw text, a session toggle restores the pills
instantly, and without the plugin the vault looks exactly as it does
today. There is one glyph definition, a CSS mask shared by every
host.
The glyph: a soft slanted hash¶
A Lucide-style hash keeps the tag affordance: you can see the tag is
still there and still editable. It is drawn thin, slanted, and
round-capped, so it reads as an icon rather than text. Geometry
(viewBox 0 0 16 16, stroked, used as a CSS mask, tunable ยฑ0.3
units): stroke-width 1.8, stroke-linecap round, path
M6.5 3 5.5 13M10.5 3 9.5 13M3.5 6.25h9M3.5 9.75h9. The glyph is
centered at (8, 8), with roughly square cells, and is about the
height of a text #. CSS custom properties, defined once on body:
--bob-task-tag-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round'%3E%3Cpath d='M6.5 3 5.5 13M10.5 3 9.5 13M3.5 6.25h9M3.5 9.75h9'/%3E%3C/svg%3E");
--bob-task-tag-hue: color-mix(in srgb, var(--color-cyan, #00bfbc) 72%, var(--text-normal));
Ink¶
The ink is one constant identity hue: a deep teal that means "tracked task" and nothing else. It never follows status, lane, priority, or freshness; that job stays with the checkbox and line tint. It never uses red, orange, yellow, green, or blue, and it stays legible on the red Blocked line tint.
| Hue | Already means |
|---|---|
| red | Blocked (line tint, blocked chips) |
| orange | attention: due freshness, ROTTEN, repair flags, the Pending chip |
| yellow | In Progress (line tint, the half-ring progress mark) |
| green | Next (line tint), fresh โ today |
| blue | the Ready lane |
| violet accent | tags (#prj, #gtd, โฆ) and links |
| cyan | inline code chips (--inline-code-hue: var(--color-cyan)) |
| grey | priority and date marks, cancelled |
Vault counts (2026-10-08): 3,406 #task lines, 2,934 closed, about
470 open โ mostly Blocked ([?], 383 lines) on the red tint, plus
Next ([*], 19), In Progress ([/], 7), and plain [ ] (63).
656 #task lines carry another tag pill, usually #prj in the
violet accent, beside the glyph.
The chosen teal blends theme cyan toward the text color so it adapts
to both themes: about #0a9391 in light (about 3.8:1 on white, above
the 3:1 non-text contrast floor) and a soft aqua of about #79dedc
in dark. Teal complements the red Blocked tint, so it is crispest
where most open #task glyphs sit, and it stands apart from the
violet #prj pill. It shares a hue family only with inline code, a
bordered monospace chip the glyph never reads as. Defined on body:
--bob-task-tag-hue: color-mix(in srgb, var(--color-cyan, #00bfbc) 72%, var(--text-normal));
The theme hook --bob-task-tag-color is unset by default and still
wins when set.
Anatomy and tones¶
There are two hosts with one shared rule set, both gated by
body.bob-task-tag-marks:
- Live Preview widget: an empty
span.bob-task-tag-markwithrole="img",aria-label, anddata-tooltip-position="top". - Rendered views: Obsidian's own
a.tagelement with the classbob-task-tag-markadded, plus the samearia-labelanddata-tooltip-position. The element is never replaced: its text#taskstays in the DOM for copy and screen readers, and its native click (tag search) keeps working.
The shared rules use family metrics: font-family:
var(--font-interface), font-size: 0.8em, display: inline-block,
position: relative, a content-box glyph area of 1.08em square,
padding 0.06em 0.14em, margin 0 0.08em, border: 0,
border-radius: 999px, background: none, text-decoration: none,
overflow: hidden, white-space: nowrap, color: transparent (this
hides the a.tag text), and vertical-align: -0.1em (tunable so the
hash sits on the text baseline like a #). Every theme tag-pill
property (--tag-* padding, background, border, color, weight, size)
is overridden with enough specificity
(body.bob-task-tag-marks a.tag.bob-task-tag-mark). The glyph is
drawn by ::before { content: ""; position: absolute; inset: 0.06em
0.14em; background-color: var(--bob-task-tag-ink); } with prefixed
and unprefixed mask-image: var(--bob-task-tag-glyph),
mask-size: contain, mask-repeat: no-repeat,
mask-position: center, plus print-color-adjust: exact (and the
-webkit- form) so PDF exports keep the glyph.
| Situation | Ink (--bob-task-tag-ink) |
Other |
|---|---|---|
| rest | var(--bob-task-tag-color, var(--bob-task-tag-hue)) |
opacity 0.9 |
| hover | var(--bob-task-tag-color, var(--bob-task-tag-hue)) |
opacity 1; capsule color-mix(in srgb, var(--bob-task-tag-ink) 14%, transparent) on both hosts (not currentColor: it is transparent here) |
resting: closed task (x, X, -) |
color-mix(in srgb, var(--bob-task-tag-color, var(--bob-task-tag-hue)) 40%, var(--text-faint)) |
opacity 0.75, derived from the nearest li.task-list-item[data-task] / .HyperMD-task-line[data-task] like the priority mark; wins on both hosts |
Cursor: default on the Live Preview widget (as in the family) and
pointer on the a.tag host (it is a link). Transitions (opacity,
background-color, 120ms) are off under prefers-reduced-motion.
The theme hook --bob-task-tag-color is unset by default. The ink
is constant: it names what the line is, never its state.
Tooltip¶
The text is exactly #task ยท tracked task followed by
Ctrl+Shift+] to demote to a bullet (lines joined with \n). It
never contains ::, because Dataview re-scans innerHTML. Exported
as the TASK_TAG_MARK_TOOLTIP constant. Ctrl+Shift+] is
task-status-cycler's toggle-obsidian-task hotkey, the existing
gesture that removes the checkbox and #task.
Eligibility¶
- Tag token: the exact, case-sensitive text
#task. The character before it is the start of the text or whitespace. The character after it is the end of the text or not a tag character (/[\p{L}\p{N}_\/-]/u). So#tasks,#task/sub,#Task,foo#task, and(#task)never match, while#task!does. - Live Preview: only on task lines, using
freshnessTaskStatus(line) !== null(quote-aware, so callouts and numbered lists count). Every eligible token on the line gets its own mark. A token is skipped whenfreshnessMarkPosInCode(tree, absFrom + 1)is true (inline code or a code block). Plain bullets (- #task โฆ), paragraphs, and headings are left alone: on a non-task line, the raw pill is the honest signal that Tasks ignores the line. - Rendered views: an
a.tagwhosetextContentis exactly#task(and whosehref, if present, is#task). Its nearestliancestor within the post-processor root must carrytask-list-item, so a nested plain child bullet under a task gets no mark, while a task nested under a plain bullet does. It must not sit undercode/preor inside a Tasks result row (.plugin-tasks-list-item,.tasks-list-text, or.task-description). With noliancestor (for example, a detached element), there is no mark.
Surfaces and interaction¶
- Live Preview: a
Prec.highestViewPlugin emits oneDecoration.replaceper eligible token, covering exactly the 5 characters of#task. There is no whitespace folding, so the spaces around the tag stay text. The mark is revealed (no decoration) while any selection range touches the tag inclusively (sel.from <= absTo && sel.to >= absFrom). As a result, the cursor never rests against a mark: typing#taskstays raw until you type the following space. The ledger snippet#task [created::โฆ](cursor between the two spaces) shows the glyph immediately. Mousedown places the cursor at the tag start and focuses the editor; it never writes. Widget equality uses a constant key, so marks never flicker. Rebuild on doc, viewport, or selection changes, Live Preview or file switches, and the newtaskTagMarksRefresheffect. A cheapline.text.indexOf("#task")prefilter runs before the task-line check. There are no marks in source mode. - Rendered views: a markdown post-processor (sort order 50)
annotates eligible
a.tagelements in place: it adds the class plusaria-labelanddata-tooltip-position, and never creates or removes nodes. It is idempotent, and attributes survive Dataview'sinnerHTMLround trip. It covers reading view, embeds, hover previews, canvas cards, and Dataview task lists. - Coexistence: ranges are disjoint from the freshness, priority, and date marks. The date mark's whitespace fold may start exactly at the tag's end (adjacent is fine, never overlapping). Vector TT16 asserts this.
Tasks query results¶
Tasks query results use CSS only, with no JS, and are keyed on the
selector
body.bob-task-tag-marks .plugin-tasks-list-item .task-description a.tag:is([data-tag-name="#task"], [href="#task"]).
Tasks 8.4.0 sets data-tag-name on description tags in
addInternalClasses. hide tags and re-renders keep working because
no JS touches Tasks' DOM. The JS post-processor never annotates these
rows (TR6). The body class makes the toggle instant.
Every row is a #task task by the global filter, so the tag carries
no information there and is hidden with display: none. The rule sits
after, and with higher specificity than, the shared host rules. The
description's leading space remains, giving a uniform gap on every
row (accepted).
Reference reading tasks¶
A task line whose exact #task tag is immediately followed by one
whitespace run and #ref (any case, so #REF and #Ref pair) is a
reference reading task: the pair renders as one open-book glyph in
the slot, in the same teal identity ink the hash uses. Shape says the
kind; ink still says "tracked task".
before: - [ ] #task #ref Harness Engineering
after: - [ ] ๐ Harness Engineering (๐ โ the teal open-book glyph)
One identity slot: #ref anywhere else (prose, headings, code,
non-task lines, #ref #task order, #task #references) never renders
the book. #task #references keeps the hash on #task; #ref #task
keeps the hash on #task; a lone #ref gets no mark.
The glyph is a 16ร16 stroked open-book mask in the hash's stroke
language (stroke-width 1.8, round caps and joins), defined once as
--bob-ref-task-glyph beside --bob-task-tag-glyph. Closed reading
tasks rest at the same 40 % mix toward --text-faint as closed hashes.
๐ already means "jump to this highlight" on annotation follow-ups,
which share the same ## Tasks lists, so the book keeps one symbol for
reading tasks. One symbol, one meaning.
Behavior matches the hash: the cursor or a click reveals both raw tags
(one touch anywhere on the pair exposes both, since the decoration
covers the whole span); the session toggle, keyboard access, and PDF
export behave as for #task. Hovering the book shows
#task #ref ยท reference reading task; its accessible label is
"Reference reading task".
Reading view turns the #task anchor into the book and hides the
adjacent #ref anchor in place (it stays in the DOM for copy and
Dataview's innerHTML round trip). In Tasks query results, where
#task already hides, the #ref pill renders as the book (CSS-only,
like the #task rule).
Pickers never show the pair: display text drops the #ref that follows
#task (as it drops #task) and reads ๐ Harness Engineering โ in
the task pickers, the Task Card header, and inbox-route subtitles. The
stored line keeps both tags, so Tasks, Dataview, bob query, and grep
keep working.
GTD checklist tasks¶
The canonical run #task #gtd #pre is one teal sunrise in the task
identity slot. #task #gtd #post is one teal flag. The partners may
appear in either order after #task; the single glyph replaces the
whole run, so its shape names the checklist lane while the shared teal
ink still means "tracked task."
before: - [?] #task #gtd #pre Brush teeth
after: - [?] โ Brush teeth (โ sunrise: PRE opens the review)
- [?] โ Morning review: chores done (โ flag: POST closes the review)
The two 16ร16 stroked masks use the hash/book geometry: no fill,
stroke-width: 1.8, round caps and joins. They are defined beside
--bob-ref-task-glyph as --bob-pre-task-glyph and
--bob-post-task-glyph. The sunrise path is
M1.4 12.2h13.2M3.8 12.2a4.2 4.2 0 0 1 8.4 0M8 3.9v2.4M2.13 6.33l1.7 1.7M13.87 6.33l-1.7 1.7;
the flag path is
M3.6 14.2V2.3M3.6 2.9h8.6l-2.1 3.2 2.1 3.2H3.6.
Both variants use the same theme-aware teal identity ink, hover capsule,
and sizing as the hash and book. The glyph does not encode status;
closed tasks (x, X, -) rest at the shared 40% mix toward
--text-faint with 0.75 opacity.
| Kind | Variant class | Accessible label | Tooltip |
|---|---|---|---|
| PRE | bob-pre-task-mark |
PRE opening checklist task |
#task #gtd #pre ยท PRE opening checklist / Opens the ]s walk ยท Ctrl+Enter when done |
| POST | bob-post-task-mark |
POST closing checklist task |
#task #gtd #post ยท POST closing checklist / Closes the ]s walk (]S) ยท Ctrl+Enter when done |
Eligibility is deliberately narrow. On a real task line, the exact
#task token must be followed in the identity slot by one whitespace
run, the exact whole-token tags #gtd and #pre or #post in either
order, and one whitespace run between them. Matching is
case-insensitive for partner tags. A line containing both #pre and
#post anywhere keeps its pills as a conflict signal. The existing
#task #ref pair takes precedence. Tags elsewhere in the title, a
missing partner, #prep, #gtd/pre, a non-task line, or code keep the
native pills.
Live Preview replaces the full run with one stable widget; touching any
part of it reveals all three raw tags for editing. Reading view annotates
the #task anchor and hides both partner anchors in place, preserving
copy, re-scans, and the toggle. Tasks query rows use CSS only: the
sunrise or flag appears when the description has the matching #gtd
pair, and the redundant #gtd pill is hidden. Rows with both #pre
and #post remain native.
CSS cannot enforce that the partner tags occupy the identity slot, because sibling combinators ignore text nodes. The Tasks-row rule may therefore draw on a misplaced but otherwise matching pair; the vault's rows are canonical. No JavaScript touches Tasks' DOM.
The Today ๐
follows the complete checklist identity run, so it stays
between the glyph and the title. The existing task-tag-marks toggle
restores the three source pills everywhere. Pickers, notices, the review
footer, CLI/TUI, bob query, and Bob Mac Capture are unchanged.
Toggle and lifecycle¶
The command "Toggle task tag marks" (id toggle-task-tag-marks) is
session-only and on by default. It flips
this.taskTagMarksEnabled and body.bob-task-tag-marks, dispatches
the refresh effect to every markdown editor, and shows the Notice
Task tag marks on / Task tag marks off. Toggling off also
strips the class, aria-label, and data-tooltip-position from
every annotated a.tag.bob-task-tag-mark in the document, so pills
look and behave natively at once. Toggling on re-annotates every
eligible a.tag in document.body using the same eligibility
function, so rendered views update without a re-render. Because Tasks
results are CSS-only, the body class handles them instantly.
onunload removes the body class and strips the annotations. When
off, JS creates no marks.
Rejected alternatives¶
- Hide
#taskentirely everywhere: this erases the tracked-versus-plain distinction for about 17,800 plain checkboxes and leaves invisible text under the cursor. - Change the global filter or storage: this rewrites about 3,400
lines and breaks the bob-cli parsers, capture, Tasks, and the
plugins that match
#task. - Tasks
removeGlobalFilter: true: this is a vault-wide Tasks setting with edit-modal side effects, and it is not toggleable or owned here. - A CSS-only
.cm-activeline reveal: everyj/kstep would reveal the tag on the new line, shifting every title by about 1.5em. - A dot or bullet: it reads as a nested bullet. A check icon
is redundant with the checkbox and clashes with done. A filled
tag silhouette turns into a blob at 0.8em. Lucide
list-todois too busy. - Ink: faint grey (the 1.35.0 ink) is lost beside the grey
priority and date marks and near-invisible on closed lines;
status hues and blue would claim a state or the Ready lane;
orange means attention and repair; pink and orchid turn muddy on
the Blocked tint and read as a near-miss beside violet pills;
the theme tag accent makes the mark read as one more tag pill
beside
#prj. - Replacing
a.tagwith a new span in rendered views: this loses native tag search, copy text, and robustness to re-renders. - A glyph in Tasks results: it would be a column of identical glyphs that carries zero information.
- An api namespace with no consumer: rejected. Pickers, the Task
Card, and notices already strip
#task.
Non-goals: storage, Rust CLI and TUI, bob query, Bob Mac Capture,
the Obsidian search and backlinks panes, the tag pane, source mode,
Mod+click tag search from Live Preview, and repair flags (tags have no
malformed canonical form).
Conformance vectors¶
Live Preview core: taskTagMarkRanges(lineText) returns
[{ from, to, kind }] in UTF-16 line offsets, where kind is task | ref
| pre | post. A ref range spans #task #ref; pre and post ranges
span the whole three-tag checklist identity run.
| # | Input | Expected |
|---|---|---|
| TT1 | - [ ] #task Buy milk |
[6,11) |
| TT2 | - [x] #task Report [completion:: 2026-10-05] |
[6,11) (resting tone is CSS) |
| TT3 | - [?] #task #gtd #context/home Check weather |
[6,11) only; other tags untouched |
| TT4 | > - [ ] #task Quoted |
[8,13) (quote-aware) |
| TT5 | 1. [ ] #task Numbered |
[7,12) |
| TT6 | - [x] (1645-1710) #task #sase Research |
[18,23) (mid-line tag) |
| TT7 | - [ ] Pack charger |
none (plain checklist) |
| TT8 | - #task Launch epic! |
none (not a task line) |
| TT9 | - [ ] #tasks a / - [ ] #task/sub a / - [ ] #Task a |
none |
| TT10 | - [ ] Note `the #task tag` here |
none in Live Preview: the core returns [16,21), and the inline-code check drops it |
| TT11 | - [ ] foo#task |
none |
| TT12 | - [ ] #task! Ship it |
[6,11) |
| TT13 | - [ ] #task [created::2026-10-07], cursor 12 |
mark [6,11) shown (cursor is not touching) |
| TT14 | - [ ] #task Buy milk, cursor 5 / 6 / 11 / selection 0โ20 |
shown / revealed / revealed / revealed |
| TT15 | - [ ] #task A #task B |
[6,11) and [14,19) |
| TT16 | - [ ] #task A [priority:: high] [created:: 2026-10-07] |
[6,11), disjoint from the priority and date mark ranges |
| TT17 | Paragraph #task text |
none |
| TT18 | - [ ] #task |
[6,11) (the tag ends the line) |
| TT19 | - [ ] (#task) parens |
none (conservative boundary) |
| TT20 | - [ ] #task #ref Harness Engineering |
[{[6,16), ref}] (one range covering both tokens) |
| TT21 | - [x] #task #ref Done book [completion:: 2026-10-05] |
[{[6,16), ref}] (resting tone is CSS) |
| TT22 | - [ ] #task #REF Loud |
[{[6,16), ref}] (case-insensitive partner) |
| TT23 | - [ ] #task #ref Extra spaces |
[{[6,18), ref}] (extra whitespace still pairs) |
| TT24 | - [ ] #task #references Not a ref |
[{[6,11), task}] (hash only) |
| TT25 | - [ ] #ref #task Reversed |
[{[11,16), task}] (hash only on #task) |
| TT26 | - [ ] #ref Alone |
none (#ref alone) |
| TT27 | - #task #ref Not a task |
none (not a task line) |
| TT28 | - [ ] Note `the #task #ref pair` here |
none in Live Preview: the core returns [{[16,26), ref}], and the inline-code check drops it |
PRE/POST checklist marks:
| # | Input | Expected |
|---|---|---|
| CK1 | - [ ] #task #gtd #pre Brush teeth |
[{[6,21), pre}] |
| CK2 | - [?] #task #gtd #post Morning review |
[{[6,22), post}] |
| CK3 | - [x] #task #gtd #pre Check weather [completion:: 2026-10-21] |
[{[6,21), pre}] (resting tone is CSS) |
| CK4 | - [ ] #task #pre #gtd Swapped |
[{[6,21), pre}] |
| CK5 | - [ ] #task #GTD #Pre Loud |
[{[6,21), pre}] |
| CK6 | - [ ] #task #gtd #post Extra spaces |
[{[6,25), post}] |
| CK7 | - [ ] #task #gtd #pre #post Conflict / - [ ] #task #gtd #pre Brush #post |
[{[6,11), task}]; pills stay |
| CK8 | - [ ] #task #gtd Topic only / - [ ] #task #pre Missing gtd |
[{[6,11), task}] |
| CK9 | - [ ] #task #gtd #prep Typo / - [ ] #task #gtd/pre Nested |
[{[6,11), task}] |
| CK10 | - [ ] #task Brush teeth #gtd #pre |
[{[6,11), task}] (not in the slot) |
| CK11 | - [ ] #task #ref #gtd #pre Odd |
[{[6,16), ref}] (the ref pair wins) |
| CK12 | - #task #gtd #pre Not a task / - [ ] Note `#task #gtd #pre` |
none / none in Live Preview (code) |
| CK13 | - [ ] #task #gtd #pre Brush teeth ^teeth, Today-linked |
๐ widget at offset 22 |
| CK14 | checklistKindForText on #gtd #pre / #GTD #Post / #gtd #pre #post / #gtd/pre / #pre, #gtd |
pre / post / pre / null / pre |
Rendered views (fake DOM in tests):
| # | DOM | Expected |
|---|---|---|
| TR1 | li.task-list-item > a.tag[href="#task"] with text #task |
annotated (class, tooltip aria-label, data-tooltip-position="top") |
| TR2 | li.task-list-item > p > a.tag (loose list) |
annotated |
| TR3 | task li > ul > plain li > a.tag #task |
not annotated |
| TR4 | plain li > ul > li.task-list-item > a.tag #task |
annotated |
| TR5 | a.tag text #Task / #tasks |
not annotated |
| TR6 | a.tag inside .plugin-tasks-list-item .task-description |
not annotated (Tasks rows are CSS-only) |
| TR7 | detached root, no li ancestor |
not annotated |
| TR8 | a second pass over TR1 | no change (idempotent) |
| TR9 | marks off / toggle off / toggle on | nothing annotated / annotations stripped document-wide / eligible tags re-annotated |
| TR10 | task li with #task + adjacent #ref anchors |
#task annotated with the book (reference label and tooltip); #ref hidden in place |
| TR11 | #task + #references anchors, or #ref before #task |
hash only on #task |
| TR12 | #ref anchor inside .plugin-tasks-list-item .task-description |
not annotated (Tasks rows are CSS-only: the #ref pill renders the book) |
| TR13 | pair present / toggle off / toggle on | book plus hidden #ref / book stripped and #ref revealed document-wide / pair re-annotated |
| CR1 | task li with adjacent #task #gtd #pre anchors |
#task has sunrise class, label, and tooltip; #gtd and #pre stay hidden in place |
| CR2 | #task #gtd #pre #post, or #task + #gtd + a word + #pre |
hash only; every pill stays visible |
| CR3 | checklist pair present / toggle off / toggle on | variants, labels, and hidden classes stripped document-wide / then re-annotated |
| CR4 | Today reading view on a CR1 row | ๐
inserted after the hidden #pre anchor and before the title |
| CR5 | Tasks row with #gtd + #post / with #pre + #post |
flag drawn and #gtd hidden / every pill stays native |
Live verification (Bryan, in Obsidian)¶
- The teal ink reads clearly yet stays secondary to the title in light and dark themes.
- The ink stays legible on Blocked (red tint), Next (green tint),
and In Progress (yellow tint) lines, and sits well beside a
#prjpill. - The hover capsule appears in both Live Preview and reading view.
- Plain checkboxes show no glyph.
- The cursor or a click reveals
#task, and typing#taskstays raw until the space. - The ledger
tatask snippet shows the glyph at once. - Vim
j/kthrough a task list does not jitter unless the column is inside the tag. - Reading view, embeds, and hover previews show the glyph, and
clicking it opens the
#tasktag search. dash.mdTasks results show no tag.- The toggle restores pills everywhere and back again.
- Closed tasks show a faint ghost of the hue (reading view and Live Preview).
- The glyph sits cleanly with the priority, date, and fresh marks on one line.
- Mobile (iOS) renders it.
- PDF export shows the glyph.
- On red Blocked
[?]rows, sunrise and flag are distinct in light and dark themes and on iOS. ]skeeps the glyph on the landing row, and ๐ follows it on Today-linked PRE rows.- Touching the checklist glyph reveals all three tags; typing stays raw.
- Tasks query rows show the matching CSS glyph, while a hand-typed
#pre #postconflict keeps all its pills.