lumargh_better-bujo/styles.css

333 lines
15 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Better Bujo — bullet-journal markers in place of Obsidian's checkboxes.
*
* Canonical glyph table (keyed on the `data-task` attribute Obsidian sets on
* each list item, in both Reading mode and Live Preview):
*
* - [ ] open task → • (a bullet point)
* - [x] done → (text stays normal; optional strike
* via the bb-strike-done body class)
* - [>] migrated (month) → >
* - [<] future log → <
* - [o] event → ○ (click toggles o ↔ O)
* - [O] event done → ● (same size as ○; click toggles back)
* - [-] cancelled → •, marker and whole line struck through, faint
* - … plain list item → (en dash, not a bullet)
* ~ … emotion/thought → styled line (the `~` glyph stays as typed)
*
* Strategy: never remove Obsidian's native marker elements — restyle them in
* place. The checkbox <input> keeps its box (which Obsidian and themes already
* position correctly in both modes) and the glyph is drawn on its ::after,
* replacing the default checkmark mask. Likewise the plain-bullet dot lives on
* `.list-bullet::after` in BOTH modes, so one rule turns it into a dash. This
* way alignment is inherited from whatever theme is active, with no hand-tuned
* offsets.
*
* Every rule is scoped under `.better-bujo` (added to each window's <body> on
* load) so disabling the plugin restores Obsidian's native rendering. */
.better-bujo {
--bb-marker-color: var(--text-muted);
--bb-event-color: var(--text-accent);
--bb-done-color: var(--text-faint);
/* Marker column geometry in Live Preview, expressed in checkbox-size units
so it is independent of font sizes: lead = space before the marker box,
gap = space between marker box and text. Values match Obsidian's default
metrics at the default font size. */
--bb-marker-lead: calc(var(--checkbox-size) * 0.45);
--bb-marker-gap: calc(var(--checkbox-size) * 0.22);
}
/* Normalize the checkbox's lead-in/gap under one ruler. Obsidian's native
chain mixes em units that resolve against different font sizes (the label's
-0.25em uses the editor font, the input's 0.85em its own UI font), which
makes it impossible for other marker types to reproduce — so plain bullets
and emotion markers below reuse these same variables instead. */
.better-bujo .markdown-source-view.mod-cm6 .task-list-label {
margin-inline-start: 0;
}
.better-bujo .markdown-source-view.mod-cm6 .task-list-label .task-list-item-checkbox {
margin-inline-start: var(--bb-marker-lead);
margin-inline-end: var(--bb-marker-gap);
}
/* ===========================================================================
* Task / event markers — restyle the native checkbox into a glyph.
*
* The <input> stays in the layout (its box is what themes align), but its
* chrome is stripped in every state: Obsidian's defaults give it a border,
* an accent background when :checked, and a checkmark mask on :checked::after.
* ======================================================================== */
.better-bujo input.task-list-item-checkbox,
.better-bujo input.task-list-item-checkbox:checked,
.better-bujo input.task-list-item-checkbox:hover,
.better-bujo input.task-list-item-checkbox:active,
.better-bujo input.task-list-item-checkbox:focus {
-webkit-appearance: none;
appearance: none;
border: none;
box-shadow: none;
background-color: transparent;
filter: none;
/* Some themes (e.g. Minimal) restyle alternative checkboxes themselves:
they mask the input and rotate it (Minimal turns [>] into a via
rotate(90deg)). Neutralize so the glyph on ::after renders as typed. */
transform: none;
-webkit-mask-image: none;
mask-image: none;
}
/* The glyph. Absolutely positioned over the checkbox box and centered, so a
glyph larger than the box overflows symmetrically without shifting any
text. `content` below is the open-task default; data-task rules swap it. */
.better-bujo input.task-list-item-checkbox::after {
content: "\2022"; /* • — open task, the default for any unrecognised marker */
position: absolute;
inset: 0;
width: auto;
height: auto;
display: flex;
align-items: center;
justify-content: center;
background-color: transparent;
-webkit-mask-image: none;
mask-image: none;
color: var(--bb-marker-color);
font-family: var(--font-text);
font-size: var(--checkbox-size);
line-height: 1;
}
/* Glyphs per marker. `data-task` lives on the <li> in Reading mode (the
checkbox is its direct child, or inside a <p> in loose lists) and on the
line div in Live Preview. Child combinators in Reading mode keep nested
list items from inheriting their parent's marker. */
/* — drawn as two crossing diagonals (like the event circles) instead of a
font glyph, so it is dead-centered in the marker box in every font/theme.
Size and stroke derive from --checkbox-size. */
.better-bujo li[data-task="x"] > input.task-list-item-checkbox::after,
.better-bujo li[data-task="x"] > p > input.task-list-item-checkbox::after,
.better-bujo .HyperMD-task-line[data-task="x"] input.task-list-item-checkbox::after,
.better-bujo li[data-task="X"] > input.task-list-item-checkbox::after,
.better-bujo li[data-task="X"] > p > input.task-list-item-checkbox::after,
.better-bujo .HyperMD-task-line[data-task="X"] input.task-list-item-checkbox::after {
--bb-x-stroke: max(1.5px, calc(var(--checkbox-size) * 0.09));
content: "";
margin: 0.045em 0 0 0.17em;
font-size: 1.5em;
width: calc(var(--checkbox-size) * 0.55);
height: calc(var(--checkbox-size) * 0.55);
/* background:
linear-gradient(45deg,
transparent calc(50% - var(--bb-x-stroke) / 2),
var(--bb-marker-color) 0,
var(--bb-marker-color) calc(50% + var(--bb-x-stroke) / 2),
transparent 0),
linear-gradient(-45deg,
transparent calc(50% - var(--bb-x-stroke) / 2),
var(--bb-marker-color) 0,
var(--bb-marker-color) calc(50% + var(--bb-x-stroke) / 2),
transparent 0); */
}
/* Done tasks read like any other line: undo Obsidian's native fade and
strikethrough. The strike comes back when the user enables it in settings
(the plugin then adds bb-strike-done next to better-bujo on <body>). */
.better-bujo .markdown-rendered ul > li.task-list-item[data-task="x"],
.better-bujo .markdown-rendered ul > li.task-list-item[data-task="X"],
.better-bujo .markdown-source-view.mod-cm6 .HyperMD-task-line[data-task="x"],
.better-bujo .markdown-source-view.mod-cm6 .HyperMD-task-line[data-task="X"] {
text-decoration: none;
color: inherit;
}
.better-bujo.bb-strike-done .markdown-rendered ul > li.task-list-item[data-task="x"],
.better-bujo.bb-strike-done .markdown-rendered ul > li.task-list-item[data-task="X"],
.better-bujo.bb-strike-done .markdown-source-view.mod-cm6 .HyperMD-task-line[data-task="x"],
.better-bujo.bb-strike-done .markdown-source-view.mod-cm6 .HyperMD-task-line[data-task="X"] {
text-decoration: line-through;
}
.better-bujo li[data-task=">"] > input.task-list-item-checkbox::after,
.better-bujo li[data-task=">"] > p > input.task-list-item-checkbox::after,
.better-bujo .HyperMD-task-line[data-task=">"] input.task-list-item-checkbox::after {
content: ">";
font-size: 1em;
font-weight: 500;
margin-top: 0.05em;
}
.better-bujo li[data-task="<"] > input.task-list-item-checkbox::after,
.better-bujo li[data-task="<"] > p > input.task-list-item-checkbox::after,
.better-bujo .HyperMD-task-line[data-task="<"] input.task-list-item-checkbox::after {
content: "<";
font-size: 1em;
font-weight: 500;
margin-bottom: 0.05em;
}
/* Events (o / O) — drawn as a CSS circle rather than font glyphs (○ ● from a
font come from whatever fallback has them, so their sizes can differ). The
circle lives on ::before: open is the outline, done the same circle filled.
All dimensions derive from --checkbox-size, so the pair is always equal. */
.better-bujo li[data-task="o"] > input.task-list-item-checkbox::before,
.better-bujo li[data-task="o"] > p > input.task-list-item-checkbox::before,
.better-bujo .HyperMD-task-line[data-task="o"] input.task-list-item-checkbox::before,
.better-bujo li[data-task="O"] > input.task-list-item-checkbox::before,
.better-bujo li[data-task="O"] > p > input.task-list-item-checkbox::before,
.better-bujo .HyperMD-task-line[data-task="O"] input.task-list-item-checkbox::before {
content: "";
position: absolute;
inset: 0;
margin: 0.4em 0 0 0.3em;
box-sizing: border-box;
width: calc(var(--checkbox-size) * 0.5);
height: calc(var(--checkbox-size) * 0.5);
border: max(1px, calc(var(--checkbox-size) * 0.08)) solid var(--bb-marker-color);
border-radius: 50%;
}
/* No inner symbol for either event state — blank out the default •. */
.better-bujo li[data-task="o"] > input.task-list-item-checkbox::after,
.better-bujo li[data-task="o"] > p > input.task-list-item-checkbox::after,
.better-bujo .HyperMD-task-line[data-task="o"] input.task-list-item-checkbox::after,
.better-bujo li[data-task="O"] > input.task-list-item-checkbox::after,
.better-bujo li[data-task="O"] > p > input.task-list-item-checkbox::after,
.better-bujo .HyperMD-task-line[data-task="O"] input.task-list-item-checkbox::after {
content: "";
}
/* ● — completed event: the same circle, filled. */
.better-bujo li[data-task="O"] > input.task-list-item-checkbox::before,
.better-bujo li[data-task="O"] > p > input.task-list-item-checkbox::before,
.better-bujo .HyperMD-task-line[data-task="O"] input.task-list-item-checkbox::before {
background-color: var(--bb-marker-color);
}
.better-bujo li[data-task="~"] > input.task-list-item-checkbox::after,
.better-bujo li[data-task="~"] > p > input.task-list-item-checkbox::after,
.better-bujo .HyperMD-task-line[data-task="~"] input.task-list-item-checkbox::after {
content: "~";
}
/* Cancelled tasks: the whole line is struck through and faint, like crossing
out an irrelevant task on paper. Mirrors Obsidian's native done styling,
which targets these same elements. The marker's ::after is absolutely
positioned, so the line's text-decoration doesn't propagate into it — the
strike on the • is applied explicitly below. */
.better-bujo .markdown-rendered li[data-task="-"],
.better-bujo .markdown-source-view.mod-cm6 .HyperMD-task-line[data-task="-"] {
text-decoration: line-through;
color: var(--bb-done-color);
}
.better-bujo li[data-task="-"] > input.task-list-item-checkbox::after,
.better-bujo li[data-task="-"] > p > input.task-list-item-checkbox::after,
.better-bujo .HyperMD-task-line[data-task="-"] input.task-list-item-checkbox::after {
text-decoration: line-through;
color: var(--bb-done-color);
}
/* Non-standard markers (>, <, ~, -) are not a checkbox state, so clicking
them shouldn't toggle anything. In Live Preview the click is forwarded by
the <label>; in Reading mode the <input> itself is the target. The standard
open/done pair ([ ] ↔ [x]) stays clickable in both modes, and events
(o / O) stay clickable too — the plugin toggles them o ↔ O. */
.better-bujo .markdown-source-view.mod-cm6 .HyperMD-task-line[data-task=">"] .task-list-label,
.better-bujo .markdown-source-view.mod-cm6 .HyperMD-task-line[data-task="<"] .task-list-label,
.better-bujo .markdown-source-view.mod-cm6 .HyperMD-task-line[data-task="~"] .task-list-label,
.better-bujo .markdown-source-view.mod-cm6 .HyperMD-task-line[data-task="-"] .task-list-label,
.better-bujo .markdown-rendered li[data-task=">"] > input.task-list-item-checkbox,
.better-bujo .markdown-rendered li[data-task="<"] > input.task-list-item-checkbox,
.better-bujo .markdown-rendered li[data-task="~"] > input.task-list-item-checkbox,
.better-bujo .markdown-rendered li[data-task="-"] > input.task-list-item-checkbox {
pointer-events: none;
}
/* Event markers toggle on click — show it. */
.better-bujo .markdown-source-view.mod-cm6 .HyperMD-task-line[data-task="o"] input.task-list-item-checkbox,
.better-bujo .markdown-source-view.mod-cm6 .HyperMD-task-line[data-task="O"] input.task-list-item-checkbox,
.better-bujo .markdown-rendered li[data-task="o"] > input.task-list-item-checkbox,
.better-bujo .markdown-rendered li[data-task="O"] > input.task-list-item-checkbox,
.better-bujo .markdown-rendered li[data-task="o"] > p > input.task-list-item-checkbox,
.better-bujo .markdown-rendered li[data-task="O"] > p > input.task-list-item-checkbox {
cursor: var(--cursor-link);
}
/* ===========================================================================
* Plain "- " list items → en dash instead of a bullet.
*
* In both modes Obsidian draws the bullet dot on `.list-bullet::after`
* (absolutely positioned and centered inside the span; the dot itself is
* `background-color` + `border-radius` on a 0.3em box). Swapping the dot for
* an en dash inside that same box inherits the theme's bullet position
* exactly. The span's own text (the typed `-` in Live Preview) stays hidden
* by Obsidian's `color: transparent`, which we leave alone.
*
* Live Preview is scoped to non-task lines so the dash never bleeds onto the
* raw `- [x]` text of an active task line; Reading-mode task bullets are
* already `display: none` natively.
* ======================================================================== */
.better-bujo .markdown-rendered .list-bullet::after,
.better-bujo .markdown-source-view.mod-cm6 .HyperMD-list-line:not(.HyperMD-task-line) .list-bullet::after {
content: "\2013"; /* */
width: auto;
height: auto;
border: none;
border-radius: 0;
background-color: transparent;
transform: none;
color: var(--bb-marker-color);
line-height: 1;
}
/* Align plain-item text with task text in Live Preview by giving the bullet
span the exact marker box of a task checkbox: lead → box → gap → text. The
bullet's parent span carries the list's --list-padding-inline-start, so
subtract it from the lead. */
.better-bujo .markdown-source-view.mod-cm6.is-live-preview .HyperMD-list-line:not(.HyperMD-task-line) .list-bullet {
width: var(--checkbox-size);
margin-inline-start: calc(var(--bb-marker-lead) - var(--list-padding-inline-start));
margin-inline-end: var(--bb-marker-gap);
}
/* ===========================================================================
* Emotion / thought lines ("~ …"). Tagged with .bb-emotion by the plugin.
* ======================================================================== */
.better-bujo .bb-emotion {
font-style: italic;
color: var(--text-muted);
}
/* Reading mode: the post-processor moves the `~` into .bb-emotion-marker and
strips it from the text. Indent the paragraph like a list item (3ch, same
as .markdown-rendered li) and clone the reading checkbox chain
(-1.5 / 1 / 0.5 × checkbox-size) so marker and text join the columns. */
.better-bujo .markdown-rendered .bb-emotion {
margin-inline-start: 3ch;
}
.better-bujo .markdown-rendered .bb-emotion .bb-emotion-marker {
display: inline-block;
width: var(--checkbox-size);
margin-inline-start: calc(var(--checkbox-size) * -1.5);
margin-inline-end: calc(var(--checkbox-size) * 0.5);
text-align: center;
color: var(--bb-marker-color);
}
/* In Live Preview the leading `~` is wrapped in .bb-emotion-marker by the
editor extension. Give it the same marker box as a task checkbox (no list
padding on these lines) so the `~` sits in the marker column and the text
aligns with task text. */
.better-bujo .markdown-source-view.mod-cm6.is-live-preview .bb-emotion-marker {
display: inline-block;
width: var(--checkbox-size);
margin-inline-start: var(--bb-marker-lead);
margin-inline-end: var(--bb-marker-gap);
text-align: center;
color: var(--bb-marker-color);
}