oficina / calendar Public

Clone
git clone https://amadan.net/oficina/calendar

Plain git — no account needed to clone.

Download

Download this file

1/* calendar.css — this app's own components.
2 *
3 * Prefix: cal-. Never rst- (rastrillo's namespace, and a future release
4 * may claim a name we took) and never estilo- (the suite's, and these
5 * are not suite components until a second app copies one).
6 *
7 * Grammar: the attribute spelling, matching rastrillo v3 — the KIND is
8 * a bare attribute, a VARIANT is a token in its value matched with ~=,
9 * and a PART is its own flat attribute. Adopted per screen, never per
10 * element.
11 *
12 * Every colour here is a --rst-* token or derived from one with
13 * color-mix. Nothing is a literal hex: the theme's own contrast table
14 * is measured, and a hex dropped in beside it is a value nobody has
15 * measured against anything.
16 */
17
18/* ── The view switcher ─────────────────────────────────────────── */
19
20/* One layout for all four views. Day, Week, Month and Agenda share this
21 * main box, so switching views never moves the header, the toolbar or
22 * the grid's edge (test/browser/views.mjs). 90rem, not rst-page's 64rem
23 * reading column: seven day columns at 64rem are ~134px, too narrow for a
24 * chip's time and title. rst-page's own inline padding is the gutter, the
25 * same 1rem as the estilo bar's, so at 1440 the view's edge lines up with
26 * the bar's brand. */
27[cal-view] { max-width: 90rem; } /* after tokens.css, so it beats rst-page's 64rem */
28
29/* The bar is sticky, so an anchor or :target lands below it, not under
30 * it (shared-chrome spec §5.3). */
31html { scroll-padding-block-start: var(--estilo-bar-block-size); }
32
33/* The toolbar (layout.html "calendar-toolbar"): the steps at the start,
34 * the view switcher at the end, one row wherever it fits. Every label in
35 * it is the same in every view, so nothing in it moves. */
36[cal-bar] {
37 align-items: center;
38 display: flex;
39 flex-wrap: wrap;
40 gap: var(--rst-sp-3);
41 justify-content: space-between;
42 margin-block-end: var(--rst-sp-4);
43}
44
45[cal-bar-steps] {
46 display: flex;
47 gap: var(--rst-sp-2);
48}
49
50/* A view tab is as wide as its label in the current tab's weight (600,
51 * against 550), whether or not it is current: a hidden bold copy of the
52 * label (the cal-tab attribute) sizes the column. Without it the switcher
53 * narrowed and widened by a fraction of a pixel with every view, and at
54 * the end of the row that moved it. */
55[cal-tab] { display: inline-grid; text-align: center; }
56[cal-tab]::after {
57 block-size: 0;
58 content: attr(cal-tab);
59 font-weight: 600;
60 overflow: hidden;
61 visibility: hidden;
62}
63
64[cal-bar-spacer] { flex: 1 1 auto; }
65
66/* The day's sentence. It is the page's opening line, so it reads at
67 * body size rather than as a caption — a summary set in small grey
68 * type is a summary people learn to skip. */
69[cal-sentence] {
70 color: var(--rst-text);
71 margin: 0 0 var(--rst-sp-4);
72 max-width: 52rem;
73}
74
75/* The agenda's scope line: a caption, not an answer, so it is muted. */
76[cal-sentence-muted] { color: var(--rst-text-muted); }
77
78/* ── Month ─────────────────────────────────────────────────────── */
79
80/* A real table: a month IS tabular data, so the row and column headers
81 * come free for a screen reader and a scriptless page keeps working
82 * semantics a div grid would have to rebuild with ARIA. */
83[cal-month] {
84 border-collapse: collapse;
85 table-layout: fixed;
86 width: 100%;
87}
88
89[cal-month] th {
90 color: var(--rst-text-muted);
91 font-size: var(--rst-fs-sm);
92 font-weight: 600;
93 padding: var(--rst-sp-2);
94 text-align: start;
95}
96
97[cal-month] td {
98 border: 1px solid var(--rst-line);
99 height: 7.5rem;
100 padding: 0;
101 vertical-align: top;
102}
103
104[cal-day-cell] {
105 display: flex;
106 flex-direction: column;
107 gap: 2px;
108 height: 100%;
109 padding: var(--rst-sp-1);
110}
111
112/* Outside the month: dimmed, but never hidden. A month grid whose
113 * leading and trailing days are blank makes the first week look
114 * broken. */
115[cal-day-cell~="outside"] { opacity: 0.55; }
116
117[cal-day-cell~="weekend"] { background: var(--rst-surface-2); }
118
119[cal-day-num] {
120 color: var(--rst-text-muted);
121 display: block;
122 font-size: var(--rst-fs-sm);
123 padding: 2px;
124 text-decoration: none;
125}
126
127[cal-day-num]:hover { text-decoration: underline; }
128
129/* Today. Three signals, never colour alone: a filled marker, bold
130 * weight, and the visually-hidden word "today" in the link's
131 * accessible name. */
132[cal-day-num~="today"] {
133 background: var(--rst-accent);
134 border-radius: var(--rst-radius-pill);
135 color: var(--rst-on-accent);
136 font-weight: 700;
137 inline-size: 1.6rem;
138 text-align: center;
139}
140
141[cal-more] {
142 color: var(--rst-text-muted);
143 font-size: var(--rst-fs-xs);
144 padding-inline-start: 2px;
145}
146
147/* ── Chips ─────────────────────────────────────────────────────── */
148
149/* One event, wherever it appears. The hue is set inline per calendar
150 * as --cal-hue, and every colour below is mixed from it against a
151 * theme token — so a chip stays legible in both schemes without the
152 * calendar's colour being a measured value of its own. */
153[cal-chip] {
154 align-items: baseline;
155 background: color-mix(in oklab, hsl(var(--cal-hue, 220) 60% 50%) 14%, var(--rst-surface));
156 border-inline-start: 3px solid hsl(var(--cal-hue, 220) 55% 45%);
157 border-radius: 0;
158 color: var(--rst-text);
159 display: flex;
160 font-size: var(--rst-fs-sm);
161 gap: var(--rst-sp-1);
162 overflow: hidden;
163 padding: 2px var(--rst-sp-1);
164 text-decoration: none;
165 white-space: nowrap;
166}
167
168[cal-chip]:hover { text-decoration: underline; }
169
170[cal-chip-time] {
171 color: var(--rst-text-muted);
172 flex: none;
173 font-variant-numeric: tabular-nums;
174}
175
176[cal-chip-title] {
177 overflow: hidden;
178 text-overflow: ellipsis;
179}
180
181/* The past is dimmed AND written in the past tense — the tense is in
182 * the markup, so the meaning survives greyscale and a stylesheet that
183 * failed to load. */
184[cal-chip~="past"] { opacity: 0.6; }
185
186/* A cancelled event is struck through and says "Cancelled" in its own
187 * text. Never the line alone. */
188[cal-chip~="cancelled"] [cal-chip-title] { text-decoration: line-through; }
189
190/* A note is a thing that is true of a day without occupying it, so it
191 * is drawn as an outline rather than a filled block. */
192[cal-chip~="note"] {
193 background: transparent;
194 border: 1px dashed color-mix(in oklab, hsl(var(--cal-hue, 220) 55% 45%) 60%, var(--rst-line));
195 border-inline-start-width: 3px;
196}
197
198/* A commitment is yours rather than shared: a quieter fill than a
199 * meeting, so a day of your own work does not read as a day of
200 * meetings. */
201[cal-chip~="commitment"] {
202 background: color-mix(in oklab, hsl(var(--cal-hue, 220) 60% 50%) 7%, var(--rst-surface));
203}
204
205[cal-chip~="tentative"] {
206 border-inline-start-style: dotted;
207}
208
209/* ── Day and week columns ──────────────────────────────────────── */
210
211[cal-grid] {
212 display: grid;
213 gap: 0;
214 grid-template-columns: 3.5rem 1fr;
215 /* The grid scrolls inside the first screen, but never below 24rem: on
216 * a short window (or a phone on its side) 100vh - 20rem is a sliver. */
217 max-block-size: max(24rem, calc(100vh - 20rem));
218 overflow: auto;
219}
220
221[cal-week-grid] {
222 display: grid;
223 gap: 0;
224 grid-template-columns: 3.5rem repeat(7, minmax(6rem, 1fr));
225}
226
227[cal-week-scroll] {
228 /* The grid scrolls inside the first screen, but never below 24rem: on
229 * a short window (or a phone on its side) 100vh - 20rem is a sliver. */
230 max-block-size: max(24rem, calc(100vh - 20rem));
231 overflow: auto;
232}
233
234[cal-hours] {
235 border-inline-end: 1px solid var(--rst-line);
236 position: relative;
237}
238
239[cal-hour] {
240 block-size: 3rem;
241 color: var(--rst-text-faint);
242 font-size: var(--rst-fs-xs);
243 font-variant-numeric: tabular-nums;
244 padding-inline-end: var(--rst-sp-2);
245 text-align: end;
246 /* The label sits at the line it names, not in the box below it. */
247 transform: translateY(-0.5em);
248}
249
250/* The day column. 72rem is 24 hours at 3rem each, so an hour label and
251 * the grid line beside it stay in step. */
252[cal-column] {
253 block-size: 72rem;
254 border-inline-end: 1px solid var(--rst-line);
255 position: relative;
256}
257
258[cal-column-head] {
259 /* A fixed height, so the all-day row can stick exactly beneath it. */
260 align-items: center;
261 block-size: var(--cal-week-head-size);
262 border-block-end: 1px solid var(--rst-line);
263 box-sizing: border-box;
264 display: flex;
265 justify-content: center;
266 padding: 0 var(--rst-sp-2);
267 position: sticky;
268 text-align: center;
269 /* 0, not --estilo-bar-block-size: the heads stick inside
270 * [cal-week-scroll], which is their own scroll box, so the sticky bar
271 * above the page never overlaps them. The bar's offset here left a 52px
272 * band of hour rows painted above the day names. */
273 top: 0;
274 z-index: 2;
275 background: var(--rst-bg);
276}
277
278[cal-column-head~="today"] { font-weight: 700; }
279
280[cal-week-grid] { --cal-week-head-size: 2.5rem; }
281
282/* The hour rules, drawn as a repeating background so 24 of them cost
283 * one declaration rather than 24 elements. */
284[cal-column-rules] {
285 background-image: repeating-linear-gradient(
286 to bottom,
287 var(--rst-line) 0,
288 var(--rst-line) 1px,
289 transparent 1px,
290 transparent 3rem
291 );
292 inset: 0;
293 position: absolute;
294}
295
296/* An empty half hour, as a link. This is what makes "click a time to
297 * create an event" work with no JavaScript: 48 ordinary links per day,
298 * each with a screen-reader label naming its time. */
299[cal-slot] {
300 display: block;
301 inset-inline: 0;
302 position: absolute;
303}
304
305[cal-slot]:hover {
306 background: color-mix(in oklab, var(--rst-accent) 10%, transparent);
307}
308
309[cal-slot]:focus-visible {
310 outline: 2px solid var(--rst-accent);
311 outline-offset: -2px;
312}
313
314/* A placed event. top/height/left/width arrive as inline style from
315 * the server's own packer — rastrillo's CSP allows inline styles, so
316 * this needs no exception. */
317[cal-placed] {
318 position: absolute;
319 z-index: 1;
320}
321
322[cal-placed] [cal-chip] {
323 block-size: 100%;
324 align-items: flex-start;
325 flex-direction: column;
326 gap: 0;
327 white-space: normal;
328}
329
330/* Under an hour there is room for one line, so time and title share
331 * it. Stacked, the title is the second line and the first thing the
332 * chip's own overflow cuts off. */
333[cal-placed~="short"] [cal-chip] {
334 align-items: baseline;
335 flex-direction: row;
336 gap: var(--rst-sp-1);
337 line-height: 1.15;
338 padding-block: 0;
339 white-space: nowrap;
340}
341
342/* The all-day strip above the timed grid. All-day events are not
343 * packed into the column: giving a birthday a height would make it
344 * look like a 24-hour meeting. */
345[cal-allday] {
346 border-block-end: 1px solid var(--rst-line);
347 display: flex;
348 flex-wrap: wrap;
349 gap: var(--rst-sp-1);
350 padding: var(--rst-sp-2);
351}
352
353/* In the week the all-day strip is one ROW of the grid, a cell per
354 * day, so every day's cell is as tall as the busiest one and the
355 * timed columns below all start on the same line. */
356[cal-allday="week"] {
357 align-content: flex-start;
358 border-inline-end: 1px solid var(--rst-line);
359 flex-direction: column;
360 flex-wrap: nowrap;
361 min-inline-size: 0;
362 padding: var(--rst-sp-1);
363}
364
365/* The week's all-day row sticks under the day headings. The grid opens
366 * scrolled to working hours, and a row that scrolled away with midnight
367 * hid every all-day event from the first screen. */
368[cal-allday="week"], [cal-allday-label] {
369 background: var(--rst-bg);
370 position: sticky;
371 top: var(--cal-week-head-size);
372 z-index: 2;
373}
374
375[cal-allday-label] {
376 border-block-end: 1px solid var(--rst-line);
377 border-inline-end: 1px solid var(--rst-line);
378 color: var(--rst-text-faint);
379 font-size: var(--rst-fs-xs);
380 padding: var(--rst-sp-1) var(--rst-sp-2) 0 0;
381 text-align: end;
382}
383
384/* ── The whisper ───────────────────────────────────────────────── */
385
386/* An event authored in another zone. The primary time is always the
387 * reader's own; this is a note beside it, never the headline. */
388[cal-elsewhere] {
389 color: var(--rst-text-faint);
390 font-size: var(--rst-fs-xs);
391}
392
393/* ── Narrow screens ────────────────────────────────────────────── */
394
395/* At 320px the month reflows to a stacked list of days. A seven-column
396 * grid at that width is seven columns of nothing.
397 *
398 * Week keeps its two dimensions and scrolls sideways: a week view IS a
399 * two-dimensional comparison, and flattening it to a list makes it the
400 * agenda, which already exists. */
401@media (max-width: 40rem) {
402 [cal-month], [cal-month] thead { display: block; }
403 [cal-month] thead { display: none; }
404 [cal-month] tbody, [cal-month] tr { display: block; }
405 [cal-month] td { display: block; height: auto; min-height: 2.5rem; }
406 /* A day with nothing in it is not worth a row of its own on a
407 * phone. */
408 [cal-month] td:not(:has([cal-chip])):not(:has([cal-day-num~="today"])) { display: none; }
409 [cal-day-cell] { flex-direction: row; align-items: baseline; gap: var(--rst-sp-2); }
410
411 [cal-week-scroll] { overflow-x: auto; }
412 [cal-week-grid] { min-inline-size: 48rem; }
413}
414
415/* ── Motion ────────────────────────────────────────────────────── */
416
417@media (prefers-reduced-motion: reduce) {
418 [cal-slot], [cal-chip] { transition: none; }
419}
420
421/* ── Quick add ─────────────────────────────────────────────────── */
422
423/* The header's action group. Quick add sits beside New event rather
424 * than replacing it: one is the fast path, the other is the one that
425 * shows every field. */
426[cal-header-actions] {
427 align-items: center;
428 display: flex;
429 flex-wrap: wrap;
430 gap: var(--rst-sp-2);
431}
432
433/* The disclosure is a <details>, so it opens with no script at all.
434 * Everything below is appearance; none of it is behaviour. */
435[cal-quick] { position: relative; }
436
437/* The closed state reads as a small text input, because that is what it
438 * behaves like — click it and type. The marker is removed in both
439 * spellings: Safari still wants the -webkit- pseudo-element and leaving
440 * it in puts a disclosure triangle inside what looks like a field. */
441[cal-quick] > summary {
442 align-items: center;
443 background: var(--rst-surface);
444 border: 1px solid var(--rst-line);
445 border-radius: var(--rst-radius-sm);
446 color: var(--rst-text-muted);
447 cursor: text;
448 display: flex;
449 font-size: var(--rst-fs-sm);
450 gap: var(--rst-sp-1);
451 list-style: none;
452 min-width: 12rem;
453 padding: var(--rst-sp-2) var(--rst-sp-3);
454}
455
456[cal-quick] > summary::-webkit-details-marker { display: none; }
457
458[cal-quick] > summary:hover { border-color: var(--rst-accent); }
459
460[cal-quick][open] > summary {
461 border-color: var(--rst-accent);
462 color: var(--rst-text);
463}
464
465/* The popover. Absolute so opening it does not push the calendar down
466 * the page — the grid behind stays exactly where it was, which is what
467 * makes this feel like a panel rather than a page change. */
468[cal-quick-form] {
469 background: var(--rst-surface);
470 border: 1px solid var(--rst-line);
471 /* A float, so the suite's float radius and shadow (estilo menu.css;
472 * shared-chrome spec §11), not a hand-built 6px and shadow of its own. */
473 border-radius: var(--estilo-float-radius);
474 box-shadow: var(--rst-shadow-pop);
475 /* Border-box, here and on the textarea below: both are width: 100%
476 * on a phone, and content-box added the padding and border on top,
477 * so the open panel ran ~15px past the right edge at 390px and the
478 * page scrolled sideways. TestQuickAddOnANarrowScreen (make browser)
479 * measures it. */
480 box-sizing: border-box;
481 /* Anchored to the END edge, so the panel opens back across the page
482 * instead of off the side of it. The box sits at the far right of the
483 * header, beside New event: anchored at the start edge a 30rem panel
484 * hangs ~28px past a 1280px viewport, which every string assertion in
485 * the Go suite happily passes. The browser gate measured it. */
486 inset-inline-end: 0;
487 margin-block-start: var(--rst-sp-1);
488 padding: var(--rst-sp-3);
489 position: absolute;
490 top: 100%;
491 width: min(30rem, 88vw);
492 z-index: 30;
493}
494
495[cal-quick-text] {
496 background: var(--rst-bg);
497 border: 1px solid var(--rst-line);
498 border-radius: var(--rst-radius-sm);
499 box-sizing: border-box;
500 color: var(--rst-text);
501 display: block;
502 font: inherit;
503 padding: var(--rst-sp-2);
504 resize: vertical;
505 width: 100%;
506}
507
508/* iOS zooms the page into any text control under 16px, and tokens.css
509 * brings controls up to 16px where the pointer is coarse. The box above
510 * sets `font: inherit` with a selector that outweighs tokens.css's bare
511 * `textarea`, and fell back to 14px. Same rule, same max(), restated
512 * here at its weight. TestNoZoomOnTap (make browser) measures it. */
513@media (pointer: coarse) {
514 [cal-quick-text] {
515 font-size: max(1rem, 1em);
516 }
517}
518
519[cal-quick-pane] {
520 background: var(--rst-surface-2);
521 border-radius: var(--rst-radius-sm);
522 font-size: var(--rst-fs-sm);
523 margin-block: var(--rst-sp-2);
524 padding: var(--rst-sp-2) var(--rst-sp-3);
525}
526
527[cal-quick-blank] { color: var(--rst-text-muted); margin: 0; }
528
529[cal-quick-detail] { margin: 0; }
530
531[cal-quick-row] {
532 display: grid;
533 gap: var(--rst-sp-2);
534 grid-template-columns: 8rem 1fr;
535 padding-block: var(--rst-sp-1);
536}
537
538[cal-quick-row] dt { color: var(--rst-text-muted); margin: 0; }
539[cal-quick-row] dd { margin: 0; }
540
541/* The caveat rides in the LABEL. Somebody who reads only the left
542 * column still learns that nothing was emailed. */
543[cal-quick-caveat] { color: var(--rst-text-faint); font-size: var(--rst-fs-xs); }
544
545[cal-quick-people] { list-style: none; margin: 0; padding: 0; }
546
547[cal-quick-notes] {
548 color: var(--rst-text-muted);
549 font-size: var(--rst-fs-xs);
550 margin: var(--rst-sp-2) 0 0;
551 padding-inline-start: var(--rst-sp-4);
552}
553
554[cal-quick-actions] {
555 align-items: center;
556 display: flex;
557 flex-wrap: wrap;
558 gap: var(--rst-sp-2);
559}
560
561[cal-quick-hint] {
562 color: var(--rst-text-faint);
563 font-size: var(--rst-fs-xs);
564 flex: 1 1 12rem;
565}
566
567/* Narrow: the popover stops floating and becomes part of the page. A
568 * 30rem panel pinned to a header on a 320px screen is off the side of
569 * it. */
570@media (max-width: 40rem) {
571 [cal-header-actions] { width: 100%; }
572 [cal-quick] { flex: 1 1 100%; }
573 [cal-quick] > summary { min-width: 0; }
574 [cal-quick-form] {
575 box-shadow: none;
576 position: static;
577 width: 100%;
578 }
579 [cal-quick-row] { grid-template-columns: 1fr; gap: 0; }
580}
581
582/* The keyboard hint. Revealed by quickadd.js, never by the template:
583 * with no script Enter is just a newline, and advertising a shortcut
584 * the page cannot honour is worse than staying quiet. */
585[cal-quick-key] {
586 color: var(--rst-text-faint);
587 font-size: var(--rst-fs-xs);
588}
589
590/* ── Booking pages, the host's side ─────────────────────────────── */
591
592[cal-book-pane] {
593 background: var(--rst-surface-2);
594 border-radius: var(--rst-radius-sm);
595 font-size: var(--rst-fs-sm);
596 margin-block: var(--rst-sp-2) var(--rst-sp-4);
597 padding: var(--rst-sp-2) var(--rst-sp-3);
598}
599
600[cal-book-blank] { color: var(--rst-text-muted); margin: 0; }
601
602[cal-book-lines] { margin: 0; padding-inline-start: var(--rst-sp-4); }
603
604/* Problems first, and unmistakably: the sentence cannot be saved while
605 * one stands. */
606[cal-book-problems] {
607 color: var(--rst-tone-negative-fg);
608 margin: 0 0 var(--rst-sp-2);
609 padding-inline-start: var(--rst-sp-4);
610}
611
612[cal-book-page] { margin-block-end: var(--rst-sp-4); }
613
614[cal-book-page-body] { padding: var(--rst-sp-3); }
615
616[cal-book-url] { font-size: var(--rst-fs-sm); overflow-wrap: anywhere; }
617
618[cal-book-page-actions] {
619 align-items: flex-start;
620 display: flex;
621 flex-wrap: wrap;
622 gap: var(--rst-sp-3);
623 margin-block-start: var(--rst-sp-3);
624}
625
626/* The publish sentence sits above its own button and nowhere else. */
627[cal-book-caveat] {
628 color: var(--rst-text-muted);
629 font-size: var(--rst-fs-xs);
630 margin: 0 0 var(--rst-sp-2);
631 max-width: 40rem;
632}
633
634[cal-booked-when] { margin: 0; }
635
636/* ── Booking, the stranger's side ────────────────────────────────── */
637
638[cal-book-zone-form] {
639 align-items: center;
640 display: flex;
641 flex-wrap: wrap;
642 gap: var(--rst-sp-2);
643 margin-block-end: var(--rst-sp-4);
644}
645
646[cal-book-days] { list-style: none; margin: 0; padding: 0; }
647[cal-book-days] li { padding-block: var(--rst-sp-1); }
648[cal-book-days] small { color: var(--rst-text-muted); margin-inline-start: var(--rst-sp-2); }
649
650/* Each slot is its own form: a button that posts an instant. */
651[cal-book-slots] {
652 display: flex;
653 flex-wrap: wrap;
654 gap: var(--rst-sp-2);
655 margin-block: var(--rst-sp-3);
656}
657
658[cal-book-details] { padding: var(--rst-sp-3); }
659
660[cal-book-manage-actions] {
661 align-items: center;
662 display: flex;
663 flex-wrap: wrap;
664 gap: var(--rst-sp-2);
665 margin-block: var(--rst-sp-4) var(--rst-sp-2);
666}
667
668/* The booker's closing row (rastrillo's form-foot, reached through our
669 * own form's attribute: this file names no rst- selector). form-foot
670 * draws its buttons at the lg size, and on a phone "Hold this time" and
671 * "Pick another time" no longer fit side by side; without wrap the row
672 * squeezes them into two- and three-line labels. Wrapping puts the
673 * second button on a row of its own instead.
674 * TestFormFootOnANarrowScreen (make browser) measures it. */
675[cal-book-details] > div:has(> button[type="submit"]) {
676 flex-wrap: wrap;
677}
678
679/* ── Layout that used to be style attributes ──────────────────────────
680 * rastrillo's CSP (fb806a2) refuses style attributes by default. These
681 * were constant, so they live here; what is still an attribute is a
682 * per-event or per-calendar value (serving.go says which, and why the
683 * policy keeps 'unsafe-inline' for them). */
684[cal-day-chips] {
685 display: flex;
686 flex-direction: column;
687 gap: var(--rst-sp-1);
688 padding: var(--rst-sp-3);
689}
690[cal-box-body] { padding: var(--rst-sp-3); }
691[cal-reminder] {
692 display: flex;
693 align-items: center;
694 gap: var(--rst-sp-2);
695}
696[cal-reminder-add] {
697 display: flex;
698 align-items: flex-end;
699 gap: var(--rst-sp-2);
700 margin-top: var(--rst-sp-3);
701}
702[cal-feed-new] { margin-top: var(--rst-sp-4); }
703/* A calendar's swatch on the Calendars list: its hue, the one value the
704 * attribute still carries. */
705[cal-dot] {
706 background: hsl(var(--cal-hue, 220) 55% 45%);
707 border-radius: var(--rst-radius-pill);
708 inline-size: 12px;
709 block-size: 12px;
710}
711