1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
the trigger and bubble are siblings inside one relatively-positioned span,
shown on :hover/:focus-within so it works from the keyboard too.
`[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
doubles as the styling hook — zero classes there. The wrapping span has no
attribute of its own, but it does not need one: `:has()` picks out "a span
that contains a [role=tooltip] bubble" precisely, without reaching for a
class on an otherwise-generic element. */
span:has(> [role="tooltip"]) {
position: relative;
display: inline-flex;
}
[role="tooltip"] {
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
margin-bottom: 0.375rem;
padding: 0.25rem 0.5rem;
border-radius: var(--gl-radius-sm);
background: var(--gl-color-text-primary);
color: var(--gl-color-surface-page);
font-family: var(--gl-font-mono);
/* 11px is the source's own literal choice — smaller than --gl-step--2, the
smallest step on the scale, because a tooltip is meant to read as a
glance-only aside rather than body text. */
font-size: 11px;
white-space: nowrap;
line-height: 1.4;
z-index: 20;
opacity: 0;
visibility: hidden;
pointer-events: none;
transition: opacity var(--gl-dur-fast) var(--gl-ease);
}
span:has(> [role="tooltip"]):hover > [role="tooltip"],
span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
opacity: 1;
visibility: visible;
}
/* Toast — the real pattern used for delete confirmations: a flat bar with an
optional destructive action and a dismiss. `[data-fixed]` pins it
bottom-right for real use; without it the toast stays in document flow for
documentation. `role="status"` is the correct live-region role for a
transient status message, so it is both the accessibility hook and the
style selector — no base class needed. The action and dismiss buttons are
plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
need anyway for the icon-only close control. */
[role="status"] {
display: flex;
align-items: center;
gap: var(--gl-space-xs);
min-width: 20rem;
padding: var(--gl-space-xs) var(--gl-space-s);
background: var(--gl-color-surface-card);
border: 1px solid var(--gl-color-border-default);
border-radius: var(--gl-radius-md);
box-shadow: var(--gl-shadow-float);
color: var(--gl-color-text-primary);
font-family: var(--gl-font-sans);
font-size: var(--gl-step--2);
}
[role="status"][data-fixed] {
position: fixed;
inset-block-end: var(--gl-space-s);
inset-inline-end: var(--gl-space-s);
z-index: 60;
}
[role="status"] > span { flex: 1; }
[role="status"] button {
all: unset;
cursor: pointer;
font-weight: 600;
color: var(--gl-color-danger);
}
[role="status"] button[aria-label="Dismiss"] {
color: var(--gl-color-text-tertiary);
font-size: 1rem;
font-weight: 400;
line-height: 1;
}
[role="status"] button[aria-label="Dismiss"]:hover { color: var(--gl-color-text-primary); }
/* Dialog — the native <dialog> element: a centered modal, flat surface, no
colored header, hairline dividers between title/body/footer. A <header>
holds the title and a <footer> holds the actions, matching the elements
the tag already wants; everything else in between is the body, styled by
excluding those two rather than by a class of its own.
`.dialog-demo` scopes a static, always-open example to its own preview
container instead of the viewport, so it can sit safely inside a
documentation page — this is a doc-only affordance, not part of Dialog's
contract. It relies on the browser's own dialog centering: the UA
stylesheet already gives an open <dialog> `position: absolute; inset: 0;
margin: auto`, which centers it inside the nearest positioned ancestor —
here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
(used here so the demo renders without JavaScript) does not paint a
backdrop at all, since `::backdrop` only exists for a dialog shown
modally — wire the real open/close state and call `.showModal()` in the
consuming app. */
.dialog-demo {
position: relative;
min-height: 20rem;
background: var(--gl-color-surface-fill);
border-radius: var(--gl-radius-lg);
}
dialog {
width: 26rem;
max-width: calc(100% - (2 * var(--gl-space-s)));
height: fit-content;
padding: 0;
background: var(--gl-color-surface-card);
border: 1px solid var(--gl-color-border-hairline);
border-radius: var(--gl-radius-lg);
box-shadow: var(--gl-shadow-float);
color: var(--gl-color-text-primary);
overflow: hidden;
}
dialog::backdrop {
background: rgba(20, 18, 14, 0.35);
}
dialog > header {
padding: var(--gl-space-s) var(--gl-space-m);
border-bottom: 1px solid var(--gl-color-border-hairline);
font-family: var(--gl-font-sans);
font-weight: 600;
font-size: var(--gl-step-0);
color: var(--gl-color-text-primary);
}
dialog > footer {
display: flex;
justify-content: flex-end;
gap: var(--gl-space-2xs);
padding: var(--gl-space-s) var(--gl-space-m);
border-top: 1px solid var(--gl-color-border-hairline);
}
dialog > *:not(header):not(footer) {
padding: var(--gl-space-m);
margin: 0;
color: var(--gl-color-text-primary);
font-size: var(--gl-step--1);
}