cmu-web-kilt 0.6.5

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.
data/css/cmu-cms.css ADDED
@@ -0,0 +1,1433 @@
1
+ /* cmu-cms.css: content components for pages built on the CMU web template
2
+ (www.cmu.edu/common/standard-v6). For CMS sites and apps alike; apps add
3
+ cmu-app.css on top.
4
+
5
+ Rules: link the template's own CSS (main.6.7.min.css) and use its classes
6
+ as they are (a.btn, .btn.ghost, a.cta, table.alternate, .sr-only). Never
7
+ copy its rules or values. Add a cmu-* class only where the template has
8
+ nothing. */
9
+
10
+ /* The hidden attribute always hides, even where a kit or template rule sets
11
+ display (such as a bold form label) */
12
+ [hidden] {
13
+ display: none !important;
14
+ }
15
+
16
+ :root {
17
+ --cmu-red: #c41230;
18
+ --cmu-ink: #22262a;
19
+ --cmu-muted: #5b6670;
20
+ --cmu-line: #d9dde1;
21
+ --cmu-tint: #f4f5f6;
22
+ --cmu-green: #1d5a3a;
23
+ --cmu-green-fill: #00853e;
24
+ --cmu-green-tint: #e3f1ea;
25
+ --cmu-amber: #6b4d00;
26
+ --cmu-amber-tint: #fff4d6;
27
+ --cmu-gold: #fdb515;
28
+ --cmu-gray: #4a535b;
29
+ --cmu-gray-tint: #eceef0;
30
+ --cmu-red-tint: #fdf2f3;
31
+ --cmu-blue: #043673; /* the template's blue */
32
+ --cmu-link: #941120; /* the template's link color */
33
+ --cmu-link-hover: #f00;
34
+ --cmu-blue-tint: #e9eff7;
35
+ /* Checkboxes, radio buttons, sliders and progress bars in CMU red instead
36
+ of the browser's blue */
37
+ accent-color: var(--cmu-red);
38
+ }
39
+
40
+ /* A section heading with the template's line over it (rule-top): the
41
+ template zeroes the top padding of a section's first heading, which puts
42
+ the words right against the line; keep the room between them */
43
+ :is(h1, h2, h3, h4).rule-top:first-child {
44
+ padding-top: 1em;
45
+ }
46
+ /* Mid-section, room above the line, so it doesn't crowd a table, code block
47
+ or callout just before it */
48
+ :is(h1, h2, h3, h4).rule-top:not(:first-child) {
49
+ margin-top: 2rem;
50
+ }
51
+ /* Right after a band with a background color, the change of color already
52
+ marks the new section, so the next section's line is redundant */
53
+ :is(.content, .grid):is(
54
+ .grey,
55
+ .cmu-lightgrey,
56
+ .darkgrey,
57
+ .red,
58
+ .gold,
59
+ .blue,
60
+ .teal,
61
+ .green,
62
+ .darkgreen
63
+ )
64
+ + :is(.content, .grid)
65
+ > div
66
+ > :is(h1, h2, h3, h4, .cmu-eyebrow).rule-top:first-child {
67
+ border-top: 0;
68
+ padding-top: 0;
69
+ }
70
+ /* An eyebrow can take the line instead of its heading; its small text has
71
+ no line height to spare, so give it room under the line */
72
+ .cmu-eyebrow.rule-top {
73
+ padding-top: 0.9rem;
74
+ }
75
+
76
+ /* Small capitals: eyebrow (red, above a heading), label (gray) */
77
+ .cmu-eyebrow {
78
+ margin: 0 0 0.5rem;
79
+ /* The template pads paragraphs; an eyebrow sits right on its heading. */
80
+ padding-bottom: 0;
81
+ font-size: 0.8rem;
82
+ font-weight: 700;
83
+ letter-spacing: 0.12em;
84
+ text-transform: uppercase;
85
+ color: var(--cmu-red);
86
+ }
87
+ .cmu-eyebrow + h1,
88
+ .cmu-eyebrow + h2,
89
+ .cmu-eyebrow + h3 {
90
+ margin-top: 0;
91
+ padding-top: 0;
92
+ }
93
+ .cmu-label {
94
+ font-size: 0.8rem;
95
+ font-weight: 700;
96
+ letter-spacing: 0.12em;
97
+ text-transform: uppercase;
98
+ color: var(--cmu-muted);
99
+ }
100
+ /* A block label sits just above what it labels, whatever that is: a
101
+ paragraph, a list, a field or a code block. The template pads both. (A
102
+ span label sits beside its controls instead.) */
103
+ :is(p, div, legend).cmu-label {
104
+ margin-bottom: 0.5rem;
105
+ padding-bottom: 0;
106
+ }
107
+ :is(p, div, legend).cmu-label + * {
108
+ margin-top: 0;
109
+ padding-top: 0;
110
+ }
111
+ .cmu-lead {
112
+ font-size: 1.2rem;
113
+ line-height: 1.55;
114
+ max-width: 44em;
115
+ margin: 0 0 1.75rem;
116
+ }
117
+ /* A button with a call to action beside it: a cmu-cta-row, or any paragraph
118
+ that holds a button and then a call to action. (Not any div: a card's div
119
+ holds its heading and text too.) */
120
+ .cmu-cta-row,
121
+ p:has(> .btn + .cta) {
122
+ display: flex;
123
+ flex-wrap: wrap;
124
+ align-items: center;
125
+ gap: 1rem 1.75rem;
126
+ }
127
+ .cmu-cta-row {
128
+ margin: 0 0 2.5rem;
129
+ }
130
+ .cmu-cta-row .btn,
131
+ p:has(> .btn + .cta) > .btn {
132
+ margin: 0;
133
+ }
134
+ .cmu-cta-note {
135
+ margin: 0;
136
+ color: var(--cmu-muted);
137
+ font-size: 0.95rem;
138
+ }
139
+
140
+ /* Hero card: copy on the left, a screenshot in a browser frame on the right */
141
+ .cmu-hero {
142
+ display: grid;
143
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
144
+ gap: 2.5rem;
145
+ align-items: center;
146
+ margin: 0 0 3.5rem;
147
+ padding: 3rem 2.5rem;
148
+ background:
149
+ linear-gradient(135deg, rgba(196, 18, 48, 0.06) 0%, rgba(23, 44, 75, 0.06) 100%),
150
+ var(--cmu-tint);
151
+ border-top: 6px solid var(--cmu-red);
152
+ }
153
+ .cmu-hero h1 {
154
+ font-size: clamp(2.2rem, 4.6vw, 3.3rem);
155
+ letter-spacing: -0.01em;
156
+ }
157
+ /* A heading right after a hero, in the same block, starts a new section:
158
+ leave what two sections' padding would (as when the hero is its own
159
+ section), not the hero's margin plus the template's heading padding */
160
+ :is(#content, body) .cmu-hero:has(+ :is(h1, h2)) {
161
+ margin-bottom: 4rem;
162
+ }
163
+ :is(#content, body) .cmu-hero + :is(h1, h2) {
164
+ padding-top: 0;
165
+ }
166
+ .cmu-hero .cmu-cta-row {
167
+ margin-bottom: 0.9rem;
168
+ }
169
+ .cmu-hero .cmu-cta-row:last-child {
170
+ margin-bottom: 0;
171
+ }
172
+ .cmu-hero-art {
173
+ position: relative;
174
+ min-width: 0;
175
+ }
176
+ .cmu-hero-art img {
177
+ display: block;
178
+ box-sizing: border-box; /* the border fits inside the window's width */
179
+ border: 1px solid var(--cmu-line);
180
+ border-top: 0;
181
+ box-shadow: 0 18px 40px rgba(23, 44, 75, 0.16);
182
+ }
183
+ .cmu-hero-art::before,
184
+ .cmu-shot--browser::before {
185
+ /* browser-window bar with three dots */
186
+ content: "";
187
+ display: block;
188
+ height: 1.6rem;
189
+ background:
190
+ radial-gradient(circle, #b9bfc5 0.28rem, transparent 0.3rem) 0.7rem 50% / 0.9rem 0.9rem
191
+ no-repeat,
192
+ radial-gradient(circle, #b9bfc5 0.28rem, transparent 0.3rem) 1.6rem 50% / 0.9rem 0.9rem
193
+ no-repeat,
194
+ radial-gradient(circle, #b9bfc5 0.28rem, transparent 0.3rem) 2.5rem 50% / 0.9rem 0.9rem
195
+ no-repeat,
196
+ #e4e7ea;
197
+ border: 1px solid var(--cmu-line);
198
+ border-bottom: 0;
199
+ }
200
+ /* Two or three screenshots, overlapping down and to the right, cropped to
201
+ one shape from the top; the last is in front */
202
+ .cmu-hero-art--stack {
203
+ display: grid;
204
+ }
205
+ .cmu-hero-art--stack::before {
206
+ display: none;
207
+ }
208
+ /* Each image, or a link around it (such as to enlarge it), is one window */
209
+ .cmu-hero-art--stack > * {
210
+ grid-area: 1 / 1;
211
+ width: 66%;
212
+ }
213
+ :is(#content, body) .cmu-hero-art--stack > a:not(.btn):not(.cta):not(.box):not(.scrolldown) {
214
+ display: block;
215
+ padding: 0;
216
+ border: 0;
217
+ }
218
+ .cmu-hero-art--stack > a img {
219
+ width: 100%;
220
+ }
221
+ /* Each window draws its own bar, with the dots, in its top padding */
222
+ .cmu-hero-art--stack img {
223
+ box-sizing: content-box;
224
+ aspect-ratio: 4 / 3;
225
+ object-fit: cover;
226
+ object-position: left top; /* keep the roof and the start of each line */
227
+ padding-top: 1.6rem;
228
+ border-top: 1px solid var(--cmu-line);
229
+ background:
230
+ radial-gradient(circle, #b9bfc5 0.28rem, transparent 0.3rem) 0.7rem 0.35rem / 0.9rem 0.9rem
231
+ no-repeat,
232
+ radial-gradient(circle, #b9bfc5 0.28rem, transparent 0.3rem) 1.6rem 0.35rem / 0.9rem 0.9rem
233
+ no-repeat,
234
+ radial-gradient(circle, #b9bfc5 0.28rem, transparent 0.3rem) 2.5rem 0.35rem / 0.9rem 0.9rem
235
+ no-repeat,
236
+ #e4e7ea;
237
+ }
238
+ .cmu-hero-art--stack > :nth-child(2) {
239
+ margin: 17% 0 0 17%;
240
+ }
241
+ /* The third, or the second of two, goes all the way to the right */
242
+ .cmu-hero-art--stack > :nth-child(3),
243
+ .cmu-hero-art--stack > :nth-child(2):last-child {
244
+ margin: 34% 0 0 34%;
245
+ }
246
+ /* A photo or a tartan pattern file, with no browser frame */
247
+ .cmu-hero-art--plain::before {
248
+ display: none;
249
+ }
250
+ .cmu-hero-art--plain img {
251
+ border: 0;
252
+ box-shadow: none;
253
+ width: 100%;
254
+ }
255
+ @media (max-width: 820px) {
256
+ .cmu-hero {
257
+ grid-template-columns: 1fr;
258
+ padding: 2rem 1.25rem;
259
+ }
260
+ }
261
+
262
+ /* Card links: one per audience or option */
263
+ .cmu-paths {
264
+ display: grid;
265
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
266
+ gap: 1.25rem;
267
+ margin: 0 0 3.5rem;
268
+ }
269
+ .cmu-paths--two {
270
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
271
+ margin-bottom: 2.75rem;
272
+ }
273
+ a.cmu-path,
274
+ a.cmu-path:link,
275
+ a.cmu-path:visited {
276
+ display: flex;
277
+ flex-direction: column;
278
+ gap: 0.55rem;
279
+ padding: 1.6rem 1.5rem 1.9rem !important; /* beats #content a { padding-bottom: 1px } */
280
+ background: #fff;
281
+ border: 1px solid var(--cmu-line) !important;
282
+ color: var(--cmu-ink) !important;
283
+ text-decoration: none !important;
284
+ transition:
285
+ border-color 0.15s,
286
+ box-shadow 0.15s,
287
+ transform 0.15s;
288
+ }
289
+ a.cmu-path strong {
290
+ font-size: 1.4rem;
291
+ font-weight: 400;
292
+ line-height: 1.25;
293
+ }
294
+ a.cmu-path .cmu-eyebrow {
295
+ margin: 0;
296
+ color: var(--cmu-muted);
297
+ }
298
+ a.cmu-path .cta {
299
+ margin-top: auto;
300
+ }
301
+ a.cmu-path:hover,
302
+ a.cmu-path:focus-visible {
303
+ border-color: var(--cmu-red) !important;
304
+ box-shadow: 0 8px 22px rgba(23, 44, 75, 0.12);
305
+ transform: translateY(-2px);
306
+ }
307
+ @media (prefers-reduced-motion: reduce) {
308
+ a.cmu-path {
309
+ transition: none;
310
+ }
311
+ a.cmu-path:hover {
312
+ transform: none;
313
+ }
314
+ }
315
+
316
+ /* How it works: numbered columns */
317
+ ol.cmu-flow {
318
+ counter-reset: cmu-flow;
319
+ list-style: none;
320
+ display: grid;
321
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
322
+ gap: 1.5rem;
323
+ margin: 0 0 3.5rem;
324
+ padding: 0;
325
+ }
326
+ ol.cmu-flow > li {
327
+ counter-increment: cmu-flow;
328
+ position: relative;
329
+ padding-top: 3.4rem;
330
+ line-height: 1.55;
331
+ }
332
+ ol.cmu-flow > li::before {
333
+ content: counter(cmu-flow);
334
+ position: absolute;
335
+ left: 0;
336
+ top: 0;
337
+ width: 2.5rem;
338
+ height: 2.5rem;
339
+ display: flex;
340
+ align-items: center;
341
+ justify-content: center;
342
+ border: 2px solid var(--cmu-red);
343
+ border-radius: 50%;
344
+ color: var(--cmu-red);
345
+ font-weight: 700;
346
+ font-size: 1.1rem;
347
+ }
348
+ ol.cmu-flow > li > strong {
349
+ display: block;
350
+ font-size: 1.15rem;
351
+ margin-bottom: 0.25rem;
352
+ }
353
+
354
+ /* A link bank with no band color (grid ... nav on white): the template pads a
355
+ link bank to give its color room, but on white that padding is only empty
356
+ space, so it goes. Colored link banks keep theirs. */
357
+ .grid.nav:not(.red, .blue, .grey, .darkgrey, .teal, .green, .darkgreen, .gold) {
358
+ padding-top: 0;
359
+ padding-bottom: 0;
360
+ }
361
+
362
+ /* On This Page as a link bank: the template's link bank (grid ... nav) with
363
+ cmu-on-this-page and a label first, for long pages whose content uses the
364
+ full width. The label takes a row of its own, over all the columns, and the
365
+ link bank drops the template's top and bottom padding, which gives a
366
+ colored band room; other link banks keep it. */
367
+ .cmu-on-this-page {
368
+ padding-top: 0;
369
+ padding-bottom: 0;
370
+ }
371
+ .cmu-on-this-page > .cmu-label {
372
+ flex-basis: 100%;
373
+ width: 100%;
374
+ margin: 0;
375
+ padding: 0;
376
+ }
377
+ /* An image with see-through parts, such as a logo, a cutout or a generated
378
+ image, over a light checkerboard, the way image editors show transparency.
379
+ On the image itself or on a figure holding it. */
380
+ img.cmu-transparent,
381
+ .cmu-transparent img {
382
+ background: #fff conic-gradient(#e6e6e6 25%, transparent 0 50%, #e6e6e6 0 75%, transparent 0) 0
383
+ 0 / 16px 16px;
384
+ }
385
+
386
+ /* Callout: a labeled aside on a page (cmu-label, then text beside it) */
387
+ .cmu-callout {
388
+ display: flex;
389
+ flex-wrap: wrap;
390
+ align-items: baseline;
391
+ gap: 0.4rem 1.5rem;
392
+ margin: 0 0 3.5rem;
393
+ padding: 1.4rem 1.75rem;
394
+ background: var(--cmu-tint);
395
+ border-left: 4px solid var(--cmu-line);
396
+ }
397
+ .cmu-callout p {
398
+ margin: 0;
399
+ padding: 0;
400
+ }
401
+ /* Colors, for what kind of aside it is: blue for a note, green for a tip,
402
+ gold for a warning, red for a caution. The label takes the color too. */
403
+ .cmu-callout--blue {
404
+ background: var(--cmu-blue-tint);
405
+ border-left-color: var(--cmu-blue);
406
+ }
407
+ .cmu-callout--green {
408
+ background: var(--cmu-green-tint);
409
+ border-left-color: var(--cmu-green-fill);
410
+ }
411
+ .cmu-callout--gold {
412
+ background: var(--cmu-amber-tint);
413
+ border-left-color: var(--cmu-gold);
414
+ }
415
+ .cmu-callout--red {
416
+ background: var(--cmu-red-tint);
417
+ border-left-color: var(--cmu-red);
418
+ }
419
+ .cmu-callout--blue .cmu-label {
420
+ color: var(--cmu-blue);
421
+ }
422
+ .cmu-callout--green .cmu-label {
423
+ color: var(--cmu-green);
424
+ }
425
+ .cmu-callout--gold .cmu-label {
426
+ color: var(--cmu-amber);
427
+ }
428
+ .cmu-callout--red .cmu-label {
429
+ color: var(--cmu-red);
430
+ }
431
+
432
+ /* Note: a plain tinted message among other content */
433
+ .cmu-note {
434
+ margin: 0 0 1.25em;
435
+ background: var(--cmu-tint);
436
+ border-left: 4px solid var(--cmu-line);
437
+ }
438
+ /* Equal padding even on a p: the template zeroes a p's top padding when
439
+ it's first (p:first-child) and its bottom padding when it's last in a
440
+ grid (.grid p:last-child). The id in :is() only adds weight; body keeps
441
+ it working on pages without #content. */
442
+ :is(#content, body) .cmu-note {
443
+ padding: 0.85em 1.1em;
444
+ }
445
+ .cmu-note p {
446
+ margin: 0;
447
+ padding: 0;
448
+ }
449
+
450
+ /* FAQ (the template's collapsed headings): the template sets the space over
451
+ an answer as an !important margin, which its slide animation can't touch,
452
+ so the space pops in before the answer slides open. As padding, it opens
453
+ and closes with the answer. */
454
+ #content h2.collapsed + div {
455
+ margin-top: 0 !important;
456
+ padding-top: 1em;
457
+ }
458
+
459
+ /* FAQ teaser: a few questions and answers in columns, before a link to the FAQ */
460
+ .cmu-faq-teaser {
461
+ display: grid;
462
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
463
+ gap: 1.25rem 2rem;
464
+ margin: 0 0 1.25rem;
465
+ }
466
+ .cmu-faq-teaser > div {
467
+ padding-top: 1rem;
468
+ border-top: 2px solid var(--cmu-line);
469
+ }
470
+ .cmu-faq-teaser h3 {
471
+ margin: 0 0 0.35rem;
472
+ padding: 0;
473
+ font-size: 1rem;
474
+ font-weight: 700;
475
+ }
476
+ .cmu-faq-teaser p {
477
+ margin: 0;
478
+ line-height: 1.55;
479
+ }
480
+
481
+ /* Two columns: text, then a screenshot; one column on phones */
482
+ .cmu-split {
483
+ display: grid;
484
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
485
+ gap: 2rem;
486
+ align-items: start;
487
+ margin: 0 0 2.75rem;
488
+ }
489
+ @media (max-width: 760px) {
490
+ .cmu-split {
491
+ grid-template-columns: minmax(0, 1fr);
492
+ }
493
+ }
494
+
495
+ /* Carousel: the template makes each slide (.grid) width: 100%, but on wide
496
+ screens it also pads .grid on both sides, so each slide came out wider
497
+ than the carousel and the slides drifted out of line. Count the padding
498
+ inside the width. */
499
+ .js-flickityCustom .grid {
500
+ box-sizing: border-box;
501
+ }
502
+ /* The carousel script measures its height once, at load; when the page then
503
+ narrows (the menu opening, images arriving) the slides shrink but the
504
+ carousel keeps the old height, leaving a gap below. Stack the slides in
505
+ one grid cell instead, so the carousel is always as tall as its tallest
506
+ slide. The script still moves them sideways with transforms. */
507
+ .js-flickityCustom .flickity-viewport {
508
+ height: auto !important; /* over the script's inline height */
509
+ }
510
+ .js-flickityCustom .flickity-slider {
511
+ position: relative;
512
+ display: grid;
513
+ height: auto;
514
+ }
515
+ .js-flickityCustom .flickity-slider > * {
516
+ grid-area: 1 / 1;
517
+ position: relative !important; /* over the script's inline position */
518
+ left: 0 !important;
519
+ }
520
+
521
+ /* Annotated image: a tall image, such as a screenshot or a diagram, on the
522
+ right, with numbered callouts on the left, each pinned beside its part of
523
+ the image (--cmu-at on the callout: how far down, 0 to 1) and overlapping
524
+ its edge. Where the component is narrower than 50rem (70rem with --wide),
525
+ the text, the callouts and the image stack. See Annotated Image in the
526
+ docs (sections.html). */
527
+ .cmu-annotated {
528
+ --cmu-annotated-bar: 0px;
529
+ container-type: inline-size;
530
+ position: relative;
531
+ margin: 0 0 1.5rem;
532
+ padding-bottom: 2.25rem; /* room for the caption, which hangs below */
533
+ }
534
+ .cmu-annotated:has(> .cmu-shot--browser) {
535
+ --cmu-annotated-bar: 1.6rem; /* the browser window's bar, above the image */
536
+ }
537
+ .cmu-annotated-notes {
538
+ list-style: none;
539
+ margin: 0 0 1.5rem;
540
+ padding: 0;
541
+ }
542
+ .cmu-annotated-notes > li.cmu-callout {
543
+ margin: 0 0 0.75rem;
544
+ padding: 1rem 1.25rem;
545
+ box-shadow: 0 6px 18px rgba(23, 44, 75, 0.12);
546
+ }
547
+ /* Title, words and call to action, one above another in every callout */
548
+ .cmu-annotated-notes > li.cmu-callout > p {
549
+ flex-basis: 100%;
550
+ }
551
+ @container (min-width: 50rem) {
552
+ .cmu-annotated:not(.cmu-annotated--wide) > figure {
553
+ position: relative;
554
+ width: 56%;
555
+ margin: 0 0 0 auto;
556
+ }
557
+ /* The caption hangs below the screenshot, so the callouts line up with
558
+ the image alone */
559
+ .cmu-annotated:not(.cmu-annotated--wide) > figure > figcaption {
560
+ position: absolute;
561
+ top: 100%;
562
+ }
563
+ .cmu-annotated:not(.cmu-annotated--wide) .cmu-annotated-text {
564
+ position: absolute;
565
+ top: 0;
566
+ bottom: 2.25rem; /* the image alone, not the caption\'s room */
567
+ left: 0;
568
+ width: 46%;
569
+ z-index: 1;
570
+ }
571
+ /* Text above the callouts stays clear of the screenshot */
572
+ .cmu-annotated:not(.cmu-annotated--wide) .cmu-annotated-text > p {
573
+ margin-right: 13%;
574
+ }
575
+ .cmu-annotated:not(.cmu-annotated--wide) .cmu-annotated-notes {
576
+ margin: 0;
577
+ }
578
+ .cmu-annotated:not(.cmu-annotated--wide) .cmu-annotated-notes > li.cmu-callout {
579
+ position: absolute;
580
+ left: 0;
581
+ right: 0;
582
+ top: calc(var(--cmu-annotated-bar) + (100% - var(--cmu-annotated-bar)) * var(--cmu-at, 0));
583
+ margin: 0;
584
+ transform: translateY(-50%);
585
+ }
586
+ }
587
+ /* --wide, for long text or callouts: side by side only from 70rem */
588
+ @container (min-width: 70rem) {
589
+ .cmu-annotated--wide > figure {
590
+ position: relative;
591
+ width: 56%;
592
+ margin: 0 0 0 auto;
593
+ }
594
+ /* The caption hangs below the screenshot, so the callouts line up with
595
+ the image alone */
596
+ .cmu-annotated--wide > figure > figcaption {
597
+ position: absolute;
598
+ top: 100%;
599
+ }
600
+ .cmu-annotated--wide .cmu-annotated-text {
601
+ position: absolute;
602
+ top: 0;
603
+ bottom: 2.25rem; /* the image alone, not the caption\'s room */
604
+ left: 0;
605
+ width: 46%;
606
+ z-index: 1;
607
+ }
608
+ /* Text above the callouts stays clear of the screenshot */
609
+ .cmu-annotated--wide .cmu-annotated-text > p {
610
+ margin-right: 13%;
611
+ }
612
+ .cmu-annotated--wide .cmu-annotated-notes {
613
+ margin: 0;
614
+ }
615
+ .cmu-annotated--wide .cmu-annotated-notes > li.cmu-callout {
616
+ position: absolute;
617
+ left: 0;
618
+ right: 0;
619
+ top: calc(var(--cmu-annotated-bar) + (100% - var(--cmu-annotated-bar)) * var(--cmu-at, 0));
620
+ margin: 0;
621
+ transform: translateY(-50%);
622
+ }
623
+ }
624
+
625
+ /* A screenshot with a border and an optional caption. --browser draws it in
626
+ a browser window; its bar is shared with the hero's, above */
627
+ .cmu-shot {
628
+ margin: 0 0 1.75rem;
629
+ }
630
+ .cmu-shot img {
631
+ display: block;
632
+ box-sizing: border-box;
633
+ border: 1px solid var(--cmu-line);
634
+ box-shadow: 0 6px 18px rgba(23, 44, 75, 0.1);
635
+ }
636
+ /* The window is as wide as its screenshot, never wider than the column */
637
+ .cmu-shot--browser {
638
+ width: fit-content;
639
+ max-width: 100%;
640
+ }
641
+ .cmu-shot--browser img {
642
+ border-top: 0;
643
+ }
644
+ /* A linked screenshot: the link wraps the image exactly, with no underline.
645
+ The template pads and underlines every link in #content with
646
+ #content a:not(.btn):not(.cta):not(.box):not(.scrolldown), so this
647
+ matches its weight. */
648
+ :is(#content, body) .cmu-shot a:not(.btn):not(.cta):not(.box):not(.scrolldown) {
649
+ display: block;
650
+ padding: 0;
651
+ border: 0;
652
+ }
653
+ /* Captioned like the template's own photos (figure.image) */
654
+ .cmu-shot figcaption {
655
+ margin-top: 0.5rem;
656
+ font-style: italic;
657
+ }
658
+
659
+ /* Enlarge on click (uses cmu-app.js): a link to the full-size image with
660
+ data-cmu-zoom opens it over the page, dimmed behind, in a <dialog>; see
661
+ Enlarge on Click in the docs (content.html) */
662
+ a[data-cmu-zoom] {
663
+ cursor: zoom-in;
664
+ }
665
+ /* The link hugs its image, without the template's link underline and
666
+ padding, so a focus ring (as when the enlarged image closes and focus
667
+ comes back) goes around the picture, not a strip across it */
668
+ :is(#content, body) a[data-cmu-zoom],
669
+ :is(#content, body) a[data-cmu-zoom]:hover {
670
+ display: inline-block;
671
+ max-width: 100%;
672
+ padding: 0;
673
+ border: 0;
674
+ vertical-align: top;
675
+ }
676
+ :is(#content, body) a[data-cmu-zoom] img {
677
+ display: block;
678
+ }
679
+ /* The template marks a focused or pressed link with a red background and
680
+ an important 3px outline. On a zoom link: no box while it's pressed (the
681
+ click opens the image), and the ring covers a screenshot's 1px border
682
+ instead of leaving it as a light gap inside the ring */
683
+ :is(#content, body) a[data-cmu-zoom]:active:not(:focus-visible) {
684
+ outline: none !important;
685
+ background: none !important;
686
+ }
687
+ :is(#content, body) .cmu-shot > a[data-cmu-zoom]:focus-visible {
688
+ outline-offset: -1px;
689
+ }
690
+ /* In a browser-window screenshot, the ring goes around the whole window: the
691
+ link's overlay reaches up over the bar, the figure's ::before (1.6rem plus
692
+ its 1px top border) */
693
+ :is(#content, body) .cmu-shot--browser > a[data-cmu-zoom] {
694
+ position: relative;
695
+ overflow: visible !important;
696
+ }
697
+ :is(#content, body) .cmu-shot--browser > a[data-cmu-zoom]:focus-visible {
698
+ outline: none !important;
699
+ }
700
+ :is(#content, body) .cmu-shot--browser > a[data-cmu-zoom]:focus-visible::after {
701
+ content: "";
702
+ position: absolute;
703
+ inset: calc(-1.6rem - 1px) 0 0;
704
+ outline: 3px solid var(--cmu-red);
705
+ outline-offset: -1px;
706
+ pointer-events: none;
707
+ }
708
+ .cmu-zoom {
709
+ max-width: min(92vw, 1400px);
710
+ max-height: 92vh;
711
+ padding: 0;
712
+ overflow: visible;
713
+ border: 0;
714
+ background: none;
715
+ }
716
+ .cmu-zoom::backdrop {
717
+ background: rgba(0, 0, 0, 0.6);
718
+ }
719
+ .cmu-zoom-frame {
720
+ max-height: 92vh;
721
+ overflow: auto;
722
+ box-shadow: 0 18px 40px rgba(0, 0, 0, 0.35);
723
+ }
724
+ .cmu-zoom img {
725
+ display: block;
726
+ max-width: 100%;
727
+ max-height: 92vh;
728
+ cursor: zoom-out;
729
+ }
730
+ /* An image much taller than the window: full width, scrolling (the script
731
+ decides) */
732
+ .cmu-zoom--tall img {
733
+ max-height: none;
734
+ }
735
+ /* The template darkens every button on hover; this one stays a plain white x */
736
+ .cmu-zoom .cmu-zoom-close,
737
+ .cmu-zoom .cmu-zoom-close:hover {
738
+ position: absolute;
739
+ top: -2.75rem;
740
+ right: 0;
741
+ margin: 0;
742
+ padding: 0 0.25rem;
743
+ border: 0;
744
+ background: none;
745
+ color: #fff;
746
+ font-size: 2.25rem;
747
+ line-height: 1;
748
+ }
749
+
750
+ /* Scroll gallery (uses cmu-app.js): steps of text, each with a figure. On a
751
+ wide screen the text scrolls on the left and a sticky stage on the right
752
+ shows the current step's figure, fading up to the next as it arrives, or
753
+ with --slide, sliding in from the side; on a narrow one, or without the
754
+ script, each step shows its own figure. See
755
+ Scroll Gallery in the docs (sections.html) */
756
+ .cmu-scroll-gallery-step + .cmu-scroll-gallery-step {
757
+ margin-top: 2.5rem;
758
+ }
759
+ .cmu-scroll-gallery-step > figure {
760
+ margin-top: 1.25rem;
761
+ }
762
+ .cmu-scroll-gallery-stage {
763
+ display: none;
764
+ }
765
+ @media (min-width: 768px) {
766
+ .cmu-scroll-gallery--on {
767
+ display: grid;
768
+ grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
769
+ column-gap: 3rem;
770
+ }
771
+ .cmu-scroll-gallery--on > .cmu-scroll-gallery-step {
772
+ grid-column: 1;
773
+ display: flex;
774
+ flex-direction: column;
775
+ justify-content: center;
776
+ min-height: 70vh;
777
+ margin: 0;
778
+ }
779
+ .cmu-scroll-gallery--on > .cmu-scroll-gallery-step > figure {
780
+ display: none;
781
+ }
782
+ .cmu-scroll-gallery--on > .cmu-scroll-gallery-stage {
783
+ grid-column: 2;
784
+ position: sticky;
785
+ top: 15vh;
786
+ align-self: start;
787
+ display: grid;
788
+ }
789
+ .cmu-scroll-gallery-stage > figure {
790
+ grid-area: 1 / 1;
791
+ margin: 0;
792
+ transition:
793
+ opacity 0.45s ease,
794
+ transform 0.45s ease;
795
+ }
796
+ .cmu-scroll-gallery-stage > .cmu-scroll-gallery-past {
797
+ opacity: 0;
798
+ transform: translateY(-1.5rem);
799
+ }
800
+ .cmu-scroll-gallery-stage > .cmu-scroll-gallery-next {
801
+ opacity: 0;
802
+ transform: translateY(1.5rem);
803
+ }
804
+ /* --slide: in from the side. The stage clips the pictures waiting either
805
+ side, with room for the screenshot's shadow */
806
+ .cmu-scroll-gallery--slide > .cmu-scroll-gallery-stage {
807
+ overflow: hidden;
808
+ padding: 0.5rem 1.25rem 1.75rem;
809
+ margin: -0.5rem -1.25rem -1.75rem;
810
+ }
811
+ .cmu-scroll-gallery--slide .cmu-scroll-gallery-stage > figure {
812
+ transition: transform 0.6s ease;
813
+ }
814
+ .cmu-scroll-gallery--slide .cmu-scroll-gallery-stage > .cmu-scroll-gallery-past {
815
+ opacity: 1;
816
+ transform: translateX(calc(-100% - 3rem));
817
+ }
818
+ .cmu-scroll-gallery--slide .cmu-scroll-gallery-stage > .cmu-scroll-gallery-next {
819
+ opacity: 1;
820
+ transform: translateX(calc(100% + 3rem));
821
+ }
822
+ }
823
+ @media (prefers-reduced-motion: reduce) {
824
+ .cmu-scroll-gallery-stage > figure,
825
+ .cmu-scroll-gallery--slide .cmu-scroll-gallery-stage > figure {
826
+ transition: none;
827
+ }
828
+ .cmu-scroll-gallery--slide .cmu-scroll-gallery-stage > :not(.cmu-scroll-gallery-current) {
829
+ opacity: 0;
830
+ }
831
+ }
832
+
833
+ /* A line across a grid band's full width, above or below its cards, such as
834
+ an introduction or a link to see more (the template spans only a first h1) */
835
+ .grid > .cmu-grid-full {
836
+ flex: 0 0 100%;
837
+ }
838
+
839
+ /* A kit block that ends its content section (as each does in Cascade, one
840
+ block per section) leaves the space below to the section's own padding */
841
+ #content .content > div > [class^="cmu-"]:last-child,
842
+ #content .content > div > [class*=" cmu-"]:last-child {
843
+ margin-bottom: 0;
844
+ }
845
+
846
+ /* Table cells centered vertically, so one-line cells sit level with wrapped
847
+ ones and with images (the template sets top or baseline) */
848
+ #content table.alternate td {
849
+ vertical-align: middle;
850
+ }
851
+ /* In a gray or gold section, a striped table keeps its white rows: the
852
+ template leaves them clear, so they'd take on the section's color */
853
+ #content :is(.grey, .cmu-lightgrey, .gold) table.alternate {
854
+ background-color: #fff;
855
+ }
856
+
857
+ /* A light gray section, the gray of the kit's code snippets: lighter than
858
+ the template's grey, for a testimonial or a quiet band. Text stays dark. */
859
+ .cmu-lightgrey {
860
+ background-color: var(--cmu-tint);
861
+ }
862
+
863
+ /* Testimonial: a quote from a person, with their name, role and square
864
+ photo beside it. Put it in a section such as content wide cmu-lightgrey.
865
+ Stacks on phones, photo first. See Testimonial in the docs
866
+ (sections.html). */
867
+ .cmu-testimonial {
868
+ display: grid;
869
+ grid-template-columns: minmax(0, 1.8fr) minmax(0, 1fr);
870
+ gap: 3rem;
871
+ align-items: center;
872
+ }
873
+ .cmu-testimonial > img {
874
+ grid-column: 2;
875
+ grid-row: 1;
876
+ width: 100%;
877
+ aspect-ratio: 1;
878
+ object-fit: cover;
879
+ }
880
+ .cmu-testimonial > figure {
881
+ margin: 0;
882
+ }
883
+ /* The red quotation-mark tile; decoration, so screen readers skip it */
884
+ .cmu-testimonial > figure::before {
885
+ content: "\201C" / "";
886
+ display: block;
887
+ width: 4.5rem;
888
+ height: 4.5rem;
889
+ background: var(--cmu-red);
890
+ color: #fff;
891
+ font:
892
+ 700 5rem/1.15 Georgia,
893
+ "Times New Roman",
894
+ serif;
895
+ text-align: center;
896
+ overflow: hidden;
897
+ }
898
+ /* The template's blockquote is 2.35em and light; here the quote is set at
899
+ about lead size, semibold, with a thin rule beside it at 30% black (the
900
+ template's 15% fades on gray) */
901
+ #content .cmu-testimonial blockquote {
902
+ margin: 1.75rem 0 0;
903
+ padding: 0 0 0 2rem;
904
+ border-left: 1px solid rgba(0, 0, 0, 0.3);
905
+ font-size: 1.6rem;
906
+ font-weight: 600;
907
+ line-height: 1.5;
908
+ color: var(--cmu-ink);
909
+ }
910
+ #content .cmu-testimonial blockquote p {
911
+ margin: 0;
912
+ padding: 0;
913
+ }
914
+ .cmu-testimonial cite {
915
+ display: block;
916
+ margin-top: 2rem;
917
+ font-style: normal;
918
+ font-weight: 700;
919
+ line-height: 1.5;
920
+ }
921
+ .cmu-testimonial cite strong {
922
+ color: var(--cmu-red);
923
+ font-size: 1.25rem;
924
+ }
925
+ @media (max-width: 760px) {
926
+ .cmu-testimonial {
927
+ grid-template-columns: minmax(0, 1fr);
928
+ gap: 1.5rem;
929
+ }
930
+ .cmu-testimonial > img {
931
+ grid-column: 1;
932
+ max-width: 16rem;
933
+ }
934
+ .cmu-testimonial > figure {
935
+ grid-row: 2;
936
+ }
937
+ #content .cmu-testimonial blockquote {
938
+ font-size: 1.3rem;
939
+ }
940
+ }
941
+
942
+ /* A page from another site in a frame (a dashboard, a form): the width of
943
+ its column at any screen size; set its height with the height attribute.
944
+ The template sizes only video iframes. */
945
+ .cmu-embed {
946
+ display: block;
947
+ width: 100%;
948
+ border: 1px solid var(--cmu-line);
949
+ }
950
+
951
+ /* A block of code to read or copy: scrolls sideways by default; --wrap
952
+ wraps long lines (URLs, HTML) so all of it stays in view. It belongs to
953
+ the sentence that introduces it, so it sits close under it (like a line
954
+ break), then a paragraph's space before what follows. */
955
+ p:not(.cmu-label):has(+ :is(.cmu-snippet, .cmu-copyable)) {
956
+ padding-bottom: 0.5em;
957
+ }
958
+ .cmu-snippet {
959
+ margin: 0 0 1em;
960
+ overflow-x: auto;
961
+ background: var(--cmu-tint);
962
+ border: 1px solid var(--cmu-line);
963
+ font-size: 0.85rem;
964
+ line-height: 1.5;
965
+ /* Long lines wrap rather than scroll; copying still gives them as written */
966
+ white-space: pre-wrap;
967
+ overflow-wrap: anywhere;
968
+ }
969
+ /* Keep the inset when the template zeroes a pre's first/last-child padding. */
970
+ :is(#content, body) .cmu-snippet {
971
+ padding: 1rem 1.25rem;
972
+ }
973
+ .cmu-snippet code {
974
+ font-family: Menlo, Consolas, monospace;
975
+ }
976
+ /* On a dark band (invert), the template turns text white; the snippet keeps
977
+ its light box, so its code (and anything marked up inside it) stays dark */
978
+ .invert .cmu-snippet,
979
+ .invert .cmu-snippet * {
980
+ color: var(--cmu-ink);
981
+ }
982
+ /* Wrapping is the default now; the old name still works */
983
+ .cmu-snippet--wrap {
984
+ white-space: pre-wrap;
985
+ overflow-wrap: anywhere;
986
+ }
987
+ /* A named copy button beside its block, on the right; under it on phones */
988
+ .cmu-copy-row {
989
+ display: flex;
990
+ flex-wrap: wrap;
991
+ align-items: stretch;
992
+ gap: 0.5rem;
993
+ margin: 0 0 1em;
994
+ }
995
+ .cmu-copy-row > .cmu-snippet {
996
+ flex: 1 1 18rem;
997
+ min-width: 0;
998
+ margin: 0;
999
+ }
1000
+ .cmu-copy-row > .btn {
1001
+ margin: 0;
1002
+ }
1003
+ /* In a copy box, room on the right so the text never runs under the icon */
1004
+ .cmu-copyable > .cmu-snippet {
1005
+ padding-right: 3rem;
1006
+ }
1007
+
1008
+ /* A code block with a copy icon in its top right corner, where people look
1009
+ for it. The wrapper holds the button still while the code scrolls
1010
+ sideways under it.
1011
+ Uses cmu-app.js. Icons: Bootstrap Icons copy and check-lg, MIT license,
1012
+ Copyright (c) 2019-2024 The Bootstrap Authors. */
1013
+ .cmu-copyable {
1014
+ position: relative;
1015
+ margin: 0 0 1em;
1016
+ }
1017
+ /* The template zeroes a first and last child's padding; keep the block's */
1018
+ :is(#content, body) .cmu-copyable > .cmu-snippet {
1019
+ margin: 0;
1020
+ padding: 1rem 3.25rem 1rem 1.25rem;
1021
+ }
1022
+ .cmu-copy {
1023
+ position: absolute;
1024
+ top: 0.5rem;
1025
+ right: 0.5rem;
1026
+ display: grid;
1027
+ place-items: center;
1028
+ width: 2rem;
1029
+ height: 2rem;
1030
+ margin: 0;
1031
+ padding: 0;
1032
+ background: #fff;
1033
+ border: 1px solid var(--cmu-line);
1034
+ border-radius: 6px;
1035
+ color: #6d6e71;
1036
+ cursor: pointer;
1037
+ }
1038
+ /* The template darkens every button on hover (and a tap leaves it there) */
1039
+ .cmu-copy:hover {
1040
+ background: #fff;
1041
+ color: #222;
1042
+ border-color: #6d6e71;
1043
+ }
1044
+ .cmu-copy::before {
1045
+ content: "";
1046
+ width: 16px;
1047
+ height: 16px;
1048
+ background: currentColor;
1049
+ mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zM2 5a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1v-1h1v1a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h1v1z'/%3E%3C/svg%3E")
1050
+ center / contain no-repeat;
1051
+ }
1052
+ .cmu-copy[data-cmu-copy-state="copied"] {
1053
+ color: var(--cmu-green);
1054
+ border-color: currentColor;
1055
+ }
1056
+ .cmu-copy[data-cmu-copy-state="copied"]::before {
1057
+ mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z'/%3E%3C/svg%3E");
1058
+ }
1059
+ /* Countdown (uses cmu-app.js): days, hours, minutes and seconds on flip
1060
+ cards; see Countdown in the docs (content.html). The sentence inside is
1061
+ the fallback and what screen readers get; the script hides it visually. */
1062
+ .cmu-countdown-on > :not(.cmu-countdown-clock, .cmu-countdown-done) {
1063
+ position: absolute;
1064
+ width: 1px;
1065
+ height: 1px;
1066
+ overflow: hidden;
1067
+ clip: rect(0 0 0 0);
1068
+ white-space: nowrap;
1069
+ }
1070
+ /* --replace: once it's done, the done message takes the cards' place */
1071
+ .cmu-countdown--replace.cmu-countdown-ended > .cmu-countdown-clock {
1072
+ display: none;
1073
+ }
1074
+ .cmu-countdown-clock {
1075
+ display: flex;
1076
+ flex-wrap: wrap;
1077
+ gap: 0.6rem;
1078
+ margin: 1rem 0 2rem;
1079
+ perspective: 400px;
1080
+ }
1081
+ .cmu-countdown-clock *,
1082
+ .cmu-countdown-clock *::before,
1083
+ .cmu-countdown-clock *::after {
1084
+ box-sizing: border-box;
1085
+ }
1086
+ .cmu-countdown-unit {
1087
+ text-align: center;
1088
+ }
1089
+ .cmu-countdown-label {
1090
+ display: block;
1091
+ margin-top: 0.4rem;
1092
+ font-size: 1.1rem;
1093
+ color: var(--cmu-muted);
1094
+ }
1095
+ .cmu-countdown-card {
1096
+ display: block;
1097
+ position: relative;
1098
+ padding-bottom: 0.72em;
1099
+ font-size: 3.25rem;
1100
+ line-height: 1.25;
1101
+ }
1102
+ @media (max-width: 767px) {
1103
+ .cmu-countdown-card {
1104
+ font-size: 2.25rem;
1105
+ }
1106
+ }
1107
+ .cmu-countdown-top,
1108
+ .cmu-countdown-bottom,
1109
+ .cmu-countdown-back::before,
1110
+ .cmu-countdown-back::after {
1111
+ display: block;
1112
+ /* Whole-pixel widths: each half is drawn on its own layer, and halves of a
1113
+ fractional width can land a pixel apart */
1114
+ width: fit-content;
1115
+ width: calc-size(fit-content, round(up, size, 1px));
1116
+ min-width: 1.8em;
1117
+ min-width: round(up, 1.8em, 1px);
1118
+ height: 0.72em;
1119
+ padding: 0 0.25em;
1120
+ border-radius: 0.15em 0.15em 0 0;
1121
+ background: #222;
1122
+ color: #ccc;
1123
+ backface-visibility: hidden;
1124
+ transform: translateZ(0);
1125
+ transform-style: preserve-3d;
1126
+ }
1127
+ .cmu-countdown-bottom {
1128
+ position: absolute;
1129
+ top: 50%;
1130
+ left: 0;
1131
+ overflow: hidden;
1132
+ border-top: 1px solid #000;
1133
+ border-radius: 0 0 0.15em 0.15em;
1134
+ background: #393939;
1135
+ color: #fff;
1136
+ pointer-events: none;
1137
+ }
1138
+ .cmu-countdown-bottom::after {
1139
+ content: attr(data-value);
1140
+ display: block;
1141
+ margin-top: -0.72em;
1142
+ }
1143
+ .cmu-countdown-back {
1144
+ position: absolute;
1145
+ top: 0;
1146
+ left: 0;
1147
+ height: 100%;
1148
+ pointer-events: none;
1149
+ }
1150
+ .cmu-countdown-back::before {
1151
+ content: attr(data-value);
1152
+ position: relative;
1153
+ z-index: -1;
1154
+ overflow: hidden;
1155
+ }
1156
+ .cmu-countdown-flip .cmu-countdown-back::before {
1157
+ animation: cmu-countdown-top 0.3s cubic-bezier(0.37, 0.01, 0.94, 0.35) both;
1158
+ transform-origin: center bottom;
1159
+ }
1160
+ .cmu-countdown-flip .cmu-countdown-back .cmu-countdown-bottom {
1161
+ animation: cmu-countdown-bottom 0.6s cubic-bezier(0.15, 0.45, 0.28, 1) both;
1162
+ transform-origin: center top;
1163
+ }
1164
+ @media (prefers-reduced-motion: reduce) {
1165
+ .cmu-countdown-flip .cmu-countdown-back::before,
1166
+ .cmu-countdown-flip .cmu-countdown-back .cmu-countdown-bottom {
1167
+ animation: none;
1168
+ }
1169
+ }
1170
+ @keyframes cmu-countdown-top {
1171
+ 0% {
1172
+ transform: rotateX(0deg);
1173
+ z-index: 2;
1174
+ }
1175
+ 0%,
1176
+ 99% {
1177
+ opacity: 0.99;
1178
+ }
1179
+ 100% {
1180
+ transform: rotateX(-90deg);
1181
+ opacity: 0;
1182
+ }
1183
+ }
1184
+ @keyframes cmu-countdown-bottom {
1185
+ 0%,
1186
+ 50% {
1187
+ z-index: -1;
1188
+ transform: rotateX(90deg);
1189
+ opacity: 0;
1190
+ }
1191
+ 51% {
1192
+ opacity: 0.99;
1193
+ }
1194
+ 100% {
1195
+ opacity: 0.99;
1196
+ transform: rotateX(0deg);
1197
+ z-index: 5;
1198
+ }
1199
+ }
1200
+
1201
+ /* A Bootstrap Icon (an optional extra; see Install) floated in a card, as
1202
+ timeline cards float an icon image: the size of one, in CMU red */
1203
+ .grid.boxes .bi.floatright {
1204
+ font-size: 3.5rem;
1205
+ line-height: 1;
1206
+ color: var(--cmu-red);
1207
+ }
1208
+
1209
+ /* A heading right after a floated icon in a card sits beside it, level
1210
+ with its top, as if it came first (the template has every heading clear
1211
+ floats, and pads all but a first heading) */
1212
+ .grid.boxes .floatright + h2 {
1213
+ clear: none;
1214
+ padding-top: 0;
1215
+ }
1216
+ /* A card with a rule (timeline cards): the rule and what follows it sit at
1217
+ the bottom, so the dates line up across a row of cards */
1218
+ .grid.boxes > div:has(> hr) {
1219
+ display: flex;
1220
+ flex-direction: column;
1221
+ }
1222
+ .grid.boxes > div:has(> hr) > hr {
1223
+ margin-top: auto;
1224
+ }
1225
+ /* Space above the rule when nothing stretches the card (stacked on phones) */
1226
+ .grid.boxes > div:has(> hr) > :first-child {
1227
+ margin-bottom: 1rem;
1228
+ }
1229
+
1230
+ /* Cards with the words at the bottom (cmu-cards-bottom): each card's
1231
+ heading, words and link sit at its bottom, so they line up across a row
1232
+ whose pictures differ in height; the picture is centered in the space
1233
+ above. Without a picture, the words still sit at the bottom */
1234
+ .grid.boxes.cmu-cards-bottom > div {
1235
+ display: flex;
1236
+ flex-direction: column;
1237
+ }
1238
+ .grid.boxes.cmu-cards-bottom > div > :is(img, figure):first-child {
1239
+ float: none;
1240
+ align-self: center;
1241
+ max-width: 100%;
1242
+ height: auto;
1243
+ margin-top: auto;
1244
+ margin-bottom: auto;
1245
+ }
1246
+ .grid.boxes.cmu-cards-bottom > div > :is(img, figure):first-child + * {
1247
+ margin-top: 1.5rem;
1248
+ }
1249
+ .grid.boxes.cmu-cards-bottom > div:not(:has(> :is(img, figure):first-child)) > :first-child {
1250
+ margin-top: auto;
1251
+ }
1252
+
1253
+ /* Lists: check marks, numbered steps */
1254
+ /* Plain list: no bullets, for a list whose items each start with their own
1255
+ label, such as a pill or a bold term. Items keep the template's indent. */
1256
+ ul.cmu-plain {
1257
+ list-style: none;
1258
+ }
1259
+ /* Replace the template's list indent, including its extra indent from the
1260
+ tenth ordered item onward. Nested ordinary lists keep their own indent. */
1261
+ :is(#content, body) :is(.cmu-flow, .cmu-steps, .cmu-checks) > li {
1262
+ margin-left: 0;
1263
+ }
1264
+ .cmu-checks {
1265
+ list-style: none;
1266
+ margin: 0 0 1rem;
1267
+ padding: 0;
1268
+ }
1269
+ .cmu-checks > li {
1270
+ position: relative;
1271
+ padding: 0 0 0.7rem 1.7rem;
1272
+ line-height: 1.5;
1273
+ }
1274
+ .cmu-checks > li::before {
1275
+ content: "";
1276
+ position: absolute;
1277
+ left: 0.25rem;
1278
+ top: 0.15em;
1279
+ width: 0.5rem;
1280
+ height: 0.85rem;
1281
+ border: solid var(--cmu-red);
1282
+ border-width: 0 3px 3px 0;
1283
+ transform: rotate(45deg);
1284
+ }
1285
+
1286
+ ol.cmu-steps {
1287
+ counter-reset: cmu-step;
1288
+ list-style: none;
1289
+ margin: 0 0 1.5rem;
1290
+ padding: 0;
1291
+ }
1292
+ ol.cmu-steps > li {
1293
+ counter-increment: cmu-step;
1294
+ position: relative;
1295
+ padding: 0 0 1rem 2.4rem;
1296
+ line-height: 1.55;
1297
+ min-height: 1.6rem;
1298
+ }
1299
+ ol.cmu-steps > li::before {
1300
+ content: counter(cmu-step);
1301
+ position: absolute;
1302
+ left: 0;
1303
+ top: 0.05rem;
1304
+ box-sizing: border-box;
1305
+ width: 1.6rem;
1306
+ height: 1.6rem;
1307
+ display: flex;
1308
+ align-items: center;
1309
+ justify-content: center;
1310
+ border: 2px solid var(--cmu-red);
1311
+ border-radius: 50%;
1312
+ color: var(--cmu-red);
1313
+ font-weight: 700;
1314
+ font-size: 0.85rem;
1315
+ }
1316
+
1317
+ /* Tables. The template makes tables display: block so they scroll on
1318
+ phones, which won't stretch them; cmu-full stretches them from 768px.
1319
+ position: relative keeps screen-reader-only text (.sr-only, positioned
1320
+ absolutely) inside that scroll, so it can't widen the page. */
1321
+ table {
1322
+ position: relative;
1323
+ }
1324
+ table.cmu-full {
1325
+ width: 100%;
1326
+ }
1327
+ @media (min-width: 768px) {
1328
+ table.cmu-full {
1329
+ display: table;
1330
+ }
1331
+ }
1332
+ table.cmu-compare {
1333
+ table-layout: fixed;
1334
+ }
1335
+ .cmu-compare th,
1336
+ .cmu-compare td {
1337
+ width: 50%;
1338
+ }
1339
+
1340
+ /* Pills: gray unless given a tone */
1341
+ .cmu-pill {
1342
+ display: inline-block;
1343
+ padding: 0.15rem 0.55rem;
1344
+ font-size: 0.8rem;
1345
+ font-weight: 700;
1346
+ white-space: nowrap;
1347
+ border-radius: 3px;
1348
+ background: var(--cmu-gray-tint);
1349
+ color: var(--cmu-gray);
1350
+ }
1351
+ .cmu-pill--green {
1352
+ background: var(--cmu-green-tint);
1353
+ color: var(--cmu-green);
1354
+ }
1355
+ .cmu-pill--amber {
1356
+ background: var(--cmu-amber-tint);
1357
+ color: var(--cmu-amber);
1358
+ }
1359
+
1360
+ /* Dates: a month-and-day block in the style of the events.cmu.edu (LiveWhale)
1361
+ widgets, for a date on its own or over a photo. A list of dates is the
1362
+ template's .events. Markup: <time class="cmu-date" datetime="2026-10-28">
1363
+ <span class="cmu-date-month">Oct</span> <span class="cmu-date-day">28</span></time> */
1364
+ .cmu-date {
1365
+ display: inline-flex;
1366
+ flex-direction: column;
1367
+ align-items: stretch;
1368
+ flex: 0 0 auto;
1369
+ min-width: 3.25em;
1370
+ border: 1px solid var(--cmu-gray);
1371
+ background: #fff;
1372
+ font-weight: 700;
1373
+ line-height: 1.5;
1374
+ text-transform: uppercase;
1375
+ text-align: center;
1376
+ }
1377
+ .cmu-date-month {
1378
+ background: var(--cmu-gray);
1379
+ color: #fff;
1380
+ padding: 0 0.5em;
1381
+ letter-spacing: 0.05em;
1382
+ }
1383
+ .cmu-date-day {
1384
+ color: var(--cmu-ink);
1385
+ font-size: 1.25em;
1386
+ padding: 0 0.4em;
1387
+ }
1388
+ .cmu-date--red {
1389
+ border-color: var(--cmu-red);
1390
+ }
1391
+ .cmu-date--red .cmu-date-month {
1392
+ background: var(--cmu-red);
1393
+ }
1394
+ /* Event cards: a photo with the date over its corner and a red rule under it */
1395
+ #content .cmu-event-cards,
1396
+ .cmu-event-cards {
1397
+ display: grid;
1398
+ grid-template-columns: repeat(auto-fill, minmax(min(100%, 13rem), 1fr));
1399
+ gap: 1.5rem;
1400
+ list-style: none;
1401
+ margin: 0 0 1.5em;
1402
+ padding: 0;
1403
+ }
1404
+ #content .cmu-event-cards > li {
1405
+ position: relative;
1406
+ margin: 0;
1407
+ padding: 0;
1408
+ }
1409
+ .cmu-event-cards img {
1410
+ display: block;
1411
+ width: 100%;
1412
+ aspect-ratio: 3 / 2;
1413
+ object-fit: cover;
1414
+ border-bottom: 4px solid var(--cmu-red);
1415
+ margin: 0 0 0.5em;
1416
+ }
1417
+ .cmu-event-cards .cmu-date {
1418
+ position: absolute;
1419
+ top: 0.5rem;
1420
+ left: 0.5rem;
1421
+ }
1422
+ .cmu-event-cards h3 {
1423
+ margin: 0;
1424
+ padding: 0;
1425
+ font-size: 1.05em;
1426
+ font-weight: 700;
1427
+ }
1428
+ .cmu-event-cards p {
1429
+ margin: 0.25em 0 0;
1430
+ padding: 0;
1431
+ color: var(--cmu-muted);
1432
+ font-size: 0.9em;
1433
+ }