@crewlethq/ui 0.4.3 → 0.5.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/README.md +888 -24
- package/dist/Accordion/index.js +2 -2
- package/dist/AddPill/index.js +1 -1
- package/dist/{AddPill-DFWXYLIQ.css → AddPill-IJQYCY6C.css} +9 -0
- package/dist/AppShell/AppShell.d.ts +26 -5
- package/dist/AppShell/index.js +3 -3
- package/dist/{AppShell-NVE6LHNI.css → AppShell-XARELGIH.css} +178 -25
- package/dist/Avatar/Avatar.d.ts +85 -40
- package/dist/Avatar/AvatarStack.d.ts +76 -0
- package/dist/Avatar/index.d.ts +5 -2
- package/dist/Avatar/index.js +1 -1
- package/dist/Avatar-XID7Z74C.css +200 -0
- package/dist/AvatarStack-GEJBNV7E.css +72 -0
- package/dist/BrandLockup/index.js +1 -1
- package/dist/{BrandLockup-6ISDEHPJ.css → BrandLockup-JKGXFCZF.css} +25 -19
- package/dist/Button/Button.d.ts +7 -2
- package/dist/Button/index.js +1 -1
- package/dist/{Button-D4J6B4MA.css → Button-X4B2TJAQ.css} +50 -19
- package/dist/Callout/index.js +1 -1
- package/dist/Canvas/index.js +4 -4
- package/dist/Card/Card.d.ts +9 -5
- package/dist/Card/index.js +1 -1
- package/dist/{Card-RLR254LD.css → Card-GLP7SUV6.css} +25 -18
- package/dist/Charts/BarList.d.ts +18 -1
- package/dist/Charts/ChartTooltip.d.ts +68 -0
- package/dist/Charts/StackedBar.d.ts +25 -7
- package/dist/Charts/StackedColumns.d.ts +112 -0
- package/dist/Charts/TimeSeries.d.ts +33 -2
- package/dist/Charts/dataColor.d.ts +22 -14
- package/dist/Charts/index.d.ts +6 -0
- package/dist/Charts/index.js +1 -1
- package/dist/Charts/useChartHover.d.ts +56 -0
- package/dist/Charts-B3YEF7R4.css +742 -0
- package/dist/Checkbox/index.js +1 -1
- package/dist/{Checkbox-VGW26YLQ.css → Checkbox-BOXQ747I.css} +2 -2
- package/dist/CodeBlock/index.js +4 -4
- package/dist/Combobox/index.js +5 -5
- package/dist/CommandPalette/CommandPalette.d.ts +97 -6
- package/dist/CommandPalette/index.d.ts +1 -1
- package/dist/CommandPalette/index.js +9 -7
- package/dist/CommandPalette-C5AMKGN2.css +259 -0
- package/dist/Copyable/index.js +3 -3
- package/dist/DataTable/index.js +7 -7
- package/dist/{DataTable-ITNACQ2X.css → DataTable-OLHPF7D4.css} +44 -43
- package/dist/DataView/index.js +14 -14
- package/dist/{DataView-256YF32J.css → DataView-N6JX464S.css} +5 -4
- package/dist/DateTimePicker/index.js +5 -5
- package/dist/DiffList/index.js +1 -1
- package/dist/Disclosure/index.js +2 -2
- package/dist/EntityChip/EntityChip.d.ts +9 -12
- package/dist/EntityChip/index.d.ts +1 -1
- package/dist/EntityChip/index.js +2 -2
- package/dist/ErrorBoundary/index.js +2 -2
- package/dist/{ErrorBoundary-ME36CQTA.css → ErrorBoundary-U2PA3LY2.css} +4 -4
- package/dist/IconButton/index.js +1 -1
- package/dist/{IconButton-VQGNMJDI.css → IconButton-TVEUWK6L.css} +2 -2
- package/dist/ImageUpload/ImageUpload.d.ts +10 -7
- package/dist/ImageUpload/index.js +2 -2
- package/dist/{ImageUpload-HKFIZR6D.css → ImageUpload-YCHJMUGX.css} +24 -10
- package/dist/Input/index.js +2 -2
- package/dist/Kbd/Kbd.d.ts +14 -4
- package/dist/Kbd/index.js +1 -1
- package/dist/Kbd-JPLDVJIP.css +71 -0
- package/dist/Layer/index.js +1 -1
- package/dist/Link/index.js +1 -1
- package/dist/List/index.js +1 -1
- package/dist/{List-XTHESXLR.css → List-MYJIV6MP.css} +12 -2
- package/dist/ListInput/index.js +5 -5
- package/dist/Listbox/index.js +2 -2
- package/dist/Listbox/useListbox.d.ts +16 -0
- package/dist/Listbox/useOptionKeys.d.ts +12 -1
- package/dist/{Listbox-X2DOTSQA.css → Listbox-6WJNJQVQ.css} +60 -7
- package/dist/Menu/index.js +4 -4
- package/dist/{Menu-6DE7I66I.css → Menu-BT5PMFJI.css} +15 -0
- package/dist/Meter/Meter.d.ts +103 -16
- package/dist/Meter/index.d.ts +2 -2
- package/dist/Meter/index.js +1 -1
- package/dist/{Meter-SKOOXQBC.css → Meter-5VCSFMZW.css} +46 -7
- package/dist/Modal/index.js +4 -4
- package/dist/{Modal-XYQJ4BL6.css → Modal-JAYBS2KS.css} +13 -4
- package/dist/OrgLabel/OrgLabel.d.ts +60 -24
- package/dist/OrgLabel/index.d.ts +1 -1
- package/dist/OrgLabel/index.js +2 -1
- package/dist/{OrgLabel-D7U6QJZD.css → OrgLabel-CR233G34.css} +9 -18
- package/dist/OrgNode/index.js +3 -2
- package/dist/OrgTable/OrgTable.d.ts +2 -2
- package/dist/OrgTable/index.js +8 -7
- package/dist/Popover/index.js +2 -2
- package/dist/PricingCard/index.js +3 -3
- package/dist/{PricingCard-JFI7RYXP.css → PricingCard-7EFXRSD2.css} +4 -5
- package/dist/SearchTrigger/SearchTrigger.d.ts +23 -4
- package/dist/SearchTrigger/index.d.ts +1 -1
- package/dist/SearchTrigger/index.js +1 -1
- package/dist/SearchTrigger-Z5D4AAY7.css +112 -0
- package/dist/SegmentedControl/index.js +2 -2
- package/dist/SegmentedMeter/SegmentedMeter.d.ts +107 -0
- package/dist/SegmentedMeter/index.d.ts +3 -0
- package/dist/SegmentedMeter/index.js +2 -0
- package/dist/SegmentedMeter-KQNML2TW.css +109 -0
- package/dist/Select/index.js +3 -3
- package/dist/{Select-2X77FSWR.css → Select-E24U5LBC.css} +34 -0
- package/dist/Shortcut/index.js +2 -2
- package/dist/SidebarNav/SidebarNav.d.ts +85 -25
- package/dist/SidebarNav/index.d.ts +1 -1
- package/dist/SidebarNav/index.js +1 -1
- package/dist/SidebarNav-X5NLZNWA.css +424 -0
- package/dist/StatCard/StatCard.d.ts +59 -12
- package/dist/StatCard/index.d.ts +1 -1
- package/dist/StatCard/index.js +1 -1
- package/dist/StatCard-KPAFD4E2.css +204 -0
- package/dist/StatGroup/index.js +1 -1
- package/dist/{StatGroup-TGB6AEKM.css → StatGroup-HVG6O62W.css} +8 -9
- package/dist/StatusDot/StatusDot.d.ts +24 -6
- package/dist/StatusDot/index.js +1 -1
- package/dist/StatusDot-7OMCQCZF.css +186 -0
- package/dist/Stepper/Stepper.d.ts +78 -0
- package/dist/Stepper/index.d.ts +3 -0
- package/dist/Stepper/index.js +4 -0
- package/dist/Stepper-HW4JM3YH.css +176 -0
- package/dist/Table/index.js +1 -1
- package/dist/{Table-MDOLVUAW.css → Table-TGCS4C3F.css} +14 -4
- package/dist/Tabs/index.js +1 -1
- package/dist/{Tabs-VLICJFVB.css → Tabs-XCNPHA7B.css} +79 -27
- package/dist/Tag/Tag.d.ts +29 -22
- package/dist/Tag/index.js +2 -2
- package/dist/{Tag-VNZEYLB6.css → Tag-GBE7LQJP.css} +82 -83
- package/dist/TagsInput/index.js +6 -6
- package/dist/ThemeSwitcher/ThemeSwitcher.d.ts +53 -21
- package/dist/ThemeSwitcher/index.d.ts +3 -3
- package/dist/ThemeSwitcher/index.js +4 -3
- package/dist/ThemeSwitcher/preferences.d.ts +19 -5
- package/dist/ThemeToggle/ThemeToggle.d.ts +40 -0
- package/dist/ThemeToggle/index.d.ts +2 -0
- package/dist/ThemeToggle/index.js +5 -0
- package/dist/TimeWindowPicker/index.js +8 -8
- package/dist/Toaster/index.js +2 -2
- package/dist/Toolbar/index.js +2 -2
- package/dist/{Toolbar-IP6LXN45.css → Toolbar-HUOSMNTH.css} +3 -1
- package/dist/Tooltip/index.js +2 -2
- package/dist/Tree/index.d.ts +2 -2
- package/dist/Tree/index.js +1 -1
- package/dist/Tree/layout.d.ts +103 -28
- package/dist/TreeCanvas/TreeCanvas.d.ts +60 -14
- package/dist/TreeCanvas/index.d.ts +1 -1
- package/dist/TreeCanvas/index.js +6 -6
- package/dist/TreeCanvas/motion.d.ts +3 -2
- package/dist/{TreeCanvas-WBNQPHC7.css → TreeCanvas-HVOV4SQN.css} +154 -30
- package/dist/TreeGrid/index.js +4 -4
- package/dist/{chunk-F6OE5FH3.js → chunk-2FPENTCF.js} +1 -1
- package/dist/chunk-4AK52VHB.js +88 -0
- package/dist/{chunk-7EM5T4ME.js → chunk-4IQD3HUQ.js} +2 -2
- package/dist/{chunk-YODNNSZL.js → chunk-4PZ6FJKW.js} +43 -13
- package/dist/{chunk-F27EPQ7D.js → chunk-4UQ7SMPK.js} +1 -1
- package/dist/chunk-5QWIJSQM.js +73 -0
- package/dist/{chunk-GTOUGQQK.js → chunk-6MU7HNB4.js} +13 -10
- package/dist/{chunk-S2XHHEW4.js → chunk-74KMX7YH.js} +4 -4
- package/dist/{chunk-WNI2WSJF.js → chunk-7KBNFFM3.js} +1 -1
- package/dist/{chunk-DD5BBGBE.js → chunk-AUS5FNQE.js} +9 -5
- package/dist/{chunk-CMEE37QJ.js → chunk-BMYPGGPV.js} +4 -4
- package/dist/{chunk-H4FBTAYS.js → chunk-BNCCEER3.js} +8 -8
- package/dist/chunk-C5WJUZVR.js +56 -0
- package/dist/{chunk-5WS6L6FA.js → chunk-CAIHUYXV.js} +9 -9
- package/dist/{chunk-XV6WRMBC.js → chunk-CQY5NTRS.js} +4 -1
- package/dist/{chunk-UOGSZKLT.js → chunk-D6EVJUGU.js} +2 -2
- package/dist/{chunk-6ZFVFA56.js → chunk-DHPUMOTX.js} +2 -2
- package/dist/{chunk-HZ5XZNPS.js → chunk-DS2C73RJ.js} +3 -3
- package/dist/{chunk-O6232G37.js → chunk-DSUY5F4E.js} +17 -5
- package/dist/{chunk-Q4ZPPART.js → chunk-EFYPAJT3.js} +3 -3
- package/dist/{chunk-WQX73TWF.js → chunk-ERVO6OUF.js} +18 -17
- package/dist/{chunk-BZYDZBAN.js → chunk-ETYEBKR4.js} +3 -3
- package/dist/{chunk-34VGEDVV.js → chunk-FD5UEN6X.js} +30 -30
- package/dist/{chunk-5SDBMKUO.js → chunk-FIFNP6PL.js} +3 -3
- package/dist/{chunk-7HPRF5XN.js → chunk-FUF52K7E.js} +98 -16
- package/dist/{chunk-5KPQ6D7N.js → chunk-FZVJDJFN.js} +2 -2
- package/dist/chunk-IA232OTU.js +156 -0
- package/dist/{chunk-2EOKFKHX.js → chunk-IG27QX7Q.js} +7 -7
- package/dist/chunk-IKB6HFGK.js +55 -0
- package/dist/{chunk-FBZAKNSX.js → chunk-IPVQKAHO.js} +10 -7
- package/dist/{chunk-3EYF6HKB.js → chunk-IVFJD7WY.js} +28 -9
- package/dist/{chunk-WOYYD2YR.js → chunk-JGRNTBF2.js} +11 -11
- package/dist/chunk-K3OWD7BJ.js +121 -0
- package/dist/{chunk-BJSKPEZI.js → chunk-KD4H66L6.js} +7 -20
- package/dist/{chunk-SFZOKW2G.js → chunk-KJ34ZBBI.js} +8 -3
- package/dist/{chunk-HQNHV7D6.js → chunk-LFHCXZO5.js} +6 -6
- package/dist/{chunk-LWKJQTOM.js → chunk-MICH6QSJ.js} +1 -1
- package/dist/chunk-N3DPO6HG.js +226 -0
- package/dist/{chunk-S4GZWSKR.js → chunk-OM5E3TTK.js} +1 -1
- package/dist/{chunk-3QRYCPXQ.js → chunk-OPKIKM35.js} +6 -6
- package/dist/{chunk-5EKIWVOR.js → chunk-PGRPNDWM.js} +2 -2
- package/dist/{chunk-LFJ6UJTI.js → chunk-PQNILU27.js} +9 -9
- package/dist/{chunk-QNCVHRZL.js → chunk-QVAFL2LE.js} +1 -1
- package/dist/{chunk-QEUY3A5P.js → chunk-QY7UU5ZB.js} +3 -2
- package/dist/{chunk-ITHXJHBB.js → chunk-R25RGPUB.js} +1 -0
- package/dist/{chunk-KLJCCMF3.js → chunk-R6735B37.js} +2 -2
- package/dist/{chunk-3ZP55QZE.js → chunk-R6FBDTP3.js} +4 -4
- package/dist/{chunk-7FZ53WDJ.js → chunk-RIAZM6L3.js} +1 -1
- package/dist/chunk-RJM4QCGG.js +550 -0
- package/dist/{chunk-NTRZGNEX.js → chunk-S3BCVWTU.js} +215 -46
- package/dist/chunk-S7KW47IQ.js +121 -0
- package/dist/{chunk-OFHBK7RI.js → chunk-SJQ546ID.js} +34 -14
- package/dist/{chunk-D35VTV2Z.js → chunk-SV7QAONL.js} +1 -1
- package/dist/{chunk-IAJLHVUA.js → chunk-TIWAHZZ6.js} +1 -1
- package/dist/{chunk-2PRH365R.js → chunk-UA7O3KKJ.js} +1 -1
- package/dist/{chunk-NPZY6YYL.js → chunk-UG5ZMAXW.js} +6 -6
- package/dist/{chunk-FEFTGVMF.js → chunk-V2N3BMOT.js} +7 -2
- package/dist/{chunk-NDCATSW7.js → chunk-V34H2YCY.js} +1 -1
- package/dist/chunk-WIATRXEJ.js +22 -0
- package/dist/{chunk-5C5YMZQU.js → chunk-WOFOMTGB.js} +16 -10
- package/dist/{chunk-QYOFACSP.js → chunk-WSOFKOLP.js} +3 -3
- package/dist/{chunk-MNAXYY3R.js → chunk-WUVZDFHS.js} +31 -11
- package/dist/{chunk-UG46QBLT.js → chunk-YIMOT5OO.js} +10 -10
- package/dist/{chunk-2ZQMA2WB.js → chunk-ZPSOF6VL.js} +2 -2
- package/dist/generated/index.d.ts +3 -0
- package/dist/generated/index.js +66 -62
- package/dist/index.js +66 -62
- package/dist/styles.css +2719 -799
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/tone.d.ts +7 -12
- package/package.json +4 -4
- package/scripts/check-css-literals.mjs +159 -23
- package/scripts/check-css-variables.mjs +5 -3
- package/scripts/css-source.mjs +97 -5
- package/dist/Avatar-P2KRQM2B.css +0 -156
- package/dist/Charts-D7G2BSXH.css +0 -277
- package/dist/CommandPalette-CSJDUCQA.css +0 -115
- package/dist/Kbd-W66MXQI5.css +0 -61
- package/dist/SearchTrigger-QXOYAUUY.css +0 -79
- package/dist/SidebarNav-QGSFKZYA.css +0 -319
- package/dist/StatCard-KYPKZUWX.css +0 -111
- package/dist/StatusDot-HA2L2FSX.css +0 -84
- package/dist/chunk-22O7LAW2.js +0 -41
- package/dist/chunk-2HQR4U4D.js +0 -143
- package/dist/chunk-ESCO4XYW.js +0 -144
- package/dist/chunk-F4PJZ4ED.js +0 -245
- package/dist/chunk-PNFASD6F.js +0 -98
- package/dist/chunk-PZSWF74H.js +0 -15
- /package/dist/{chunk-ZCR6YGQ4.js → chunk-PKIN4IMB.js} +0 -0
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { cx } from './cx.js';
|
|
2
2
|
export { useClipboard, writeClipboard } from './useClipboard.js';
|
|
3
3
|
export type { Clipboard, ClipboardOptions, ClipboardState } from './useClipboard.js';
|
|
4
|
-
export type {
|
|
4
|
+
export type { Tone } from './tone.js';
|
|
5
5
|
export { HeadingLevelProvider, headingTag, nextHeadingLevel, useHeadingLevel } from './headingLevel.js';
|
|
6
6
|
export type { HeadingLevel, HeadingLevelProviderProps } from './headingLevel.js';
|
package/dist/utils/tone.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The
|
|
2
|
+
* The one colour vocabulary a component is allowed to take as a prop.
|
|
3
3
|
*
|
|
4
4
|
* ONE SPELLING. The package shipped `warn` in Tag and Toaster and `warning` in
|
|
5
5
|
* StatCard and Callout, and `danger` beside `error`, so the same state had two
|
|
@@ -10,16 +10,11 @@
|
|
|
10
10
|
* info are states, `brand` is where the reader is, and everything else is
|
|
11
11
|
* neutral. Identity (a seat, a node, a vendor, a tool) takes neutral colour and
|
|
12
12
|
* is carried by its name, its glyph and its position.
|
|
13
|
-
*/
|
|
14
|
-
export type Tone = 'neutral' | 'info' | 'success' | 'warning' | 'danger' | 'brand';
|
|
15
|
-
/**
|
|
16
|
-
* The phase vocabulary, and nothing else.
|
|
17
13
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* could not be.
|
|
14
|
+
* So does a CATEGORY. A phase, a unit or a model is neutral with its word, and
|
|
15
|
+
* inside a figure it is a series its legend names, from the data ramp the
|
|
16
|
+
* application maps it onto. There used to be a second vocabulary here, three
|
|
17
|
+
* phase hues, and it spent three of the hues the states and the series are held
|
|
18
|
+
* apart in on a word the label already said.
|
|
24
19
|
*/
|
|
25
|
-
export type
|
|
20
|
+
export type Tone = 'neutral' | 'info' | 'success' | 'warning' | 'danger' | 'brand';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crewlethq/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Crewlet shared React components built on @crewlethq/tokens and @crewlethq/icons.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -37,13 +37,13 @@
|
|
|
37
37
|
"scripts": {
|
|
38
38
|
"build": "node scripts/write-barrel.mjs && tsup && tsc -p tsconfig.build.json && node scripts/bundle-css.mjs",
|
|
39
39
|
"dev": "node scripts/write-barrel.mjs && tsup --watch --onSuccess \"node scripts/bundle-css.mjs\"",
|
|
40
|
-
"lint": "node scripts/write-barrel.mjs && eslint src scripts && node scripts/check-css-variables.mjs && node scripts/check-css-literals.mjs src
|
|
40
|
+
"lint": "node scripts/write-barrel.mjs && eslint src scripts && node scripts/check-css-variables.mjs && node scripts/check-css-literals.mjs src",
|
|
41
41
|
"typecheck": "node scripts/write-barrel.mjs && tsc -p tsconfig.json --noEmit",
|
|
42
42
|
"clean": "rm -rf dist src/generated"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@crewlethq/icons": "0.
|
|
46
|
-
"@crewlethq/tokens": "0.
|
|
45
|
+
"@crewlethq/icons": "0.5.0",
|
|
46
|
+
"@crewlethq/tokens": "0.5.0"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"react": ">=18",
|
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// Refuses a value a component should have taken from a token, over the folders
|
|
3
|
-
// it is given.
|
|
3
|
+
// it is given. The package's own lint runs it over all of src/, so every
|
|
4
|
+
// component keeps these rules at every commit.
|
|
4
5
|
//
|
|
5
|
-
// WHY IT TAKES FOLDERS.
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
// so a component that has not been rewritten yet does not have to be
|
|
9
|
-
// allow-listed to keep the build green. The list of folders in the package's
|
|
10
|
-
// lint script is the record of which are done; when the last one lands, the
|
|
11
|
-
// list becomes `src` and this paragraph goes with it.
|
|
12
|
-
//
|
|
13
|
-
// It is also the published bin, `crewlet-css-check`, so a consumer can hold
|
|
14
|
-
// its own stylesheets to the same rules.
|
|
6
|
+
// WHY IT TAKES FOLDERS. It is also the published bin, `crewlet-css-check`, so
|
|
7
|
+
// a consumer can hold its own stylesheets to the same rules, and a consumer's
|
|
8
|
+
// stylesheets live wherever its build puts them.
|
|
15
9
|
//
|
|
16
10
|
// THE RULES.
|
|
17
11
|
//
|
|
@@ -25,9 +19,27 @@
|
|
|
25
19
|
// off the scale is a component that drifts from the one beside it.
|
|
26
20
|
// 3. No color-mix(). Mixing two tokens produces a third colour nobody
|
|
27
21
|
// measured, which is how a "warning text" step ended up at 4.41:1.
|
|
28
|
-
// 4.
|
|
29
|
-
//
|
|
30
|
-
//
|
|
22
|
+
// 4. EVERY MOTION IS PAIRED WITH ITS STOP. A rule that starts an animation or
|
|
23
|
+
// a transition is named again, selector for selector, by a later rule in
|
|
24
|
+
// the same file inside `@media (prefers-reduced-motion: reduce)` that sets
|
|
25
|
+
// it to `none` (or takes the element out with `display: none`), unless it
|
|
26
|
+
// only starts inside `@media (prefers-reduced-motion: no-preference)`.
|
|
27
|
+
// The document baseline collapses motion too, but a component is also
|
|
28
|
+
// used in an application that does not import the baseline.
|
|
29
|
+
// THE SAME SELECTOR, LATER, because that is the one arrangement the
|
|
30
|
+
// cascade guarantees: the two tie on specificity and the stop wins on
|
|
31
|
+
// source order. The rule was "the file mentions prefers-reduced-motion",
|
|
32
|
+
// and three components passed it while still moving for a reader who had
|
|
33
|
+
// asked them not to. DataTable stopped everything under a catch-all,
|
|
34
|
+
// `.crewlet-data-table.crewlet-data-table *`, which is two classes, and
|
|
35
|
+
// its row's transition was two classes and two elements. TreeCanvas
|
|
36
|
+
// stopped `.crewlet-tree-canvas__card--composing`, one class, where the
|
|
37
|
+
// ghost's arrival started on two. And TreeCanvas stopped its node
|
|
38
|
+
// controls ABOVE the rules that started them, so source order handed
|
|
39
|
+
// every tie back to the motion. A stop that looks broader is not one the
|
|
40
|
+
// check can verify, and all three of those looked right. LATER is where
|
|
41
|
+
// a browser places it: declarations written after a block nested in their
|
|
42
|
+
// rule come after that block, so a motion below a nested stop beats it.
|
|
31
43
|
// 5. A media query's length is one of the breakpoint tokens. A media query
|
|
32
44
|
// cannot read a custom property, so the number has to be written out; this
|
|
33
45
|
// is what says it is still the same number.
|
|
@@ -53,6 +65,17 @@ const LENGTH_IN_QUERY = /(\d*\.?\d+)px/g;
|
|
|
53
65
|
const COLOUR_PROPERTY =
|
|
54
66
|
/^(color|background|background-color|border(-(top|right|bottom|left))?-color|border|border-(top|right|bottom|left)|outline|outline-color|fill|stroke|box-shadow|text-shadow|caret-color|column-rule-color|text-decoration-color|accent-color|scrollbar-color|--crewlet-[\w-]*)$/;
|
|
55
67
|
|
|
68
|
+
/** The declarations that start a motion, and the one each belongs to. */
|
|
69
|
+
const MOTION = new Map([
|
|
70
|
+
['animation', 'animation'],
|
|
71
|
+
['animation-name', 'animation'],
|
|
72
|
+
['transition', 'transition'],
|
|
73
|
+
['transition-property', 'transition'],
|
|
74
|
+
]);
|
|
75
|
+
|
|
76
|
+
/** The one query a stop is read inside: exactly this, with nothing else around it. */
|
|
77
|
+
const REDUCE = /^@media\s*\(\s*prefers-reduced-motion\s*:\s*reduce\s*\)$/;
|
|
78
|
+
|
|
56
79
|
function declarations(body) {
|
|
57
80
|
const found = [];
|
|
58
81
|
for (const part of body.split(';')) {
|
|
@@ -75,6 +98,123 @@ function withoutTokens(value) {
|
|
|
75
98
|
return text;
|
|
76
99
|
}
|
|
77
100
|
|
|
101
|
+
/**
|
|
102
|
+
* One selector, spelled one way: whitespace collapsed, none round a combinator,
|
|
103
|
+
* and one kind of quote. Two spellings of one selector are one selector here,
|
|
104
|
+
* so a stop is never refused for its layout.
|
|
105
|
+
*/
|
|
106
|
+
function normalSelector(selector) {
|
|
107
|
+
return selector
|
|
108
|
+
.replace(/\s+/g, ' ')
|
|
109
|
+
.replace(/\s*([>+~])\s*/g, '$1')
|
|
110
|
+
.replace(/"/g, "'")
|
|
111
|
+
.trim();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** A selector list split at its own commas, not the ones inside `:not(…)` or `[…]`. */
|
|
115
|
+
function selectorList(list) {
|
|
116
|
+
const parts = [];
|
|
117
|
+
let depth = 0;
|
|
118
|
+
let from = 0;
|
|
119
|
+
for (let at = 0; at < list.length; at += 1) {
|
|
120
|
+
const char = list[at];
|
|
121
|
+
if (char === '(' || char === '[') depth += 1;
|
|
122
|
+
else if (char === ')' || char === ']') depth -= 1;
|
|
123
|
+
else if (char === ',' && depth === 0) {
|
|
124
|
+
parts.push(list.slice(from, at));
|
|
125
|
+
from = at + 1;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
parts.push(list.slice(from));
|
|
129
|
+
return parts;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* The selectors a block's own declarations apply to, with any nesting
|
|
134
|
+
* resolved, or null for a block that declares for no element: a top-level
|
|
135
|
+
* at-rule, or a keyframe.
|
|
136
|
+
*/
|
|
137
|
+
function appliesTo(block) {
|
|
138
|
+
let list = null;
|
|
139
|
+
for (const head of [...block.context, block.selector]) {
|
|
140
|
+
if (/^@keyframes\b/.test(head)) return null;
|
|
141
|
+
if (head.startsWith('@')) continue;
|
|
142
|
+
const parts = selectorList(head);
|
|
143
|
+
list =
|
|
144
|
+
list === null
|
|
145
|
+
? parts
|
|
146
|
+
: list.flatMap((parent) => parts.map((part) => (part.includes('&') ? part.replaceAll('&', parent) : `${parent} ${part}`)));
|
|
147
|
+
}
|
|
148
|
+
return list === null ? null : list.map(normalSelector);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** The conditional heads a block sits under, its own included when it is one. */
|
|
152
|
+
function conditions(block) {
|
|
153
|
+
return [...block.context, block.selector].filter((head) => head.startsWith('@')).map((head) => head.replace(/\s+/g, ' '));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Whether a block's declarations reach a browser only when the reader has NOT
|
|
158
|
+
* asked for less motion. Only a plain conjunction counts: under `not`, `or` or
|
|
159
|
+
* a comma list the same block also applies to a reader who has.
|
|
160
|
+
*/
|
|
161
|
+
function onlyWithMotion(heads) {
|
|
162
|
+
return heads.some(
|
|
163
|
+
(head) =>
|
|
164
|
+
/^@media\b/.test(head) && /\(\s*prefers-reduced-motion\s*:\s*no-preference\s*\)/.test(head) && !/,|\bor\b|\bnot\b/.test(head),
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Rule 4: every rule that starts a motion, answered selector for selector by a
|
|
170
|
+
* later stop in the same file. Returns the findings.
|
|
171
|
+
*/
|
|
172
|
+
function unpairedMotion(file) {
|
|
173
|
+
const starts = [];
|
|
174
|
+
const stops = [];
|
|
175
|
+
for (const block of rules(file.text)) {
|
|
176
|
+
const selectors = appliesTo(block);
|
|
177
|
+
if (selectors === null) continue;
|
|
178
|
+
const heads = conditions(block);
|
|
179
|
+
const reduced = heads.some((head) => /prefers-reduced-motion\s*:\s*reduce/.test(head));
|
|
180
|
+
const isStop = heads.length === 1 && REDUCE.test(heads[0] ?? '');
|
|
181
|
+
for (const { property, value } of declarations(block.body)) {
|
|
182
|
+
const important = /!\s*important\s*$/i.test(value);
|
|
183
|
+
const bare = value.replace(/!\s*important\s*$/i, '').trim().toLowerCase();
|
|
184
|
+
if (isStop && property === 'display' && bare === 'none') {
|
|
185
|
+
for (const family of ['animation', 'transition']) stops.push({ family, selectors, index: block.index, important });
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
const family = MOTION.get(property);
|
|
189
|
+
if (family === undefined) continue;
|
|
190
|
+
if (isStop && bare === 'none') stops.push({ family, selectors, index: block.index, important });
|
|
191
|
+
// Motion declared for a reader who asked for less is a deliberate
|
|
192
|
+
// alternative, such as a fade in place of a slide, and motion declared
|
|
193
|
+
// only for a reader who did not ask needs no stop.
|
|
194
|
+
if (reduced || onlyWithMotion(heads) || bare === 'none') continue;
|
|
195
|
+
starts.push({ family, property, selectors, index: block.index, important });
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const problems = [];
|
|
200
|
+
for (const start of starts) {
|
|
201
|
+
for (const selector of start.selectors) {
|
|
202
|
+
const stopped = stops.some(
|
|
203
|
+
(stop) =>
|
|
204
|
+
stop.family === start.family &&
|
|
205
|
+
stop.index > start.index &&
|
|
206
|
+
(stop.important || !start.important) &&
|
|
207
|
+
stop.selectors.includes(selector),
|
|
208
|
+
);
|
|
209
|
+
if (stopped) continue;
|
|
210
|
+
problems.push(
|
|
211
|
+
`${file.where}:${lineOf(file.text, start.index)}: ${start.property} on ${selector} has no reduced-motion stop. Name the same selector in a later rule of this file inside @media (prefers-reduced-motion: reduce) and set ${start.family}: none, or start it inside @media (prefers-reduced-motion: no-preference): a stop naming another selector can lose on specificity, and one above the rule it stops loses on source order`,
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return problems;
|
|
216
|
+
}
|
|
217
|
+
|
|
78
218
|
/**
|
|
79
219
|
* The breakpoint steps, from the tokens package's own typed export.
|
|
80
220
|
*
|
|
@@ -94,13 +234,13 @@ export async function findings(roots, base = packageRoot) {
|
|
|
94
234
|
|
|
95
235
|
for (const file of files) {
|
|
96
236
|
const at = (index) => `${file.where}:${lineOf(file.text, index)}`;
|
|
97
|
-
const hasReducedMotion = file.text.includes('prefers-reduced-motion');
|
|
98
237
|
|
|
99
|
-
for (const { selector, body, index } of rules(file.text)) {
|
|
238
|
+
for (const { selector, body, index, nestedDeclarations } of rules(file.text)) {
|
|
100
239
|
const where = at(index);
|
|
101
|
-
const inQuery = /@media/.test(selector);
|
|
102
240
|
|
|
103
|
-
|
|
241
|
+
// Declarations resumed after a nested block carry their block's head
|
|
242
|
+
// again, and the head was read with the block.
|
|
243
|
+
if (/^@media\b/.test(selector) && !nestedDeclarations) {
|
|
104
244
|
for (const match of selector.matchAll(LENGTH_IN_QUERY)) {
|
|
105
245
|
if (!allowed.has(Number(match[1]))) {
|
|
106
246
|
problems.push(
|
|
@@ -142,11 +282,7 @@ export async function findings(roots, base = packageRoot) {
|
|
|
142
282
|
}
|
|
143
283
|
}
|
|
144
284
|
|
|
145
|
-
|
|
146
|
-
problems.push(
|
|
147
|
-
`${file.where}: animates or transitions with no prefers-reduced-motion rule in the file. The document baseline is opt-in, so a component states its own`,
|
|
148
|
-
);
|
|
149
|
-
}
|
|
285
|
+
problems.push(...unpairedMotion(file));
|
|
150
286
|
}
|
|
151
287
|
|
|
152
288
|
return { problems, checked: `${files.length} stylesheets in ${roots.length} folder(s)` };
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// The rules EVERY component in the package keeps, checked over all of src/.
|
|
3
3
|
//
|
|
4
|
-
// Its sibling, check-css-literals.mjs, holds the rules
|
|
5
|
-
//
|
|
6
|
-
//
|
|
4
|
+
// Its sibling, check-css-literals.mjs, holds the rules about VALUES: which
|
|
5
|
+
// colour, size, radius, duration and depth a component may spell out, and how
|
|
6
|
+
// every motion is stopped. These are the rules about which names a stylesheet
|
|
7
|
+
// reads, what it loads and how it draws text and focus, and each of them fails
|
|
8
|
+
// silently in production:
|
|
7
9
|
//
|
|
8
10
|
// 1. A name in a token namespace (--color-*, --font-*, --spacing-* and the
|
|
9
11
|
// rest of TOKEN_PREFIXES) must be one the @crewlethq/tokens build emits,
|
package/scripts/css-source.mjs
CHANGED
|
@@ -46,14 +46,106 @@ export function readSources(roots, base, extensions) {
|
|
|
46
46
|
return files;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* Every block in a stylesheet, in source order, whatever it is nested in.
|
|
51
|
+
*
|
|
52
|
+
* Each is `{ selector, body, index, context, nestedDeclarations }`: the text
|
|
53
|
+
* before its brace (a selector list, or an at-rule's prelude such as
|
|
54
|
+
* `@media (width < 1024px)`), the declarations it makes ITSELF before the
|
|
55
|
+
* first block nested in it, where that text starts, and the heads of the
|
|
56
|
+
* blocks it sits inside, outermost first. A keyframe's `from` or `50%` is a
|
|
57
|
+
* block too, with its `@keyframes` in its context.
|
|
58
|
+
*
|
|
59
|
+
* NESTING-AWARE, because the regex this replaced, `([^{}]+)\{([^{}]*)\}`, saw
|
|
60
|
+
* only the innermost blocks. It never saw an at-rule's prelude, so the literal
|
|
61
|
+
* check's breakpoint rule read not one top-level `@media` query in the package;
|
|
62
|
+
* it could not say which query a rule sat inside, which is the whole of
|
|
63
|
+
* pairing a motion with the reduced-motion rule that stops it; and it never
|
|
64
|
+
* saw the declarations of a rule with a rule nested in it. Its offsets also
|
|
65
|
+
* started after the previous block's brace, so a finding named the line that
|
|
66
|
+
* block closed on rather than the line of the selector.
|
|
67
|
+
*
|
|
68
|
+
* DECLARATIONS AFTER A NESTED BLOCK ARE AN ENTRY OF THEIR OWN, at their own
|
|
69
|
+
* offset, with the block's selector and context and `nestedDeclarations: true`,
|
|
70
|
+
* because that is where a browser puts them: in a nested-declarations rule
|
|
71
|
+
* that matches what its parent matches, at the parent's specificity, AFTER the
|
|
72
|
+
* nested block in source order. Folded into the parent at the parent's offset,
|
|
73
|
+
* an `animation` written below a nested reduced-motion stop read as written
|
|
74
|
+
* above it, and the pairing check passed a motion that beats its own stop. The
|
|
75
|
+
* flag lets a check that reads the HEAD rather than the declarations, such as
|
|
76
|
+
* the breakpoint rule, read each head once.
|
|
77
|
+
*/
|
|
50
78
|
export function rules(text) {
|
|
51
79
|
const found = [];
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
80
|
+
const open = [];
|
|
81
|
+
// Where the statement being read began: a declaration, or the head of the
|
|
82
|
+
// next block, which is everything since the last `;`, `{` or `}`.
|
|
83
|
+
let statement = 0;
|
|
84
|
+
let quote = null;
|
|
85
|
+
/**
|
|
86
|
+
* A block's own declarations from where they resume to `end`: its body while
|
|
87
|
+
* nothing is nested in it yet, and an entry of their own once something is,
|
|
88
|
+
* since a browser places them after that nested block.
|
|
89
|
+
*/
|
|
90
|
+
const declarationsUntil = (frame, end) => {
|
|
91
|
+
const declared = text.slice(frame.from, end);
|
|
92
|
+
if (!frame.nested) {
|
|
93
|
+
frame.body += declared;
|
|
94
|
+
} else if (declared.trim() !== '') {
|
|
95
|
+
found.push({
|
|
96
|
+
selector: frame.selector,
|
|
97
|
+
body: declared,
|
|
98
|
+
index: frame.from + declared.length - declared.trimStart().length,
|
|
99
|
+
context: frame.context,
|
|
100
|
+
nestedDeclarations: true,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
for (let at = 0; at < text.length; at += 1) {
|
|
105
|
+
const char = text[at];
|
|
106
|
+
if (quote !== null) {
|
|
107
|
+
if (char === '\\') at += 1;
|
|
108
|
+
else if (char === quote) quote = null;
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (char === '"' || char === "'") {
|
|
112
|
+
quote = char;
|
|
113
|
+
} else if (char === ';') {
|
|
114
|
+
statement = at + 1;
|
|
115
|
+
} else if (char === '{') {
|
|
116
|
+
const parent = open.at(-1);
|
|
117
|
+
if (parent) {
|
|
118
|
+
declarationsUntil(parent, statement);
|
|
119
|
+
parent.nested = true;
|
|
120
|
+
}
|
|
121
|
+
const head = text.slice(statement, at);
|
|
122
|
+
open.push({
|
|
123
|
+
selector: head.trim(),
|
|
124
|
+
index: statement + head.length - head.trimStart().length,
|
|
125
|
+
context: open.map((each) => each.selector),
|
|
126
|
+
from: at + 1,
|
|
127
|
+
body: '',
|
|
128
|
+
nested: false,
|
|
129
|
+
});
|
|
130
|
+
statement = at + 1;
|
|
131
|
+
} else if (char === '}') {
|
|
132
|
+
const frame = open.pop();
|
|
133
|
+
if (frame) {
|
|
134
|
+
declarationsUntil(frame, at);
|
|
135
|
+
found.push({
|
|
136
|
+
selector: frame.selector,
|
|
137
|
+
body: frame.body,
|
|
138
|
+
index: frame.index,
|
|
139
|
+
context: frame.context,
|
|
140
|
+
nestedDeclarations: false,
|
|
141
|
+
});
|
|
142
|
+
const parent = open.at(-1);
|
|
143
|
+
if (parent) parent.from = at + 1;
|
|
144
|
+
}
|
|
145
|
+
statement = at + 1;
|
|
146
|
+
}
|
|
55
147
|
}
|
|
56
|
-
return found;
|
|
148
|
+
return found.sort((a, b) => a.index - b.index);
|
|
57
149
|
}
|
|
58
150
|
|
|
59
151
|
export function report(name, problems, checked) {
|
package/dist/Avatar-P2KRQM2B.css
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* The identity badge.
|
|
3
|
-
*
|
|
4
|
-
* IT IS NEUTRAL, and that is the whole rule. The system this replaces coloured
|
|
5
|
-
* a seat by `PALETTE[hash(name) % 8]`, over the same eight families it also
|
|
6
|
-
* spent on phases and event categories, so one amber meant "the execute
|
|
7
|
-
* phase", "the decision category" and "the Analyst" at once. A hash of a name
|
|
8
|
-
* carries no information: rename the seat and its colour changes, which is the
|
|
9
|
-
* proof it never meant anything. Identity is the monogram and the name.
|
|
10
|
-
*
|
|
11
|
-
* The seeded tints stay for the one case that earns them, a roster somebody
|
|
12
|
-
* scans, and their grounds are TOKENS: measured under white initials and held
|
|
13
|
-
* at 4.5:1 by the palette suite. Spelled as literals, five of the ten sat
|
|
14
|
-
* under that floor while the suite measured ten values nothing painted with.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
.crewlet-avatar {
|
|
18
|
-
--crewlet-avatar-size: 32px;
|
|
19
|
-
display: inline-flex;
|
|
20
|
-
align-items: center;
|
|
21
|
-
justify-content: center;
|
|
22
|
-
flex: none;
|
|
23
|
-
width: var(--crewlet-avatar-size);
|
|
24
|
-
height: var(--crewlet-avatar-size);
|
|
25
|
-
overflow: hidden;
|
|
26
|
-
object-fit: cover;
|
|
27
|
-
font-family: var(--font-family-sans);
|
|
28
|
-
font-size: var(--font-size-xs);
|
|
29
|
-
font-weight: var(--font-weight-semibold);
|
|
30
|
-
letter-spacing: var(--font-letter-spacing-wide);
|
|
31
|
-
/* The document's own leading rather than a tight step of the badge's own.
|
|
32
|
-
The box is a fixed square that centres whatever line it holds, so the ink
|
|
33
|
-
lands in the same place either way; what the tight step bought was one
|
|
34
|
-
more number in a component that already sets four. */
|
|
35
|
-
line-height: var(--font-line-height-normal);
|
|
36
|
-
text-transform: uppercase;
|
|
37
|
-
user-select: none;
|
|
38
|
-
box-sizing: border-box;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/*
|
|
42
|
-
* The four steps. Each pairs its box with a type step, so two initials sit
|
|
43
|
-
* inside the circle at every one of them; a numeric size computes its own,
|
|
44
|
-
* because nothing in the scale can answer for an arbitrary box.
|
|
45
|
-
*/
|
|
46
|
-
.crewlet-avatar--xs {
|
|
47
|
-
--crewlet-avatar-size: 20px;
|
|
48
|
-
font-size: var(--font-size-2xs);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
.crewlet-avatar--sm {
|
|
52
|
-
--crewlet-avatar-size: 26px;
|
|
53
|
-
font-size: var(--font-size-2xs);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
.crewlet-avatar--md {
|
|
57
|
-
--crewlet-avatar-size: 32px;
|
|
58
|
-
font-size: var(--font-size-xs);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
.crewlet-avatar--lg {
|
|
62
|
-
--crewlet-avatar-size: 40px;
|
|
63
|
-
font-size: var(--font-size-sm);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/*
|
|
67
|
-
* Shapes. THE SQUARE IS THE DEFAULT, which is the change: the engine's
|
|
68
|
-
* identity mark is a rounded square and it is what a reader sees in every seat
|
|
69
|
-
* chip, every list row and every header on that product. A circle stays for a
|
|
70
|
-
* PERSON, where the round badge is the platform convention a member list
|
|
71
|
-
* already speaks.
|
|
72
|
-
*
|
|
73
|
-
* The square's radius moves with the box rather than sitting at one step. The
|
|
74
|
-
* engine draws 4px at 20, 8px at 26 and 12px at 40, which is a roughly
|
|
75
|
-
* constant proportion; one radius across the four steps reads as a pill at the
|
|
76
|
-
* smallest and as a plain box at the largest. A NUMERIC SIZE OBEYS THE SAME
|
|
77
|
-
* LADDER, from `avatarSquareCorner` in the component, which picks the corner
|
|
78
|
-
* of the step nearest the box it was given: taking one fixed step there is how
|
|
79
|
-
* `size={80}` ended up drawn squarer than `size="lg"` at half its width.
|
|
80
|
-
*/
|
|
81
|
-
.crewlet-avatar--circle {
|
|
82
|
-
border-radius: var(--radius-circle);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
.crewlet-avatar--square {
|
|
86
|
-
border-radius: var(--radius-md);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
.crewlet-avatar--square.crewlet-avatar--xs {
|
|
90
|
-
border-radius: var(--radius-xs);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
.crewlet-avatar--square.crewlet-avatar--lg {
|
|
94
|
-
border-radius: var(--radius-lg);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
.crewlet-avatar--image {
|
|
98
|
-
display: block;
|
|
99
|
-
object-fit: cover;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/* ── tones ─────────────────────────────────────────────────────────────── */
|
|
103
|
-
|
|
104
|
-
.crewlet-avatar--fallback {
|
|
105
|
-
border: 1px solid transparent;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
.crewlet-avatar--neutral {
|
|
109
|
-
background: var(--color-surface-elevated);
|
|
110
|
-
border-color: var(--color-border-default);
|
|
111
|
-
color: var(--color-text-secondary);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/*
|
|
115
|
-
* The label on the accent fill is the on-accent step, not the on-brand one.
|
|
116
|
-
* The themes repaint the brand fill monochrome and leave the accent where it
|
|
117
|
-
* is, so on-brand is black in the dark palette and black on the accent
|
|
118
|
-
* measures 4.35:1. On-accent is white in every palette and measures 4.83:1.
|
|
119
|
-
*/
|
|
120
|
-
.crewlet-avatar--brand {
|
|
121
|
-
background: var(--color-brand-accent);
|
|
122
|
-
color: var(--color-text-on-accent);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
.crewlet-avatar--seeded {
|
|
126
|
-
color: var(--color-text-on-accent);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
.crewlet-avatar--tint-0 { background: var(--color-avatar-tint-0); }
|
|
130
|
-
.crewlet-avatar--tint-1 { background: var(--color-avatar-tint-1); }
|
|
131
|
-
.crewlet-avatar--tint-2 { background: var(--color-avatar-tint-2); }
|
|
132
|
-
.crewlet-avatar--tint-3 { background: var(--color-avatar-tint-3); }
|
|
133
|
-
.crewlet-avatar--tint-4 { background: var(--color-avatar-tint-4); }
|
|
134
|
-
.crewlet-avatar--tint-5 { background: var(--color-avatar-tint-5); }
|
|
135
|
-
.crewlet-avatar--tint-6 { background: var(--color-avatar-tint-6); }
|
|
136
|
-
.crewlet-avatar--tint-7 { background: var(--color-avatar-tint-7); }
|
|
137
|
-
.crewlet-avatar--tint-8 { background: var(--color-avatar-tint-8); }
|
|
138
|
-
.crewlet-avatar--tint-9 { background: var(--color-avatar-tint-9); }
|
|
139
|
-
|
|
140
|
-
/*
|
|
141
|
-
* A HUMAN SEAT IS DRAWN, NOT TINTED. The engine does not run it, which is a
|
|
142
|
-
* structural fact rather than a status, so it takes the edge and no fill at
|
|
143
|
-
* all. Last, so it wins over whichever tone it is paired with.
|
|
144
|
-
*
|
|
145
|
-
* The whole border rather than its style alone: the badge is the same person
|
|
146
|
-
* whether or not they have uploaded a photo, and an image draws no border of
|
|
147
|
-
* its own for a style to change.
|
|
148
|
-
*/
|
|
149
|
-
.crewlet-avatar--dashed {
|
|
150
|
-
background: transparent;
|
|
151
|
-
/* The same hairline the solid neutral badge draws, so the human seat differs
|
|
152
|
-
by its LINE STYLE and its missing fill rather than by a second grey a
|
|
153
|
-
reader would have to hold two of in mind. */
|
|
154
|
-
border: 1px dashed var(--color-border-default);
|
|
155
|
-
color: var(--color-text-secondary);
|
|
156
|
-
}
|