atproto blogging
1/**
2 * Weaver Editor - Base Styles
3 *
4 * Core styles for the contenteditable editor.
5 * Host app should provide CSS variables for theming.
6 *
7 * Required CSS variables (Rose Pine defaults shown):
8 * --color-base: #faf4ed
9 * --color-surface: #fffaf3
10 * --color-overlay: #f2e9e1
11 * --color-text: #1f1d2e
12 * --color-muted: #635e74
13 * --color-subtle: #4a4560
14 * --color-border: #908caa
15 * --color-primary: #907aa9
16 * --color-error: #b4637a
17 * --font-body: serif stack
18 * --font-heading: sans stack
19 * --font-mono: monospace stack
20 * --spacing-line-height: 1.6
21 */
22
23/* Editor container */
24.weaver-editor-content {
25 outline: none;
26 min-height: 1em;
27 line-height: var(--spacing-line-height, 1.6);
28 background: var(--color-base, #faf4ed);
29 color: var(--color-text, #1f1d2e);
30 font-family: var(--font-body, Georgia, serif);
31 /* break-spaces ensures trailing whitespace takes up space and allows cursor placement */
32 white-space-collapse: break-spaces;
33 /* Wrap long words/URLs only when they would overflow */
34 overflow-wrap: break-word;
35}
36
37.weaver-editor-content:focus {
38 outline: none;
39}
40
41/* Override default margins - break-spaces renders newlines visually */
42.weaver-editor-content p {
43 margin-bottom: 0 !important;
44}
45
46.weaver-editor-content h1,
47.weaver-editor-content h2,
48.weaver-editor-content h3,
49.weaver-editor-content h4,
50.weaver-editor-content h5,
51.weaver-editor-content h6 {
52 margin-top: 0 !important;
53 margin-bottom: 0 !important;
54 font-family: var(--font-heading, system-ui, sans-serif);
55}
56
57.weaver-editor-content pre {
58 margin-bottom: 0 !important;
59}
60
61.weaver-editor-content blockquote {
62 margin-top: 0 !important;
63 margin-bottom: 0 !important;
64}
65
66.weaver-editor-content ul,
67.weaver-editor-content ol {
68 margin-bottom: 0 !important;
69}
70
71/* ==========================================================================
72 Markdown Syntax Visibility
73 ========================================================================== */
74
75/* Inline syntax characters (**, *, ~~, `, etc) */
76.md-syntax-inline {
77 color: var(--color-muted, #635e74);
78 opacity: 0.6;
79}
80
81/* Block-level syntax characters (#, >, -, etc) */
82.md-syntax-block {
83 color: var(--color-muted, #635e74);
84 opacity: 0.7;
85 font-weight: normal;
86}
87
88/* Hidden syntax spans - collapsed when cursor is not near */
89.md-syntax-inline.hidden,
90.md-syntax-block.hidden,
91.image-alt.hidden,
92.math-source.hidden {
93 display: none;
94}
95
96/* Hide HTML list markers when markdown syntax is visible (not hidden) */
97/* This prevents double bullets/numbers when showing "- " or "1. " */
98li:has(.md-syntax-block:not(.hidden)) {
99 list-style-type: none;
100}
101
102/* ==========================================================================
103 Math
104 ========================================================================== */
105
106/* Math source is hidden by default, shown when syntax is visible */
107.math-source {
108 display: none;
109 color: var(--color-text, #1f1d2e);
110 font-family: var(--font-mono, Consolas, monospace);
111 white-space: pre-wrap;
112 background: color-mix(in srgb, var(--color-primary, #907aa9) 10%, transparent);
113 padding: 0 2px;
114 border-radius: 2px;
115}
116
117/* When syntax is visible (cursor nearby), show source too */
118.math-source:not(.hidden) {
119 display: inline;
120}
121
122/* Rendered math is always visible */
123.math-rendered {
124 display: inline;
125}
126
127.math-display.math-rendered {
128 display: block;
129 text-align: center;
130 margin: 0.5rem 0;
131}
132
133/* Clickable math - click to edit */
134.math-clickable {
135 cursor: pointer;
136}
137
138/* Math error styling */
139.math-error {
140 border: 1px dashed var(--color-error, #b4637a);
141 border-radius: 4px;
142 padding: 2px 6px;
143 background: color-mix(in srgb, var(--color-error, #b4637a) 10%, transparent);
144}
145
146.math-error code {
147 font-family: var(--font-mono, Consolas, monospace);
148 font-size: 0.9em;
149}
150
151/* ==========================================================================
152 Code
153 ========================================================================== */
154
155.weaver-editor-content code {
156 font-family: var(--font-mono, Consolas, monospace);
157 background: var(--color-overlay, #f2e9e1);
158 padding: 0.1em 0.3em;
159 border-radius: 3px;
160}
161
162.weaver-editor-content pre {
163 font-family: var(--font-mono, Consolas, monospace);
164 background: var(--color-overlay, #f2e9e1);
165 padding: 0.5em;
166 border-radius: 4px;
167 overflow-x: auto;
168}
169
170.weaver-editor-content pre code {
171 background: none;
172 padding: 0;
173}
174
175/* ==========================================================================
176 Links
177 ========================================================================== */
178
179.weaver-editor-content a {
180 color: inherit;
181 text-decoration: underline;
182 text-decoration-color: var(--color-muted, #635e74);
183}
184
185/* ==========================================================================
186 Blockquotes
187 ========================================================================== */
188
189.weaver-editor-content blockquote {
190 margin: 0;
191 padding-left: 1em;
192 border-left: 3px solid var(--color-border, #908caa);
193}
194
195/* ==========================================================================
196 Helpers
197 ========================================================================== */
198
199/* Cursor positioning helper after <br> */
200.br-cursor {
201 display: inline-block;
202 font-size: 0;
203 width: 0;
204 height: 1em;
205 line-height: 1em;
206 vertical-align: baseline;
207}
208
209/* ==========================================================================
210 Embeds
211 ========================================================================== */
212
213.weaver-editor-content .embed-placeholder {
214 background: var(--color-overlay, #f2e9e1);
215 border-radius: 4px;
216 padding: 0.5em;
217 display: block;
218}
219
220/* Pending image (before upload) */
221.weaver-editor-content .pending-image {
222 opacity: 0.7;
223 position: relative;
224}
225
226.weaver-editor-content .pending-image::after {
227 content: "Uploading...";
228 position: absolute;
229 bottom: 0.5em;
230 right: 0.5em;
231 background: var(--color-overlay, #f2e9e1);
232 color: var(--color-text, #1f1d2e);
233 padding: 0.2em 0.5em;
234 border-radius: 3px;
235 font-size: 0.8em;
236 border: 1px solid var(--color-border, #908caa);
237}
238
239/* ==========================================================================
240 Footnotes (Editor Mode)
241 ========================================================================== */
242
243/* Inline footnote reference [^name] */
244.footnote-ref {
245 font-family: var(--font-mono, Consolas, monospace);
246 font-size: 0.9rem;
247 color: var(--color-subtle, #4a4560);
248 background: color-mix(in srgb, var(--color-surface, #fffaf3) 10%, transparent);
249 padding: 0 2px;
250}
251
252/* Footnote definition wrapper */
253.footnote-def-editor {
254 margin-bottom: 1rem;
255 margin-top: -1rem;
256 margin-inline-start: 2rem;
257 padding: 0 0.5rem;
258 border-inline-start: 2px solid var(--color-border, #908caa);
259}
260
261/* The [^name]: prefix in definitions */
262.footnote-def-syntax {
263 font-family: var(--font-mono, Consolas, monospace);
264 font-size: 0.9rem;
265 color: var(--color-subtle, #4a4560);
266}
267
268/* Inner paragraphs in footnote defs */
269.footnote-def-editor p {
270 margin: 0;
271 display: inline;
272}
273
274/* ==========================================================================
275 Remote Cursors (Collaborative Editing)
276 ========================================================================== */
277
278.remote-cursors-overlay {
279 position: absolute;
280 top: 0;
281 left: 0;
282 right: 0;
283 bottom: 0;
284 pointer-events: none;
285 z-index: 10;
286}
287
288.remote-cursor {
289 position: absolute;
290 pointer-events: none;
291}
292
293.remote-cursor-caret {
294 width: 2px;
295 height: var(--cursor-height, 1.2em);
296 background-color: var(--cursor-color, #907aa9);
297 border-radius: 1px;
298}
299
300.remote-cursor-label {
301 position: absolute;
302 top: -1.4em;
303 left: 0;
304 background-color: var(--cursor-color, #907aa9);
305 color: white;
306 font-size: 0.7rem;
307 font-family: var(--font-heading, system-ui, sans-serif);
308 padding: 1px 4px;
309 border-radius: 3px 3px 3px 0;
310 white-space: nowrap;
311 max-width: 120px;
312 overflow: hidden;
313 text-overflow: ellipsis;
314}
315
316.remote-selection {
317 position: absolute;
318 pointer-events: none;
319 border-radius: 2px;
320}