@motion-proto/live-tokens 0.91.2 → 0.92.0
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.
- package/.claude/skills/live-tokens-create-page/SKILL.md +10 -3
- package/.claude/skills/live-tokens-set-type/SKILL.md +3 -3
- package/CHANGELOG.md +140 -0
- package/bin/lib/tokenVocabulary.mjs +2 -2
- package/bin/rules/testRuns.mjs +1 -1
- package/bin/rules/tokens.mjs +3 -3
- package/dist-plugin/chunk-JOSSYGR2.js +1634 -0
- package/dist-plugin/index.cjs +932 -15
- package/dist-plugin/index.js +1 -1
- package/dist-plugin/setType/index.cjs +23 -2
- package/dist-plugin/setType/index.js +23 -2
- package/dist-plugin/tokensCssMigrations/index.cjs +936 -15
- package/dist-plugin/tokensCssMigrations/index.d.cts +23 -3
- package/dist-plugin/tokensCssMigrations/index.d.ts +23 -3
- package/dist-plugin/tokensCssMigrations/index.js +5 -1
- package/package.json +1 -1
- package/src/app/site.css +243 -9
- package/src/demo/TestingLoops.svelte +9 -9
- package/src/editor/core/fonts/weightCoverage.ts +31 -2
- package/src/editor/core/palettes/tokenRegistry.ts +36 -37
- package/src/editor/core/themes/parsers/mediaBlocks.ts +46 -0
- package/src/editor/core/typeScale/typeScale.ts +341 -0
- package/src/editor/skill-atlas/SourcePane.svelte +3 -3
- package/src/editor/skill-atlas/skillSources.generated.ts +2 -2
- package/src/editor/skill-atlas/trees/create-page.ts +14 -14
- package/src/editor/skill-atlas/trees/set-type.ts +2 -2
- package/src/editor/ui/UIFontFamilySelector.svelte +5 -1
- package/src/editor/ui/UIFontWeightSelector.svelte +4 -0
- package/src/editor/ui/UILetterSpacingSelector.svelte +4 -0
- package/src/editor/ui/UILineHeightSelector.svelte +4 -0
- package/src/editor/ui/UITextTransformSelector.svelte +4 -0
- package/src/editor/ui/UIVariantSelector.svelte +6 -8
- package/src/editor/ui/VariablesTab.svelte +4 -4
- package/src/editor/ui/sections/textStyles.ts +44 -92
- package/src/editor/ui/text-styles/ControlBody.svelte +100 -0
- package/src/editor/ui/text-styles/ResetIcon.svelte +60 -0
- package/src/editor/ui/text-styles/StepRow.svelte +330 -0
- package/src/editor/ui/text-styles/StyleControl.svelte +128 -0
- package/src/editor/ui/text-styles/TextStylesSection.svelte +551 -0
- package/src/editor/ui/text-styles/textStyleEdits.ts +308 -0
- package/src/editor/ui/variantScales.ts +16 -0
- package/src/system/styles/tokens.css +412 -48
- package/src/testing-js/page-compliance.contract.js +233 -80
- package/src/testing-js/page-compliance.contract.js.map +1 -1
- package/dist-plugin/chunk-GWMEYBZ2.js +0 -715
- package/src/editor/ui/TextStylesSection.svelte +0 -171
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import UIFontFamilySelector from '../UIFontFamilySelector.svelte';
|
|
3
|
+
import UIFontWeightSelector from '../UIFontWeightSelector.svelte';
|
|
4
|
+
import UILetterSpacingSelector from '../UILetterSpacingSelector.svelte';
|
|
5
|
+
import UILineHeightSelector from '../UILineHeightSelector.svelte';
|
|
6
|
+
import UITextTransformSelector from '../UITextTransformSelector.svelte';
|
|
7
|
+
import type { TextStyle } from '../sections/textStyles';
|
|
8
|
+
import {
|
|
9
|
+
DEFAULTS,
|
|
10
|
+
VIEWPORTS,
|
|
11
|
+
axisName,
|
|
12
|
+
sizeName,
|
|
13
|
+
usageName,
|
|
14
|
+
type StyleAxis,
|
|
15
|
+
type Viewport,
|
|
16
|
+
} from '../../core/typeScale/typeScale';
|
|
17
|
+
import ControlBody from './ControlBody.svelte';
|
|
18
|
+
import ResetIcon from './ResetIcon.svelte';
|
|
19
|
+
import StyleControl from './StyleControl.svelte';
|
|
20
|
+
import {
|
|
21
|
+
SIZE_RANGE_PX,
|
|
22
|
+
SMALL_SIZE_PX,
|
|
23
|
+
faceLabel,
|
|
24
|
+
formatPx,
|
|
25
|
+
isLinked,
|
|
26
|
+
isStored,
|
|
27
|
+
linkExpression,
|
|
28
|
+
sizesOf,
|
|
29
|
+
valueOf,
|
|
30
|
+
weightLabel,
|
|
31
|
+
type LinkAxis,
|
|
32
|
+
type StyleTarget,
|
|
33
|
+
type TextStyleEdits,
|
|
34
|
+
type TokenView,
|
|
35
|
+
} from './textStyleEdits';
|
|
36
|
+
|
|
37
|
+
interface Props {
|
|
38
|
+
target: StyleTarget;
|
|
39
|
+
style: TextStyle;
|
|
40
|
+
view: TokenView;
|
|
41
|
+
/** The viewport the sample renders at and the sizes highlight. */
|
|
42
|
+
viewport: Viewport;
|
|
43
|
+
edits: TextStyleEdits;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
let { target, style, view, viewport, edits }: Props = $props();
|
|
47
|
+
|
|
48
|
+
const VIEWPORT_LABEL: Record<Viewport, string> = { desktop: 'Desktop', tablet: 'Tablet', phone: 'Phone' };
|
|
49
|
+
|
|
50
|
+
let sizes = $derived(sizesOf(view, target));
|
|
51
|
+
let prefix = $derived(target.prefix);
|
|
52
|
+
const axis = (a: StyleAxis) => axisName(prefix, a);
|
|
53
|
+
let chip = $derived(
|
|
54
|
+
target.step === null
|
|
55
|
+
? style.defaultElement
|
|
56
|
+
: DEFAULTS.usages[target.usage].elements[target.step]?.join(', '),
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
let sampleStyle = $derived(
|
|
60
|
+
[
|
|
61
|
+
`font-family: var(${axis('font-family')})`,
|
|
62
|
+
`font-size: var(${sizeName(prefix, viewport)})`,
|
|
63
|
+
`font-weight: var(${axis('font-weight')})`,
|
|
64
|
+
`line-height: var(${axis('line-height')})`,
|
|
65
|
+
`letter-spacing: var(${axis('letter-spacing')})`,
|
|
66
|
+
...(style.hasTextTransform ? [`text-transform: var(${axis('text-transform')})`] : []),
|
|
67
|
+
].join('; '),
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
// A typed value that the store leaves unchanged would otherwise stay in the
|
|
71
|
+
// input, so the input re-reads the size the store now resolves.
|
|
72
|
+
function editSize(vp: Viewport, input: HTMLInputElement) {
|
|
73
|
+
edits.setSize(target, vp, input.valueAsNumber);
|
|
74
|
+
input.value = formatPx(sizesOf(edits.view(), target)[vp].px);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function link(a: LinkAxis, label: (value: string) => string) {
|
|
78
|
+
return {
|
|
79
|
+
linked: isLinked(view, target, a),
|
|
80
|
+
text: label(valueOf(view, usageName(target.usage, a))),
|
|
81
|
+
title: `Linked to ${linkExpression(target, a)}`,
|
|
82
|
+
ontoggle: () => edits.toggleLink(target, a),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const write = (a: StyleAxis) => (value: string | null) => edits.writeToken(axis(a), value);
|
|
87
|
+
const reset = (a: StyleAxis) => () => edits.resetKey(axis(a));
|
|
88
|
+
</script>
|
|
89
|
+
|
|
90
|
+
<div class="step">
|
|
91
|
+
<div class="step-id">
|
|
92
|
+
<code class="step-name">{style.name}</code>
|
|
93
|
+
{#if chip}
|
|
94
|
+
<span class="chip">{chip}</span>
|
|
95
|
+
{/if}
|
|
96
|
+
{#if sizes[viewport].px < SMALL_SIZE_PX}
|
|
97
|
+
<span class="flag">Below {SMALL_SIZE_PX}px</span>
|
|
98
|
+
{/if}
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
<div class="sizes">
|
|
102
|
+
{#each VIEWPORTS as vp (vp)}
|
|
103
|
+
{@const size = sizes[vp]}
|
|
104
|
+
<div class="size-row" class:is-current={vp === viewport} data-reset-scope>
|
|
105
|
+
<span class="size-label">{VIEWPORT_LABEL[vp]}</span>
|
|
106
|
+
<ControlBody width="4.75rem" linked={!size.edited}>
|
|
107
|
+
<input
|
|
108
|
+
class="size-input"
|
|
109
|
+
type="number"
|
|
110
|
+
min={SIZE_RANGE_PX.min}
|
|
111
|
+
max={SIZE_RANGE_PX.max}
|
|
112
|
+
step="any"
|
|
113
|
+
value={formatPx(size.px)}
|
|
114
|
+
aria-label="{style.name} {vp} size in px"
|
|
115
|
+
title={size.edited ? `Recommended ${formatPx(size.recommendedPx)}px` : 'Recommended size'}
|
|
116
|
+
onchange={(e) => editSize(vp, e.currentTarget)}
|
|
117
|
+
/>
|
|
118
|
+
{#snippet after()}
|
|
119
|
+
<span class="unit">px</span>
|
|
120
|
+
<ResetIcon
|
|
121
|
+
label="{style.name} {vp} size"
|
|
122
|
+
visible={size.edited}
|
|
123
|
+
onreset={() => edits.resetSize(target, vp)}
|
|
124
|
+
/>
|
|
125
|
+
{/snippet}
|
|
126
|
+
</ControlBody>
|
|
127
|
+
</div>
|
|
128
|
+
{/each}
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
<div class="step-sample" style={sampleStyle}>{style.preview}</div>
|
|
132
|
+
|
|
133
|
+
<div class="step-controls">
|
|
134
|
+
<StyleControl
|
|
135
|
+
label="Face"
|
|
136
|
+
name="{style.name} face"
|
|
137
|
+
width="10rem"
|
|
138
|
+
resetVisible={isStored(view, axis('font-family'))}
|
|
139
|
+
onreset={reset('font-family')}
|
|
140
|
+
link={link('font-family', faceLabel)}
|
|
141
|
+
>
|
|
142
|
+
<UIFontFamilySelector variable={axis('font-family')} onwrite={write('font-family')} />
|
|
143
|
+
</StyleControl>
|
|
144
|
+
<StyleControl
|
|
145
|
+
label="Weight"
|
|
146
|
+
name="{style.name} weight"
|
|
147
|
+
width="8rem"
|
|
148
|
+
resetVisible={isStored(view, axis('font-weight'))}
|
|
149
|
+
onreset={reset('font-weight')}
|
|
150
|
+
link={link('font-weight', weightLabel)}
|
|
151
|
+
>
|
|
152
|
+
<UIFontWeightSelector variable={axis('font-weight')} onwrite={write('font-weight')} />
|
|
153
|
+
</StyleControl>
|
|
154
|
+
<StyleControl
|
|
155
|
+
label="Line height"
|
|
156
|
+
name="{style.name} line height"
|
|
157
|
+
width="8rem"
|
|
158
|
+
resetVisible={isStored(view, axis('line-height'))}
|
|
159
|
+
onreset={reset('line-height')}
|
|
160
|
+
>
|
|
161
|
+
<UILineHeightSelector variable={axis('line-height')} onwrite={write('line-height')} />
|
|
162
|
+
</StyleControl>
|
|
163
|
+
<StyleControl
|
|
164
|
+
label="Letter spacing"
|
|
165
|
+
name="{style.name} letter spacing"
|
|
166
|
+
width="9.5rem"
|
|
167
|
+
resetVisible={isStored(view, axis('letter-spacing'))}
|
|
168
|
+
onreset={reset('letter-spacing')}
|
|
169
|
+
>
|
|
170
|
+
<UILetterSpacingSelector variable={axis('letter-spacing')} onwrite={write('letter-spacing')} />
|
|
171
|
+
</StyleControl>
|
|
172
|
+
{#if style.hasTextTransform}
|
|
173
|
+
<StyleControl
|
|
174
|
+
label="Transform"
|
|
175
|
+
name="{style.name} transform"
|
|
176
|
+
width="8rem"
|
|
177
|
+
resetVisible={isStored(view, axis('text-transform'))}
|
|
178
|
+
onreset={reset('text-transform')}
|
|
179
|
+
>
|
|
180
|
+
<UITextTransformSelector variable={axis('text-transform')} onwrite={write('text-transform')} />
|
|
181
|
+
</StyleControl>
|
|
182
|
+
{/if}
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
|
|
186
|
+
<style>
|
|
187
|
+
.step {
|
|
188
|
+
display: grid;
|
|
189
|
+
grid-template-columns: 7.5rem 11.5rem minmax(0, 1fr);
|
|
190
|
+
column-gap: var(--ui-space-16);
|
|
191
|
+
row-gap: var(--ui-space-10);
|
|
192
|
+
padding: var(--ui-space-12) var(--ui-space-10);
|
|
193
|
+
border-bottom: 1px solid var(--ui-border-low);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.step:last-child {
|
|
197
|
+
border-bottom: none;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.step-id {
|
|
201
|
+
grid-row: 1 / span 2;
|
|
202
|
+
display: flex;
|
|
203
|
+
flex-direction: column;
|
|
204
|
+
align-items: flex-start;
|
|
205
|
+
gap: var(--ui-space-6);
|
|
206
|
+
min-width: 0;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.step-name {
|
|
210
|
+
font-family: var(--ui-font-mono);
|
|
211
|
+
font-size: var(--ui-font-size-sm);
|
|
212
|
+
color: var(--ui-text-primary);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.chip {
|
|
216
|
+
padding: 1px var(--ui-space-8);
|
|
217
|
+
border: 1px solid var(--ui-border-low);
|
|
218
|
+
border-radius: var(--ui-radius-full);
|
|
219
|
+
color: var(--ui-text-secondary);
|
|
220
|
+
font-family: var(--ui-font-mono);
|
|
221
|
+
font-size: var(--ui-font-size-xs);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.flag {
|
|
225
|
+
padding: 1px var(--ui-space-8);
|
|
226
|
+
border: 1px dashed var(--ui-border-high);
|
|
227
|
+
border-radius: var(--ui-radius-full);
|
|
228
|
+
color: var(--ui-text-primary);
|
|
229
|
+
font-size: var(--ui-font-size-xs);
|
|
230
|
+
white-space: nowrap;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.sizes {
|
|
234
|
+
grid-row: 1 / span 2;
|
|
235
|
+
display: grid;
|
|
236
|
+
align-content: start;
|
|
237
|
+
gap: var(--ui-space-6);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.size-row {
|
|
241
|
+
display: grid;
|
|
242
|
+
grid-template-columns: 3.5rem auto;
|
|
243
|
+
align-items: center;
|
|
244
|
+
gap: var(--ui-space-4);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.size-label {
|
|
248
|
+
color: var(--ui-text-muted);
|
|
249
|
+
font-size: var(--ui-font-size-xs);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.size-row.is-current .size-label {
|
|
253
|
+
color: var(--ui-text-primary);
|
|
254
|
+
font-weight: var(--ui-font-weight-semibold);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.size-input {
|
|
258
|
+
box-sizing: border-box;
|
|
259
|
+
width: 100%;
|
|
260
|
+
height: 1.75rem;
|
|
261
|
+
padding: 0 var(--ui-space-8);
|
|
262
|
+
background: var(--ui-surface-high);
|
|
263
|
+
border: 1px solid var(--ui-border-low);
|
|
264
|
+
border-radius: var(--ui-radius-md);
|
|
265
|
+
color: var(--ui-text-primary);
|
|
266
|
+
font: inherit;
|
|
267
|
+
font-size: var(--ui-font-size-sm);
|
|
268
|
+
font-variant-numeric: tabular-nums;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.size-input:hover {
|
|
272
|
+
border-color: var(--ui-border-high);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.size-input:focus-visible {
|
|
276
|
+
outline: 2px solid var(--ui-text-primary);
|
|
277
|
+
outline-offset: 2px;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.unit {
|
|
281
|
+
flex: none;
|
|
282
|
+
color: var(--ui-text-muted);
|
|
283
|
+
font-size: var(--ui-font-size-xs);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/* Samples take the editor's ink; colour sits outside a text style. */
|
|
287
|
+
.step-sample {
|
|
288
|
+
grid-column: 3;
|
|
289
|
+
min-width: 0;
|
|
290
|
+
max-width: min(100%, 22ch);
|
|
291
|
+
color: var(--ui-text-primary);
|
|
292
|
+
display: -webkit-box;
|
|
293
|
+
-webkit-line-clamp: 2;
|
|
294
|
+
line-clamp: 2;
|
|
295
|
+
-webkit-box-orient: vertical;
|
|
296
|
+
overflow: hidden;
|
|
297
|
+
overflow-wrap: anywhere;
|
|
298
|
+
text-wrap: balance;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.step-controls {
|
|
302
|
+
grid-column: 3;
|
|
303
|
+
align-self: end;
|
|
304
|
+
display: flex;
|
|
305
|
+
flex-wrap: wrap;
|
|
306
|
+
gap: var(--ui-space-12);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
@media (max-width: 720px) {
|
|
310
|
+
.step {
|
|
311
|
+
grid-template-columns: minmax(0, 1fr);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.step-id {
|
|
315
|
+
grid-row: auto;
|
|
316
|
+
flex-direction: row;
|
|
317
|
+
align-items: center;
|
|
318
|
+
flex-wrap: wrap;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.sizes {
|
|
322
|
+
grid-row: auto;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.step-sample,
|
|
326
|
+
.step-controls {
|
|
327
|
+
grid-column: auto;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
</style>
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import ControlBody from './ControlBody.svelte';
|
|
4
|
+
import ResetIcon from './ResetIcon.svelte';
|
|
5
|
+
|
|
6
|
+
interface Link {
|
|
7
|
+
linked: boolean;
|
|
8
|
+
/** What the linked value shows, such as the usage's face. */
|
|
9
|
+
text: string;
|
|
10
|
+
/** The link expression, shown as the linked value's tooltip. */
|
|
11
|
+
title: string;
|
|
12
|
+
ontoggle: () => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface Props {
|
|
16
|
+
label: string;
|
|
17
|
+
/** Names the control in accessible labels, such as `heading-xl face`. */
|
|
18
|
+
name: string;
|
|
19
|
+
width: string;
|
|
20
|
+
resetVisible: boolean;
|
|
21
|
+
onreset: () => void;
|
|
22
|
+
link?: Link;
|
|
23
|
+
children: Snippet;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let { label, name, width, resetVisible, onreset, link, children }: Props = $props();
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<div class="ctl" data-reset-scope>
|
|
30
|
+
<div class="ctl-head">
|
|
31
|
+
<span class="ctl-label">{label}</span>
|
|
32
|
+
<ResetIcon label={name} visible={resetVisible} {onreset} />
|
|
33
|
+
</div>
|
|
34
|
+
<ControlBody {width} linked={link ? link.linked : null}>
|
|
35
|
+
{#if link?.linked}
|
|
36
|
+
<span class="linked-value" title={link.title}>{link.text}</span>
|
|
37
|
+
{:else}
|
|
38
|
+
{@render children()}
|
|
39
|
+
{/if}
|
|
40
|
+
{#snippet after()}
|
|
41
|
+
{#if link}
|
|
42
|
+
<button
|
|
43
|
+
type="button"
|
|
44
|
+
class="lock"
|
|
45
|
+
class:is-unlinked={!link.linked}
|
|
46
|
+
aria-pressed={link.linked}
|
|
47
|
+
aria-label="{link.linked ? 'Unlink' : 'Relink'} {name}"
|
|
48
|
+
title={link.linked ? 'Unlink' : 'Relink'}
|
|
49
|
+
onclick={link.ontoggle}
|
|
50
|
+
>
|
|
51
|
+
<i class="fas {link.linked ? 'fa-lock' : 'fa-lock-open'}" aria-hidden="true"></i>
|
|
52
|
+
</button>
|
|
53
|
+
{/if}
|
|
54
|
+
{/snippet}
|
|
55
|
+
</ControlBody>
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<style>
|
|
59
|
+
.ctl {
|
|
60
|
+
display: flex;
|
|
61
|
+
flex-direction: column;
|
|
62
|
+
gap: var(--ui-space-4);
|
|
63
|
+
min-width: 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* The label line has a fixed height and the reset icon trails the label, so
|
|
67
|
+
showing or hiding the icon moves nothing. */
|
|
68
|
+
.ctl-head {
|
|
69
|
+
display: flex;
|
|
70
|
+
align-items: center;
|
|
71
|
+
gap: var(--ui-space-4);
|
|
72
|
+
height: 18px;
|
|
73
|
+
min-width: 0;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.ctl-label {
|
|
77
|
+
font-size: var(--ui-font-size-xs);
|
|
78
|
+
font-weight: var(--ui-font-weight-semibold);
|
|
79
|
+
color: var(--ui-text-secondary);
|
|
80
|
+
white-space: nowrap;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.linked-value {
|
|
84
|
+
box-sizing: border-box;
|
|
85
|
+
display: block;
|
|
86
|
+
height: 1.75rem;
|
|
87
|
+
padding: 0 var(--ui-space-8);
|
|
88
|
+
background: var(--ui-surface-higher);
|
|
89
|
+
border: 1px solid var(--ui-border-low);
|
|
90
|
+
border-left: none;
|
|
91
|
+
border-radius: 0 var(--ui-radius-md) var(--ui-radius-md) 0;
|
|
92
|
+
color: var(--ui-text-secondary);
|
|
93
|
+
font-size: var(--ui-font-size-sm);
|
|
94
|
+
line-height: calc(1.75rem - 2px);
|
|
95
|
+
white-space: nowrap;
|
|
96
|
+
overflow: hidden;
|
|
97
|
+
text-overflow: ellipsis;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.lock {
|
|
101
|
+
flex: none;
|
|
102
|
+
display: inline-grid;
|
|
103
|
+
place-items: center;
|
|
104
|
+
width: 24px;
|
|
105
|
+
height: 24px;
|
|
106
|
+
padding: 0;
|
|
107
|
+
background: none;
|
|
108
|
+
border: none;
|
|
109
|
+
border-radius: var(--ui-radius-md);
|
|
110
|
+
color: var(--ui-text-tertiary);
|
|
111
|
+
font-size: 0.8125rem;
|
|
112
|
+
cursor: pointer;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.lock:hover {
|
|
116
|
+
color: var(--ui-text-primary);
|
|
117
|
+
background: var(--ui-surface-higher);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.lock:focus-visible {
|
|
121
|
+
outline: 2px solid var(--ui-text-primary);
|
|
122
|
+
outline-offset: 1px;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.lock.is-unlinked {
|
|
126
|
+
color: var(--ui-link-broken);
|
|
127
|
+
}
|
|
128
|
+
</style>
|