A calm place to write long-form, and publish it to the open social web. skypress.blog/
0

Configure Feed

Select the types of activity you want to include in your feed.

at trunk 11 kB View raw
1/** 2 * Studio (editor) chrome styles. 3 * 4 * The Studio is a `client:only` React island, so Astro's component-scoped styles 5 * never reach its DOM — these rules must be global. Shared by the real editor 6 * page (`src/pages/editor.astro`). 7 * 8 * The signed-in bars (mode / publish) and the editor surface share one centred 9 * content column so they line up with each other. 10 */ 11 12:root { 13 /* Content column shared by the studio bars and the editor surface. */ 14 --studio-measure: 60rem; 15 --studio-gutter: 1.25rem; 16} 17 18.studio__loading { 19 max-width: var(--studio-measure); 20 margin: 0 auto; 21 padding: 2rem var(--studio-gutter); 22 color: var(--muted); 23} 24 25/* Login (signed out). The `.login__*` form rules are shared with the dashboard 26 and live in `login.css` (imported by editor.astro alongside this file). */ 27.studio__login { 28 max-width: 30rem; 29 margin: 0 auto; 30 padding: 4rem 1.5rem; 31} 32.studio__error { 33 color: var(--ember); 34 font-size: 0.9rem; 35} 36/* Same alignment when the error sits on its own above the editor column (the 37 signed-in `?edit=` load-failure notice) rather than inside the login card. */ 38.studio__error--banner { 39 max-width: var(--studio-measure); 40 margin: 0.5rem auto 0; 41 padding: 0 var(--studio-gutter); 42} 43 44/* Publish panel */ 45.publish { 46 display: flex; 47 flex-wrap: wrap; 48 align-items: center; 49 gap: 0.75rem; 50 max-width: var(--studio-measure); 51 margin: 0 auto; 52 padding: 0.75rem var(--studio-gutter); 53} 54.publish__target { 55 display: inline-flex; 56 align-items: center; 57 gap: 0.4rem; 58 font-size: 0.85rem; 59 color: var(--muted); 60} 61.publish__target--fixed strong { 62 color: var(--ink); 63} 64.publish__select { 65 padding: 0.45rem 0.6rem; 66 border: 1px solid var(--line-strong); 67 border-radius: 8px; 68 background: var(--paper-raised); 69 font: inherit; 70 font-size: 0.9rem; 71} 72.publish__button { 73 padding: 0.5rem 1rem; 74 border: 0; 75 border-radius: 8px; 76 background: var(--sun); 77 color: #fff; 78 font: inherit; 79 font-weight: 600; 80 cursor: pointer; 81} 82.publish__button:disabled { 83 opacity: 0.5; 84 cursor: not-allowed; 85} 86.publish__cancel { 87 padding: 0.5rem 0.9rem; 88 border: 1px solid var(--line-strong); 89 background: var(--paper-raised); 90 border-radius: 8px; 91 font: inherit; 92 cursor: pointer; 93} 94.publish__confirm { 95 flex: 1 1 100%; 96 background: var(--sun-tint); 97 border: 1px solid var(--line-strong); 98 border-radius: 10px; 99 padding: 0.85rem 1rem; 100} 101.publish__warning { 102 margin: 0 0 0.75rem; 103} 104.publish__actions { 105 display: flex; 106 gap: 0.75rem; 107 flex-wrap: wrap; 108} 109.publish__status, 110.publish__error { 111 flex: 1 1 100%; 112 font-size: 0.9rem; 113} 114.publish__error { 115 color: var(--ember); 116} 117.publish__count { 118 margin: 0; 119 font-size: 0.8rem; 120 color: var(--muted); 121} 122.publish__count--over { 123 /* Fixed red, NOT a theme token: --ember is recolored per publication 124 (themes.ts), which could leave this over-limit warning unreadable. */ 125 color: #b00020; 126 font-weight: 600; 127} 128 129/* Mode bar */ 130.studio__mode { 131 display: flex; 132 align-items: center; 133 justify-content: space-between; 134 gap: 1rem; 135 max-width: var(--studio-measure); 136 margin: 0 auto; 137 padding: 0.5rem var(--studio-gutter); 138 font-size: 0.85rem; 139 color: var(--muted); 140} 141.studio__mode button { 142 border: 1px solid var(--line-strong); 143 background: var(--paper-raised); 144 border-radius: 6px; 145 padding: 0.25rem 0.7rem; 146 font: inherit; 147 cursor: pointer; 148} 149 150/* Borderless article title, sitting above the framed editor canvas — echoes the 151 block-editor post title (large display heading, no box). A `<textarea>` (not a 152 single-line input) so long titles wrap and the field auto-grows to fit instead 153 of clipping on one line — it stays single-line semantically (Enter is blocked 154 in the markup). Auto-grows via JS, like the lede; resize/overflow off. */ 155.studio__title { 156 display: block; 157 max-width: var(--studio-measure); 158 margin: 1.25rem auto 0; 159 padding: 0 var(--studio-gutter); 160 width: 100%; 161 box-sizing: border-box; 162 border: 0; 163 background: transparent; 164 color: var(--ink); 165 font-family: var(--font-display); 166 font-size: clamp(1.9rem, 4vw, 2.6rem); 167 font-weight: 700; 168 line-height: 1.15; 169 resize: none; 170 overflow: hidden; 171 overflow-wrap: break-word; 172} 173.studio__title::placeholder { 174 color: var(--muted); 175 opacity: 0.6; 176} 177.studio__title:focus { 178 outline: none; 179} 180/* Italic lede under the title — echoes the title (display face, borderless) but quieter: 181 smaller, muted, italic. Auto-grows via JS (resize/overflow off). */ 182.studio__lede { 183 display: block; 184 max-width: var(--studio-measure); 185 margin: 0.5rem auto 0; 186 padding: 0 var(--studio-gutter); 187 width: 100%; 188 box-sizing: border-box; 189 border: 0; 190 background: transparent; 191 color: var(--muted); 192 font-family: var(--font-display); 193 font-size: 1.2rem; 194 font-style: italic; 195 line-height: 1.4; 196 resize: none; 197 overflow: hidden; 198} 199.studio__lede::placeholder { 200 color: var(--muted); 201 opacity: 0.6; 202} 203.studio__lede:focus { 204 outline: none; 205} 206.studio__lede-hint { 207 max-width: var(--studio-measure); 208 margin: 0.25rem auto 0; 209 padding: 0 var(--studio-gutter); 210 font-size: 0.8rem; 211 color: var(--muted); 212} 213/* Tighten the gap between the lede (or its hint) and the editor surface below. */ 214.studio__lede + .skypress-editor, 215.studio__lede-hint + .skypress-editor { 216 margin-top: 0.75rem; 217} 218 219/* Editor surface. We compose @wordpress/block-editor directly (Decision 0021), 220 so these rules target our own chrome (`.skypress-editor__*`) plus the standard 221 `.block-editor-*`/`.components-*` classes — not isolated-block-editor's old 222 `.iso-*` DOM. The bundled block CSS hard-codes light surfaces and near-black 223 ink that ignore `prefers-color-scheme`; we frame the editor as a contained 224 writing panel and drive every colour from the design tokens so it follows 225 light/dark like the rest of the app. */ 226.skypress-editor { 227 max-width: var(--studio-measure); 228 margin: 1.5rem auto 3rem; 229 background-color: var(--paper-raised); 230 border: 1px solid var(--line-strong); 231 border-radius: var(--radius); 232 color: var(--ink); 233 box-shadow: var(--shadow); 234} 235/* Toolbar (our chrome): the block inserter on the left; undo/redo and the 236 block-settings cog pushed to the right by the spacer. Block-editor SVG icons 237 use `fill: currentColor`, so tinting the buttons to the ink token themes them 238 too — including the cog and inserter, which sit outside the floating toolbar. */ 239.skypress-editor__toolbar { 240 display: flex; 241 align-items: center; 242 gap: 0.25rem; 243 padding: 0.5rem 0.75rem; 244 border-bottom: 1px solid var(--line); 245} 246.skypress-editor__toolbar-spacer { 247 flex: 1 1 auto; 248} 249.skypress-editor__toolbar .components-button { 250 color: var(--ink); 251} 252/* The writing canvas. `min-height` keeps the panel tall enough to invite writing 253 even when empty; the gutter matches the title/lede column above. */ 254.skypress-editor__body { 255 min-height: 60vh; 256 padding: 1rem var(--studio-gutter) 2rem; 257} 258 259/* The fixed `<BlockToolbar>` sits in our header, and toolbar popovers (link 260 editing, the "more" format menu) portal into the `Popover.Slot` inside 261 `.skypress-editor`. Both re-skin from the tokens here — without this the 262 toolbar reads as a light slab in dark mode. */ 263.skypress-editor .components-accessible-toolbar, 264.skypress-editor .components-toolbar, 265.skypress-editor .components-toolbar-group { 266 background-color: var(--paper-raised); 267 border-color: var(--line-strong); 268 color: var(--ink); 269} 270.skypress-editor .components-toolbar-group { 271 border-right-color: var(--line); 272} 273.skypress-editor .components-accessible-toolbar .components-button { 274 color: var(--ink); 275} 276/* Block-settings inspector, opened as a popover by the cog. The bare 277 `BlockInspector` has no width of its own, so give it the standard editor 278 sidebar width. The class is unique to this editor, so the rule is unscoped. */ 279.skypress-editor__inspector .components-popover__content { 280 width: 280px; 281 max-width: calc( 100vw - 2rem ); 282} 283 284.skypress-editor__status { 285 margin: 0.75rem 0 0; 286 color: var(--muted); 287 font-size: 0.85rem; 288} 289/* Idle (no save feedback yet): collapse the live region out of view without 290 leaving an empty gap. We can't use `display: none` here — that removes the 291 element from the accessibility tree, and an `aria-live` region must stay 292 rendered before its content changes for the first update to be announced. 293 Clip it to zero size instead so it remains in the tree but takes no space. */ 294.skypress-editor__status:empty { 295 position: absolute; 296 width: 1px; 297 height: 1px; 298 margin: -1px; 299 padding: 0; 300 overflow: hidden; 301 clip: rect(0, 0, 0, 0); 302 white-space: nowrap; 303 border: 0; 304} 305 306/* Cover image picker — a labeled strip below the editor, in the shared content 307 column. Distinct from the editor canvas; the chosen image is the article's 308 explicit cover (else the first body image is used). */ 309.studio__cover { 310 max-width: var(--studio-measure); 311 margin: 0 auto 3rem; 312 padding: 0 var(--studio-gutter); 313} 314.studio__cover-label { 315 display: block; 316 margin-bottom: 0.5rem; 317 font-size: 0.85rem; 318 font-weight: 600; 319 color: var(--ink); 320} 321.studio__cover-empty { 322 display: flex; 323 flex-direction: column; 324 gap: 0.4rem; 325 align-items: flex-start; 326} 327.studio__cover-hint { 328 margin: 0; 329 font-size: 0.8rem; 330 color: var(--muted); 331} 332.studio__cover-preview { 333 display: flex; 334 flex-direction: column; 335 gap: 0.6rem; 336 align-items: flex-start; 337} 338.studio__cover-image { 339 max-width: 100%; 340 max-height: 18rem; 341 border: 1px solid var(--line-strong); 342 border-radius: var(--radius); 343} 344.studio__cover-actions { 345 display: flex; 346 gap: 0.6rem; 347} 348.studio__cover-error { 349 margin: 0.5rem 0 0; 350 font-size: 0.8rem; 351 color: var(--ember); 352} 353 354/* Publish success pill — sunrise callback, rises into view (Studio-owned). 355 Deliberately uses a fixed warm palette, NOT the --sun* or --ink tokens: those 356 flip with the colour scheme, and no single text colour stays legible over a 357 gradient whose --sun-tint end goes near-black in dark mode. A constant light 358 sunrise gradient + dark ink keeps the look and clears WCAG AA in both schemes 359 (≈7.5:1 over the gold end, ≈12:1 over the peach). */ 360.studio__published { 361 width: fit-content; 362 max-width: var(--studio-measure); 363 margin: 0.35rem auto 0; 364 display: flex; 365 align-items: center; 366 gap: 0.6rem; 367 padding: 0.5rem 1rem; 368 border-radius: 999px; 369 background: linear-gradient(100deg, #fde4c4, #f4a72c); 370 color: #3a2200; 371 font-size: 0.9rem; 372 font-weight: 600; 373 box-shadow: 0 1px 8px rgba(232, 146, 12, 0.3); 374 animation: studio-published-rise 400ms ease-out; 375} 376 377.studio__published-link { 378 color: #3a2200; 379 font-weight: 700; 380 text-decoration: underline; 381 white-space: nowrap; 382} 383 384@keyframes studio-published-rise { 385 from { 386 opacity: 0; 387 transform: translateY(0.5rem); 388 } 389 to { 390 opacity: 1; 391 transform: translateY(0); 392 } 393} 394 395@media (prefers-reduced-motion: reduce) { 396 .studio__published { 397 animation: none; 398 } 399} 400 401/* @-mention autocomplete row (portaled into the editor's completer popover). */ 402.skypress-mention-option { 403 display: flex; 404 align-items: center; 405 gap: 0.4rem; 406} 407.skypress-mention-option__avatar { 408 border-radius: 50%; 409} 410.skypress-mention-option__handle { 411 color: var(--muted); 412} 413 414/* Rendered mention link in the article — inherits link styling; hook for theming. */ 415.skypress-mention { 416 text-decoration: underline; 417}