secondbrain-py 0.2.1__py3-none-any.whl
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.
- brain/__init__.py +0 -0
- brain/__main__.py +18 -0
- brain/_capture_command.py +445 -0
- brain/_compose.py +52 -0
- brain/activity.py +206 -0
- brain/ask.py +631 -0
- brain/audio.py +591 -0
- brain/backfill/__init__.py +12 -0
- brain/backfill/search_extras.py +141 -0
- brain/backfill/source_rows.py +101 -0
- brain/bin/__init__.py +1 -0
- brain/bin/_launcher.py +107 -0
- brain/bin/down.py +8 -0
- brain/bin/launchd.py +268 -0
- brain/bin/monitor.py +570 -0
- brain/bin/rebuild.py +8 -0
- brain/bin/status.py +8 -0
- brain/bin/up.py +8 -0
- brain/brief.py +272 -0
- brain/capture.py +49 -0
- brain/chat.py +293 -0
- brain/cli.py +9760 -0
- brain/cli_claude.py +81 -0
- brain/cli_connect.py +285 -0
- brain/cli_demo.py +266 -0
- brain/config.py +1949 -0
- brain/connect.py +925 -0
- brain/db.py +540 -0
- brain/demo/__init__.py +452 -0
- brain/demo/corpus/manifest.json +403 -0
- brain/demo/embedder.py +74 -0
- brain/durations.py +84 -0
- brain/edit_session.py +156 -0
- brain/editor.py +67 -0
- brain/elicit/__init__.py +16 -0
- brain/elicit/detectors.py +250 -0
- brain/elicit/drafter.py +70 -0
- brain/elicit/queue.py +220 -0
- brain/elicit/schema.py +48 -0
- brain/elicit/session.py +445 -0
- brain/embedding_targets.py +54 -0
- brain/embeddings.py +424 -0
- brain/enrichment.py +808 -0
- brain/errors.py +357 -0
- brain/eval/__init__.py +129 -0
- brain/eval/answer_eval.py +281 -0
- brain/eval/baseline.py +265 -0
- brain/eval/concept_extraction.py +378 -0
- brain/eval/corpus.py +152 -0
- brain/eval/errors.py +19 -0
- brain/eval/graph_baseline.py +226 -0
- brain/eval/graph_retrieval.py +202 -0
- brain/eval/graph_runner.py +319 -0
- brain/eval/metrics.py +101 -0
- brain/eval/runner.py +223 -0
- brain/format.py +783 -0
- brain/gaps.py +390 -0
- brain/graph_rag/__init__.py +94 -0
- brain/graph_rag/_retrieval_common.py +113 -0
- brain/graph_rag/aggregates.py +303 -0
- brain/graph_rag/aliases/__init__.py +583 -0
- brain/graph_rag/backends/__init__.py +10 -0
- brain/graph_rag/backends/_age_helpers.py +473 -0
- brain/graph_rag/backends/age.py +782 -0
- brain/graph_rag/backends/base.py +272 -0
- brain/graph_rag/build.py +344 -0
- brain/graph_rag/communities.py +644 -0
- brain/graph_rag/communities_summary.py +437 -0
- brain/graph_rag/concepts.py +202 -0
- brain/graph_rag/cooccur.py +193 -0
- brain/graph_rag/cross_type.py +312 -0
- brain/graph_rag/extract.py +885 -0
- brain/graph_rag/fuse.py +371 -0
- brain/graph_rag/global_.py +412 -0
- brain/graph_rag/grouping.py +372 -0
- brain/graph_rag/person_resolver.py +167 -0
- brain/graph_rag/reconcile.py +792 -0
- brain/graph_rag/relational.py +353 -0
- brain/graph_rag/retrieve.py +526 -0
- brain/graph_rag/router.py +288 -0
- brain/graph_rag/schema.py +320 -0
- brain/graph_rag/sync.py +237 -0
- brain/graph_rag/tenancy.py +43 -0
- brain/graph_rag/themes.py +501 -0
- brain/graph_rag/weighting.py +202 -0
- brain/ingest/__init__.py +1926 -0
- brain/ingest/chunker.py +249 -0
- brain/ingest/docx.py +40 -0
- brain/ingest/gmail.py +621 -0
- brain/ingest/markdown.py +37 -0
- brain/ingest/pdf.py +61 -0
- brain/ingest/stdin.py +22 -0
- brain/ingest/sub_tokens.py +91 -0
- brain/ingest/text.py +16 -0
- brain/interactions.py +205 -0
- brain/maintenance.py +355 -0
- brain/mcp_server.py +3405 -0
- brain/migrations/001_init.sql +43 -0
- brain/migrations/002_qwen3_embedding.sql +17 -0
- brain/migrations/003_vault_model.sql +41 -0
- brain/migrations/004_relax_content_hash_uniqueness.sql +18 -0
- brain/migrations/005_derived_links.sql +67 -0
- brain/migrations/006_dedup_file_by_source_path.sql +25 -0
- brain/migrations/007_email_thread_and_draft.sql +15 -0
- brain/migrations/008_gmail_thread_unique.sql +11 -0
- brain/migrations/009_chunks_weighted_tsv.sql +28 -0
- brain/migrations/010_interactions.sql +30 -0
- brain/migrations/011_documents_summary.sql +23 -0
- brain/migrations/012_graphrag.sql +171 -0
- brain/migrations/013_graphrag_communities.sql +125 -0
- brain/migrations/014_graphrag_community_summary_hash.sql +33 -0
- brain/migrations/015_interactions_graph_targets.sql +89 -0
- brain/migrations/016_index_hygiene.sql +61 -0
- brain/migrations/017_elicit.sql +30 -0
- brain/migrations/018_review_gap_signal_kinds.sql +40 -0
- brain/migrations/019_search_queries.sql +35 -0
- brain/migrations/020_link_suggestions.sql +40 -0
- brain/migrations/021_timeline_doc_date.sql +34 -0
- brain/migrations/022_link_suggestions_undirected.sql +84 -0
- brain/migrations/023_search_queries_fts_count.sql +28 -0
- brain/quartz_overrides/__init__.py +8 -0
- brain/quartz_overrides/quartz/bootstrap-cli.mjs +65 -0
- brain/quartz_overrides/quartz/build.ts +568 -0
- brain/quartz_overrides/quartz/cli/args.js +152 -0
- brain/quartz_overrides/quartz/cli/build_partial_handler.js +544 -0
- brain/quartz_overrides/quartz/cli/handlers.js +636 -0
- brain/quartz_overrides/quartz/components/CommandPalette.tsx +172 -0
- brain/quartz_overrides/quartz/components/Explorer.tsx +198 -0
- brain/quartz_overrides/quartz/components/Footer.tsx +27 -0
- brain/quartz_overrides/quartz/components/Graph.tsx +468 -0
- brain/quartz_overrides/quartz/components/PageTitle.tsx +72 -0
- brain/quartz_overrides/quartz/components/RelatedDocs.tsx +38 -0
- brain/quartz_overrides/quartz/components/Search.tsx +161 -0
- brain/quartz_overrides/quartz/components/SummaryLede.tsx +72 -0
- brain/quartz_overrides/quartz/components/index.ts +92 -0
- brain/quartz_overrides/quartz/components/pages/TagContent.tsx +272 -0
- brain/quartz_overrides/quartz/components/scripts/commandPalette.inline.ts +665 -0
- brain/quartz_overrides/quartz/components/scripts/explorer.inline.ts +768 -0
- brain/quartz_overrides/quartz/components/scripts/graph.inline.ts +2302 -0
- brain/quartz_overrides/quartz/components/scripts/relatedDocs.inline.ts +163 -0
- brain/quartz_overrides/quartz/components/scripts/search.inline.ts +1011 -0
- brain/quartz_overrides/quartz/plugins/emitters/contentIndex.ts +546 -0
- brain/quartz_overrides/quartz/plugins/transformers/codeCopy.ts +94 -0
- brain/quartz_overrides/quartz/plugins/transformers/derivedFenceMark.ts +302 -0
- brain/quartz_overrides/quartz/plugins/transformers/emailThread.ts +148 -0
- brain/quartz_overrides/quartz/plugins/transformers/emptyDoorFilter.ts +213 -0
- brain/quartz_overrides/quartz/plugins/transformers/index.ts +114 -0
- brain/quartz_overrides/quartz/plugins/transformers/linkKindMark.ts +205 -0
- brain/quartz_overrides/quartz/plugins/transformers/linkSourceTag.ts +104 -0
- brain/quartz_overrides/quartz/plugins/transformers/relativeDate.ts +100 -0
- brain/quartz_overrides/quartz/plugins/transformers/reloadSignal.ts +131 -0
- brain/quartz_overrides/quartz/processors/parse.ts +371 -0
- brain/quartz_overrides/quartz/processors/parser_cache.ts +78 -0
- brain/quartz_overrides/quartz/static/brain-logo-dark.png +0 -0
- brain/quartz_overrides/quartz/static/brain-logo-light.png +0 -0
- brain/quartz_overrides/quartz/static/codeCopy.js +196 -0
- brain/quartz_overrides/quartz/static/emailThread.js +334 -0
- brain/quartz_overrides/quartz/static/favicon.ico +0 -0
- brain/quartz_overrides/quartz/static/icon.png +0 -0
- brain/quartz_overrides/quartz/static/linkSourceTag.js +104 -0
- brain/quartz_overrides/quartz/static/relativeDate.js +142 -0
- brain/quartz_overrides/quartz/static/reload.js +168 -0
- brain/quartz_overrides/quartz/styles/brain/_article.scss +252 -0
- brain/quartz_overrides/quartz/styles/brain/_atmosphere.scss +113 -0
- brain/quartz_overrides/quartz/styles/brain/_callouts.scss +180 -0
- brain/quartz_overrides/quartz/styles/brain/_cmdk.scss +7 -0
- brain/quartz_overrides/quartz/styles/brain/_code.scss +208 -0
- brain/quartz_overrides/quartz/styles/brain/_command_palette.scss +369 -0
- brain/quartz_overrides/quartz/styles/brain/_email_thread.scss +228 -0
- brain/quartz_overrides/quartz/styles/brain/_explorer.scss +142 -0
- brain/quartz_overrides/quartz/styles/brain/_home.scss +182 -0
- brain/quartz_overrides/quartz/styles/brain/_links.scss +322 -0
- brain/quartz_overrides/quartz/styles/brain/_marginalia.scss +117 -0
- brain/quartz_overrides/quartz/styles/brain/_motion.scss +175 -0
- brain/quartz_overrides/quartz/styles/brain/_people_hub.scss +100 -0
- brain/quartz_overrides/quartz/styles/brain/_related_docs.scss +137 -0
- brain/quartz_overrides/quartz/styles/brain/_search.scss +252 -0
- brain/quartz_overrides/quartz/styles/brain/_sidebar.scss +468 -0
- brain/quartz_overrides/quartz/styles/brain/_summary_lede.scss +56 -0
- brain/quartz_overrides/quartz/styles/brain/_surface.scss +43 -0
- brain/quartz_overrides/quartz/styles/brain/_tag_content.scss +118 -0
- brain/quartz_overrides/quartz/styles/brain/_tokens.scss +197 -0
- brain/quartz_overrides/quartz/styles/brain/_typography.scss +92 -0
- brain/quartz_overrides/quartz/styles/custom.scss +89 -0
- brain/quartz_overrides/quartz/styles/graph.scss +505 -0
- brain/quartz_overrides/quartz/util/ctx.ts +92 -0
- brain/quartz_overrides/quartz/util/fastpath_manifest.ts +608 -0
- brain/quartz_overrides/quartz/util/path.ts +358 -0
- brain/quartz_overrides/quartz/util/sourceIcons.ts +55 -0
- brain/quartz_overrides/quartz.config.ts +270 -0
- brain/quartz_overrides/quartz.layout.ts +314 -0
- brain/queries.py +1188 -0
- brain/rank_fusion.py +8 -0
- brain/resurface.py +210 -0
- brain/review/__init__.py +26 -0
- brain/review/emit.py +27 -0
- brain/review/queries.py +436 -0
- brain/review/render.py +196 -0
- brain/review/scans.py +355 -0
- brain/review/weekly.py +413 -0
- brain/search.py +704 -0
- brain/set_similarity.py +15 -0
- brain/setup.py +1205 -0
- brain/tags.py +56 -0
- brain/templates/Caddyfile.j2 +9 -0
- brain/templates/__init__.py +1 -0
- brain/templates/bin/__init__.py +1 -0
- brain/templates/bin/_brain-brief-fg.sh +25 -0
- brain/templates/bin/_brain-build-fg.sh +53 -0
- brain/templates/bin/_brain-watcher-fg.sh +65 -0
- brain/templates/bin/brain-down.sh +89 -0
- brain/templates/bin/brain-status.sh +83 -0
- brain/templates/bin/brain-up.sh +221 -0
- brain/templates/docker/age/Dockerfile +79 -0
- brain/templates/docker-compose.stock.yml.j2 +26 -0
- brain/templates/docker-compose.yml.j2 +34 -0
- brain/templates/env.example +190 -0
- brain/templates/launchd/__init__.py +1 -0
- brain/templates/launchd/com.brain.brief.plist.j2 +45 -0
- brain/templates/launchd/com.brain.build.plist.j2 +46 -0
- brain/templates/launchd/com.brain.watcher.plist.j2 +46 -0
- brain/templates/skill/SKILL.md +63 -0
- brain/templates/skill/__init__.py +1 -0
- brain/timeline.py +834 -0
- brain/todo.py +124 -0
- brain/uninstall.py +185 -0
- brain/vault/__init__.py +115 -0
- brain/vault/_atomic.py +25 -0
- brain/vault/daily_index.py +228 -0
- brain/vault/derived_links/__init__.py +50 -0
- brain/vault/derived_links/directory.py +683 -0
- brain/vault/derived_links/fence.py +408 -0
- brain/vault/derived_links/gws.py +64 -0
- brain/vault/derived_links/participants.py +143 -0
- brain/vault/derived_links/pass_runner.py +362 -0
- brain/vault/derived_links/rules.py +137 -0
- brain/vault/export.py +683 -0
- brain/vault/frontmatter.py +165 -0
- brain/vault/graph.py +620 -0
- brain/vault/graph_format.py +388 -0
- brain/vault/link_rewrite.py +235 -0
- brain/vault/links.py +260 -0
- brain/vault/note_builder.py +211 -0
- brain/vault/paths.py +55 -0
- brain/vault/quartz_overlay.py +236 -0
- brain/vault/rename.py +591 -0
- brain/vault/resolver.py +304 -0
- brain/vault/slug.py +127 -0
- brain/vault/sync.py +1513 -0
- brain/vault/sync_summaries.py +264 -0
- brain/vault/templates.py +145 -0
- brain/vault/watch.py +1052 -0
- brain/wiki/__init__.py +6 -0
- brain/wiki/_github_slugger.py +76 -0
- brain/wiki/_person_name.py +314 -0
- brain/wiki/build_homepage.py +541 -0
- brain/wiki/build_partial.py +273 -0
- brain/wiki/build_people.py +934 -0
- brain/wiki/build_related.py +758 -0
- brain/wiki/build_swap.py +585 -0
- brain/wiki/build_watcher.py +975 -0
- brain/wiki/edit_classifier.py +215 -0
- brain/wiki/errors.py +10 -0
- brain/wiki/fastpath_manifest.py +475 -0
- brain/wiki/fastpath_state.py +174 -0
- brain/wiki/install.py +296 -0
- brain/wiki/slug.py +111 -0
- secondbrain_py-0.2.1.dist-info/METADATA +195 -0
- secondbrain_py-0.2.1.dist-info/RECORD +273 -0
- secondbrain_py-0.2.1.dist-info/WHEEL +5 -0
- secondbrain_py-0.2.1.dist-info/entry_points.txt +11 -0
- secondbrain_py-0.2.1.dist-info/licenses/LICENSE +21 -0
- secondbrain_py-0.2.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
// Brain command palette — Lane C of the 2026 commonplace-book redesign.
|
|
2
|
+
//
|
|
3
|
+
// This file is installed at
|
|
4
|
+
// `<vault>/.quartz/quartz/styles/brain/_command_palette.scss` by `brain vault
|
|
5
|
+
// render --overlay` and pulled into the global SCSS via `custom.scss`'s
|
|
6
|
+
// `@use "./brain/command_palette"` line (added between `_sidebar` and
|
|
7
|
+
// `_article`).
|
|
8
|
+
//
|
|
9
|
+
// Visual rules for the Cmd/Ctrl-P palette:
|
|
10
|
+
//
|
|
11
|
+
// * Native `<dialog>` reset — strip the browser's default
|
|
12
|
+
// `padding`, `border`, `position`, etc. so our modal styles
|
|
13
|
+
// control the chrome cleanly.
|
|
14
|
+
// * Native `::backdrop` pseudo-element — replaces the manual
|
|
15
|
+
// `.brain-cmdk-backdrop` div with the browser-managed scrim.
|
|
16
|
+
// Tinted with `var(--scrim)` from `_tokens.scss` (light/dark
|
|
17
|
+
// variants).
|
|
18
|
+
// * Modal — centered, rounded card on `--surface-1` with
|
|
19
|
+
// `--shadow-md`. Scales `0.96 → 1.0` on open; mirrored on close.
|
|
20
|
+
// * Input — single-row text field, larger than body text, no
|
|
21
|
+
// visible borders (clean writing-tool feel).
|
|
22
|
+
// * Source chips — compact filter rail mirroring Search's source
|
|
23
|
+
// vocabulary so quick-open can narrow to gmail / krisp / slack /
|
|
24
|
+
// manual / vault without invoking the full search overlay.
|
|
25
|
+
// * Results — vertical list, each item carries kind icon, title,
|
|
26
|
+
// and a faint slug subtitle. Selected item highlighted via
|
|
27
|
+
// `aria-selected="true"`.
|
|
28
|
+
//
|
|
29
|
+
// The component markup itself (rendered by `CommandPalette.tsx`):
|
|
30
|
+
//
|
|
31
|
+
// <dialog id="brain-cmdk-root" class="brain-cmdk-root" aria-label="Command palette">
|
|
32
|
+
// <div class="brain-cmdk-modal">
|
|
33
|
+
// <div class="brain-cmdk-chips">...</div>
|
|
34
|
+
// <input class="brain-cmdk-input" role="combobox" aria-expanded="false"
|
|
35
|
+
// aria-haspopup="listbox" aria-controls="brain-cmdk-results"
|
|
36
|
+
// aria-autocomplete="list" type="text" autocomplete="off"
|
|
37
|
+
// placeholder="Search the wiki…" aria-label="Search the wiki">
|
|
38
|
+
// <ul class="brain-cmdk-results" id="brain-cmdk-results" role="listbox">
|
|
39
|
+
// <!-- populated by commandPalette.inline.ts -->
|
|
40
|
+
// </ul>
|
|
41
|
+
// <div class="brain-cmdk-empty" hidden>No results.</div>
|
|
42
|
+
// <div class="brain-cmdk-footer">
|
|
43
|
+
// <kbd>↑</kbd><kbd>↓</kbd> navigate · <kbd>↵</kbd> open · <kbd>esc</kbd> close
|
|
44
|
+
// </div>
|
|
45
|
+
// </div>
|
|
46
|
+
// </dialog>
|
|
47
|
+
//
|
|
48
|
+
// brain (Lane C audit fix 2026-05-02): refactored to native
|
|
49
|
+
// `<dialog>`. Open/close is driven by the dialog's own `open`
|
|
50
|
+
// attribute (set by `dialog.showModal()`); the `.is-open` class on
|
|
51
|
+
// the dialog still gates the entrance/exit transitions because the
|
|
52
|
+
// transition properties below interpolate ON the dialog itself, and
|
|
53
|
+
// the class flip provides a paint-frame boundary the browser can
|
|
54
|
+
// animate over.
|
|
55
|
+
//
|
|
56
|
+
// Tokens consumed (from `_tokens.scss`):
|
|
57
|
+
// * `--surface-1`/`--surface-2` — modal + input bg
|
|
58
|
+
// * `--scrim` — `::backdrop` tint
|
|
59
|
+
// * `--ink-0`/`--ink-1`/`--ink-2` — title, subtitle, footer
|
|
60
|
+
// * `--rule` — input bottom hairline + footer top hairline
|
|
61
|
+
// * `--accent-soft`/`--accent-strong` — selected item bg + ring
|
|
62
|
+
// * `--shadow-md` — modal elevation
|
|
63
|
+
// * `--motion-fast`/`--motion-mid`/`--motion-easing` — fades + scale
|
|
64
|
+
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
// 1. Dialog reset + positioning
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
//
|
|
69
|
+
// brain (Lane C audit fix): native `<dialog>` ships with browser
|
|
70
|
+
// defaults for `padding`, `border`, `background`, `position`, `width`,
|
|
71
|
+
// and `margin: auto` for centering. We strip them all so the
|
|
72
|
+
// `.brain-cmdk-modal` child is the only chrome that paints. Using
|
|
73
|
+
// `all: unset` would also blow away the dialog's open/closed
|
|
74
|
+
// semantics, so we reset properties explicitly.
|
|
75
|
+
//
|
|
76
|
+
// `position: fixed` + `inset: 0` + `display: flex` re-implements
|
|
77
|
+
// centering — native dialog's `margin: auto` only works when the
|
|
78
|
+
// dialog has an intrinsic size, which we don't want (the modal
|
|
79
|
+
// sizes itself).
|
|
80
|
+
|
|
81
|
+
#brain-cmdk-root.brain-cmdk-root {
|
|
82
|
+
// Reset native dialog chrome.
|
|
83
|
+
padding: 0;
|
|
84
|
+
border: 0;
|
|
85
|
+
background: transparent;
|
|
86
|
+
color: inherit;
|
|
87
|
+
// Position over the full viewport so flex centering works.
|
|
88
|
+
// `position: fixed` overrides the browser default of `absolute`.
|
|
89
|
+
position: fixed;
|
|
90
|
+
inset: 0;
|
|
91
|
+
margin: 0;
|
|
92
|
+
// Browser default sets `max-width` / `max-height` to `calc(100% - 6px - 2em)`;
|
|
93
|
+
// override so we control sizing via the modal child.
|
|
94
|
+
max-width: 100vw;
|
|
95
|
+
max-height: 100vh;
|
|
96
|
+
width: 100vw;
|
|
97
|
+
height: 100vh;
|
|
98
|
+
// brain: `display: none` when `[open]` is absent is the native
|
|
99
|
+
// default — but stock dialog also matches `display: block` on
|
|
100
|
+
// [open], which conflicts with our `display: flex` for centering.
|
|
101
|
+
// Re-pin to flex on `[open]` so the modal sits in the center.
|
|
102
|
+
z-index: 1000;
|
|
103
|
+
// brain: prevent body content showing through edges when the
|
|
104
|
+
// backdrop is being painted. `overflow: hidden` on the dialog
|
|
105
|
+
// itself isn't enough; we also clip backdrop scroll below.
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
#brain-cmdk-root.brain-cmdk-root[open] {
|
|
109
|
+
display: flex;
|
|
110
|
+
align-items: flex-start;
|
|
111
|
+
justify-content: center;
|
|
112
|
+
// 12vh top spacing so the modal sits in the upper third — standard
|
|
113
|
+
// PKB convention (Reflect, Notion, Linear all bias to the top).
|
|
114
|
+
padding-top: 12vh;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
// 2. Native `::backdrop`
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
//
|
|
121
|
+
// brain (Lane C audit fix): the browser-painted `::backdrop`
|
|
122
|
+
// pseudo-element replaces the manual `<div class="brain-cmdk-backdrop">`.
|
|
123
|
+
// The browser stacks it above all page content but below the dialog's
|
|
124
|
+
// own contents, no z-index gymnastics required.
|
|
125
|
+
//
|
|
126
|
+
// The opacity transition runs on the `::backdrop` directly. Stock
|
|
127
|
+
// browsers may not support animating the backdrop in every version;
|
|
128
|
+
// graceful — the worst case is the scrim appearing instantly without
|
|
129
|
+
// the fade, which is still a coherent UI.
|
|
130
|
+
|
|
131
|
+
#brain-cmdk-root.brain-cmdk-root::backdrop {
|
|
132
|
+
background: var(--scrim);
|
|
133
|
+
backdrop-filter: blur(8px);
|
|
134
|
+
-webkit-backdrop-filter: blur(8px);
|
|
135
|
+
opacity: 0;
|
|
136
|
+
transition: opacity var(--motion-mid) var(--motion-easing);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
#brain-cmdk-root.brain-cmdk-root.is-open::backdrop {
|
|
140
|
+
opacity: 1;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// ---------------------------------------------------------------------------
|
|
144
|
+
// 3. Modal card + source chips + input
|
|
145
|
+
// ---------------------------------------------------------------------------
|
|
146
|
+
|
|
147
|
+
.brain-cmdk-modal {
|
|
148
|
+
position: relative;
|
|
149
|
+
width: min(640px, calc(100vw - 2rem));
|
|
150
|
+
max-height: 70vh;
|
|
151
|
+
background: var(--surface-1);
|
|
152
|
+
border-radius: 12px;
|
|
153
|
+
box-shadow: var(--shadow-md);
|
|
154
|
+
display: flex;
|
|
155
|
+
flex-direction: column;
|
|
156
|
+
overflow: hidden;
|
|
157
|
+
// Entrance transform — small scale-up paired with the backdrop fade.
|
|
158
|
+
transform: scale(0.96);
|
|
159
|
+
opacity: 0;
|
|
160
|
+
transition:
|
|
161
|
+
transform var(--motion-mid) var(--motion-easing),
|
|
162
|
+
opacity var(--motion-mid) var(--motion-easing);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
#brain-cmdk-root.brain-cmdk-root.is-open .brain-cmdk-modal {
|
|
166
|
+
transform: scale(1);
|
|
167
|
+
opacity: 1;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.brain-cmdk-chips {
|
|
171
|
+
display: flex;
|
|
172
|
+
flex-wrap: wrap;
|
|
173
|
+
gap: 0.35rem;
|
|
174
|
+
padding: 0.65rem 1.2rem 0;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.brain-cmdk-chip {
|
|
178
|
+
appearance: none;
|
|
179
|
+
border: 1px solid var(--rule);
|
|
180
|
+
border-radius: 999px;
|
|
181
|
+
background: var(--surface-2);
|
|
182
|
+
color: var(--ink-2);
|
|
183
|
+
display: inline-flex;
|
|
184
|
+
align-items: center;
|
|
185
|
+
gap: 0.3rem;
|
|
186
|
+
min-height: 24px;
|
|
187
|
+
padding: 0.12rem 0.55rem;
|
|
188
|
+
cursor: pointer;
|
|
189
|
+
font-family: var(--bodyFont);
|
|
190
|
+
font-size: var(--fs-xs);
|
|
191
|
+
line-height: 1;
|
|
192
|
+
transition:
|
|
193
|
+
background var(--motion-fast) var(--motion-easing),
|
|
194
|
+
border-color var(--motion-fast) var(--motion-easing),
|
|
195
|
+
color var(--motion-fast) var(--motion-easing);
|
|
196
|
+
|
|
197
|
+
&[data-active="true"] {
|
|
198
|
+
background: var(--accent-soft);
|
|
199
|
+
border-color: color-mix(in srgb, var(--accent-strong) 45%, var(--rule));
|
|
200
|
+
color: var(--ink-0);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
&:hover {
|
|
204
|
+
border-color: var(--ink-2);
|
|
205
|
+
color: var(--ink-0);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.brain-cmdk-chip-icon {
|
|
210
|
+
width: 1em;
|
|
211
|
+
text-align: center;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.brain-cmdk-chip-label {
|
|
215
|
+
text-transform: lowercase;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.brain-cmdk-input {
|
|
219
|
+
appearance: none;
|
|
220
|
+
width: 100%;
|
|
221
|
+
box-sizing: border-box;
|
|
222
|
+
padding: 1rem 1.2rem;
|
|
223
|
+
border: 0;
|
|
224
|
+
border-bottom: 1px solid var(--rule);
|
|
225
|
+
background: transparent;
|
|
226
|
+
color: var(--ink-0);
|
|
227
|
+
font-family: var(--bodyFont);
|
|
228
|
+
font-size: var(--fs-lg);
|
|
229
|
+
outline: none;
|
|
230
|
+
// brain (Linear): lining numerals + slight Geist tightness — tech
|
|
231
|
+
// aesthetic doesn't have old-style numerals.
|
|
232
|
+
font-variant-numeric: lining-nums proportional-nums;
|
|
233
|
+
letter-spacing: -0.011em;
|
|
234
|
+
|
|
235
|
+
&::placeholder {
|
|
236
|
+
color: var(--ink-2);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// ---------------------------------------------------------------------------
|
|
241
|
+
// 4. Results list
|
|
242
|
+
// ---------------------------------------------------------------------------
|
|
243
|
+
|
|
244
|
+
.brain-cmdk-results {
|
|
245
|
+
list-style: none;
|
|
246
|
+
margin: 0;
|
|
247
|
+
padding: 0.4rem 0;
|
|
248
|
+
overflow-y: auto;
|
|
249
|
+
flex: 1 1 auto;
|
|
250
|
+
// Custom scrollbar so the list reads as part of the modal chrome.
|
|
251
|
+
scrollbar-width: thin;
|
|
252
|
+
scrollbar-color: var(--rule) transparent;
|
|
253
|
+
|
|
254
|
+
&::-webkit-scrollbar {
|
|
255
|
+
width: 6px;
|
|
256
|
+
}
|
|
257
|
+
&::-webkit-scrollbar-thumb {
|
|
258
|
+
background: var(--rule);
|
|
259
|
+
border-radius: 3px;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.brain-cmdk-result {
|
|
264
|
+
display: flex;
|
|
265
|
+
align-items: center;
|
|
266
|
+
gap: 0.7rem;
|
|
267
|
+
padding: 0.55rem 1.2rem;
|
|
268
|
+
cursor: pointer;
|
|
269
|
+
color: var(--ink-1);
|
|
270
|
+
transition: background var(--motion-fast) var(--motion-easing);
|
|
271
|
+
|
|
272
|
+
// Kind icon (left-most). Mono-width so titles stack visually.
|
|
273
|
+
> .brain-cmdk-icon {
|
|
274
|
+
flex: 0 0 1.2rem;
|
|
275
|
+
text-align: center;
|
|
276
|
+
color: var(--ink-2);
|
|
277
|
+
font-size: var(--fs-sm);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Body wraps title + slug subtitle.
|
|
281
|
+
> .brain-cmdk-body {
|
|
282
|
+
flex: 1 1 auto;
|
|
283
|
+
min-width: 0;
|
|
284
|
+
|
|
285
|
+
> .brain-cmdk-title {
|
|
286
|
+
color: var(--ink-0);
|
|
287
|
+
font-weight: 600;
|
|
288
|
+
font-family: var(--displayFont);
|
|
289
|
+
font-size: var(--fs-md);
|
|
290
|
+
line-height: 1.2;
|
|
291
|
+
// Truncate over-long titles to a single line.
|
|
292
|
+
white-space: nowrap;
|
|
293
|
+
overflow: hidden;
|
|
294
|
+
text-overflow: ellipsis;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
> .brain-cmdk-slug {
|
|
298
|
+
color: var(--ink-2);
|
|
299
|
+
// brain (Linear): mono slug — Geist Mono at small size reads
|
|
300
|
+
// as a clean tech path, replacing the small-caps editorial
|
|
301
|
+
// treatment.
|
|
302
|
+
font-family: var(--codeFont);
|
|
303
|
+
font-size: var(--fs-xs);
|
|
304
|
+
line-height: 1.2;
|
|
305
|
+
white-space: nowrap;
|
|
306
|
+
overflow: hidden;
|
|
307
|
+
text-overflow: ellipsis;
|
|
308
|
+
letter-spacing: 0.02em;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// brain: ARIA-driven selected state. The inline script sets
|
|
313
|
+
// `aria-selected="true"` on the active item; styling follows the
|
|
314
|
+
// attribute so the visual highlight stays a11y-accessible.
|
|
315
|
+
&[aria-selected="true"] {
|
|
316
|
+
background: var(--accent-soft);
|
|
317
|
+
color: var(--ink-0);
|
|
318
|
+
> .brain-cmdk-body > .brain-cmdk-title,
|
|
319
|
+
> .brain-cmdk-icon {
|
|
320
|
+
color: var(--ink-0);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
&:hover {
|
|
325
|
+
background: color-mix(in srgb, var(--accent-soft) 60%, transparent);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// "No results" empty state.
|
|
330
|
+
.brain-cmdk-empty {
|
|
331
|
+
padding: 2rem 1.2rem;
|
|
332
|
+
text-align: center;
|
|
333
|
+
color: var(--ink-2);
|
|
334
|
+
font-family: var(--bodyFont);
|
|
335
|
+
font-size: var(--fs-sm);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// ---------------------------------------------------------------------------
|
|
339
|
+
// 5. Footer hint row
|
|
340
|
+
// ---------------------------------------------------------------------------
|
|
341
|
+
|
|
342
|
+
.brain-cmdk-footer {
|
|
343
|
+
border-top: 1px solid var(--rule);
|
|
344
|
+
padding: 0.5rem 1.2rem;
|
|
345
|
+
display: flex;
|
|
346
|
+
align-items: center;
|
|
347
|
+
gap: 0.4rem;
|
|
348
|
+
color: var(--ink-2);
|
|
349
|
+
// brain (Linear): mono footer hint — tech aesthetic, not small-caps.
|
|
350
|
+
font-family: var(--codeFont);
|
|
351
|
+
font-size: var(--fs-xs);
|
|
352
|
+
letter-spacing: 0.02em;
|
|
353
|
+
background: var(--surface-2);
|
|
354
|
+
|
|
355
|
+
kbd {
|
|
356
|
+
display: inline-flex;
|
|
357
|
+
align-items: center;
|
|
358
|
+
justify-content: center;
|
|
359
|
+
min-width: 18px;
|
|
360
|
+
padding: 0.05rem 0.3rem;
|
|
361
|
+
background: var(--surface-1);
|
|
362
|
+
color: var(--ink-1);
|
|
363
|
+
border: 1px solid var(--rule);
|
|
364
|
+
border-radius: 4px;
|
|
365
|
+
font-family: var(--codeFont);
|
|
366
|
+
font-size: 0.85em;
|
|
367
|
+
letter-spacing: normal;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
// Brain wiki — email-thread reading mode (P4.4 of the Wiki UX
|
|
2
|
+
// Overhaul).
|
|
3
|
+
//
|
|
4
|
+
// This file is installed at
|
|
5
|
+
// `<vault>/.quartz/quartz/styles/brain/_email_thread.scss` by `brain
|
|
6
|
+
// vault render --overlay` and is pulled into the global SCSS via
|
|
7
|
+
// `custom.scss`'s `@use "./brain/email_thread"` line.
|
|
8
|
+
//
|
|
9
|
+
// Scope of this file:
|
|
10
|
+
//
|
|
11
|
+
// * `<details>` + `<summary>` chrome inside `article` — paint each
|
|
12
|
+
// per-message collapsible as an intentional section card rather
|
|
13
|
+
// than the browser-default disclosure widget. Solid left rail in
|
|
14
|
+
// `--accent-soft`, padded body, hover state on the summary, no
|
|
15
|
+
// `<summary>` marker carat (replaced with our own `▸` / `▾`
|
|
16
|
+
// glyph that rotates on `[open]`).
|
|
17
|
+
// * `.brain-thread-message.brain-thread-latest` — the runtime-
|
|
18
|
+
// wrapped section around the leading H2 message. Mirrors the
|
|
19
|
+
// `<details>` body padding / left rail so the latest message
|
|
20
|
+
// reads as a section card too, just without the disclosure
|
|
21
|
+
// widget (it's always visible).
|
|
22
|
+
// * `.brain-email-replies-only-toggle` — the filter button the
|
|
23
|
+
// runtime injects at the top of `<article>`. Pill-shape, neutral
|
|
24
|
+
// surface, accent border on `aria-pressed="true"`.
|
|
25
|
+
// * `body.brain-replies-only [data-brain-is-mine="false"]` —
|
|
26
|
+
// visibility rule for the toggle. When the body class is on,
|
|
27
|
+
// hide every section whose `From:` doesn't match the user's
|
|
28
|
+
// email.
|
|
29
|
+
//
|
|
30
|
+
// Scope NOT covered here:
|
|
31
|
+
//
|
|
32
|
+
// * The H2 inside the latest-message section reuses
|
|
33
|
+
// `_article.scss`'s heading rhythm (the `> h2` rule in
|
|
34
|
+
// `article`). We intentionally do NOT restate it here — single
|
|
35
|
+
// source of truth.
|
|
36
|
+
// * Per-source link tinting on email-thread links lives in
|
|
37
|
+
// `_links.scss` (`[data-brain-source="gmail"]`).
|
|
38
|
+
//
|
|
39
|
+
// Tokens consumed (all from `_tokens.scss`):
|
|
40
|
+
//
|
|
41
|
+
// * `--accent-soft` — left rail on each message section
|
|
42
|
+
// * `--accent-strong` — toggle button pressed-state border
|
|
43
|
+
// * `--rule` — summary hover + toggle hairline
|
|
44
|
+
// * `--surface-1` — section + button background
|
|
45
|
+
// * `--ink-1` / `--ink-2` — body / dimmed text
|
|
46
|
+
// * `--fs-sm` / `--fs-xs` — toggle + summary type sizes
|
|
47
|
+
// * `--codeFont` — toggle button face (mono chrome to
|
|
48
|
+
// match the search-chip rail rhythm)
|
|
49
|
+
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// 1. Per-message <details> chrome
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
//
|
|
54
|
+
// Stock browser default for `<details>` is unstyled — a triangle
|
|
55
|
+
// disclosure widget on a plain text run. The brain treatment paints
|
|
56
|
+
// each message as a section card with a left accent rail and a
|
|
57
|
+
// padded body, matching the editorial rhythm in `_article.scss`. The
|
|
58
|
+
// `<summary>` gets a hover state + a custom rotation glyph so the
|
|
59
|
+
// disclosure feels intentional rather than browser-OEM.
|
|
60
|
+
|
|
61
|
+
article details.brain-thread-message,
|
|
62
|
+
article > details {
|
|
63
|
+
// brain: tag every <details> inside an article with the section
|
|
64
|
+
// chrome, even when the runtime hasn't yet stamped
|
|
65
|
+
// `.brain-thread-message`. The two selectors are equivalent in
|
|
66
|
+
// practice (every <details> in an article body comes from
|
|
67
|
+
// `to_extracted_thread`) but the comma-form keeps the rule painted
|
|
68
|
+
// even before the runtime fires (avoids a brief unstyled flash).
|
|
69
|
+
margin: 1.2rem 0;
|
|
70
|
+
padding: 0.6rem 0.9rem 0.6rem 1.1rem;
|
|
71
|
+
background: var(--surface-1, transparent);
|
|
72
|
+
border-left: 3px solid var(--accent-soft);
|
|
73
|
+
border-radius: 4px;
|
|
74
|
+
// brain: subtle elevation shifts on [open] — closed sections sit
|
|
75
|
+
// flat; opened ones lift a hair to signal "this is what you're
|
|
76
|
+
// reading right now."
|
|
77
|
+
box-shadow: 0 1px 0 var(--rule);
|
|
78
|
+
transition: box-shadow 120ms ease-out;
|
|
79
|
+
|
|
80
|
+
&[open] {
|
|
81
|
+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
> summary {
|
|
85
|
+
// brain: replace the OEM triangle with our own glyph (managed
|
|
86
|
+
// via ::before below) so the summary reads as an intentional
|
|
87
|
+
// section header rather than a generic disclosure widget.
|
|
88
|
+
list-style: none;
|
|
89
|
+
cursor: pointer;
|
|
90
|
+
font-family: var(--codeFont);
|
|
91
|
+
font-size: var(--fs-sm);
|
|
92
|
+
color: var(--ink-2);
|
|
93
|
+
padding: 0.2rem 0;
|
|
94
|
+
user-select: none;
|
|
95
|
+
display: flex;
|
|
96
|
+
align-items: baseline;
|
|
97
|
+
gap: 0.4rem;
|
|
98
|
+
transition: color 120ms ease-out;
|
|
99
|
+
|
|
100
|
+
// Hide WebKit's native disclosure marker (Chrome / Safari).
|
|
101
|
+
// `list-style: none` above handles Firefox; `::-webkit-details-
|
|
102
|
+
// marker` covers WebKit.
|
|
103
|
+
&::-webkit-details-marker {
|
|
104
|
+
display: none;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// brain: custom disclosure glyph. Right-pointing triangle when
|
|
108
|
+
// closed, rotates 90° on `[open]`. CSS-only, no JS hook — the
|
|
109
|
+
// browser's native open/close still drives the state.
|
|
110
|
+
&::before {
|
|
111
|
+
content: "▸";
|
|
112
|
+
display: inline-block;
|
|
113
|
+
width: 0.8em;
|
|
114
|
+
color: var(--accent-strong);
|
|
115
|
+
transition: transform 120ms ease-out;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
&:hover {
|
|
119
|
+
color: var(--ink-1);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
&[open] > summary::before {
|
|
124
|
+
transform: rotate(90deg);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// brain: indent the message body inside the disclosure so the
|
|
128
|
+
// closed-state summary visually anchors the section, and the
|
|
129
|
+
// opened body reads as inset content. The inner paragraphs use
|
|
130
|
+
// article-default leading so they match the latest-message body.
|
|
131
|
+
> *:not(summary) {
|
|
132
|
+
margin-left: 1.2rem;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
> p {
|
|
136
|
+
margin: 0.4rem 0;
|
|
137
|
+
color: var(--ink-1);
|
|
138
|
+
line-height: 1.55;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ---------------------------------------------------------------------------
|
|
143
|
+
// 2. Latest-message section wrapper (runtime-injected)
|
|
144
|
+
// ---------------------------------------------------------------------------
|
|
145
|
+
//
|
|
146
|
+
// The latest message renders as `## H2 + body` in the markdown (per
|
|
147
|
+
// `to_extracted_thread`'s contract — pinned by the P2.1 test). The
|
|
148
|
+
// runtime wraps that H2 + its trailing siblings inside a
|
|
149
|
+
// `<section class="brain-thread-message brain-thread-latest">` so the
|
|
150
|
+
// "Show only my replies" filter has a uniform DOM shape across
|
|
151
|
+
// latest + older messages. The styling here mirrors `<details>`'s
|
|
152
|
+
// chrome minus the disclosure widget (always-visible).
|
|
153
|
+
|
|
154
|
+
article section.brain-thread-message.brain-thread-latest {
|
|
155
|
+
display: block;
|
|
156
|
+
margin: 1.2rem 0 1.6rem 0;
|
|
157
|
+
padding: 0.4rem 0.9rem 0.6rem 1.1rem;
|
|
158
|
+
background: var(--surface-1, transparent);
|
|
159
|
+
border-left: 3px solid var(--accent-strong);
|
|
160
|
+
border-radius: 4px;
|
|
161
|
+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
|
|
162
|
+
|
|
163
|
+
// The H2 inside the latest section is the most recent message's
|
|
164
|
+
// heading. Pull the top margin in so it lands flush with the
|
|
165
|
+
// section's top padding.
|
|
166
|
+
> h2 {
|
|
167
|
+
margin-top: 0;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// ---------------------------------------------------------------------------
|
|
172
|
+
// 3. "Show only my replies" toggle button
|
|
173
|
+
// ---------------------------------------------------------------------------
|
|
174
|
+
//
|
|
175
|
+
// Runtime-injected at the top of <article> on email-thread pages.
|
|
176
|
+
// Pill chrome, mono face (matches the cmd-K palette + chip rail
|
|
177
|
+
// rhythm), neutral surface in default state, accent border + bold
|
|
178
|
+
// type on `aria-pressed="true"`.
|
|
179
|
+
|
|
180
|
+
article > .brain-email-replies-only-toggle {
|
|
181
|
+
display: inline-block;
|
|
182
|
+
margin: 0 0 1rem 0;
|
|
183
|
+
padding: 0.35em 0.9em;
|
|
184
|
+
font-family: var(--codeFont);
|
|
185
|
+
font-size: var(--fs-xs);
|
|
186
|
+
font-weight: 500;
|
|
187
|
+
color: var(--ink-2);
|
|
188
|
+
background: var(--surface-1);
|
|
189
|
+
border: 1px solid var(--rule);
|
|
190
|
+
border-radius: 999px;
|
|
191
|
+
cursor: pointer;
|
|
192
|
+
letter-spacing: 0.02em;
|
|
193
|
+
transition: color 120ms ease-out, border-color 120ms ease-out,
|
|
194
|
+
background 120ms ease-out;
|
|
195
|
+
|
|
196
|
+
&:hover {
|
|
197
|
+
color: var(--ink-1);
|
|
198
|
+
border-color: var(--accent-soft);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
&[aria-pressed="true"] {
|
|
202
|
+
color: var(--accent-strong);
|
|
203
|
+
border-color: var(--accent-strong);
|
|
204
|
+
background: var(--accent-soft);
|
|
205
|
+
font-weight: 600;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
&:focus-visible {
|
|
209
|
+
outline: 2px solid var(--accent-strong);
|
|
210
|
+
outline-offset: 2px;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// ---------------------------------------------------------------------------
|
|
215
|
+
// 4. Filter visibility rules
|
|
216
|
+
// ---------------------------------------------------------------------------
|
|
217
|
+
//
|
|
218
|
+
// When the toggle is ON, hide every message section whose `From:`
|
|
219
|
+
// doesn't match the user's email. The runtime stamps
|
|
220
|
+
// `data-brain-is-mine="true|false"` on each section
|
|
221
|
+
// (`.brain-thread-message`) at boot; the body class
|
|
222
|
+
// `brain-replies-only` is the master switch. Using `display: none`
|
|
223
|
+
// (rather than `visibility` / opacity) so hidden sections also
|
|
224
|
+
// collapse out of the document flow — keeps the visible list compact.
|
|
225
|
+
|
|
226
|
+
body.brain-replies-only article [data-brain-is-mine="false"] {
|
|
227
|
+
display: none;
|
|
228
|
+
}
|