vuetiwatch 0.1.0 → 0.2.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 +200 -17
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/plugin.d.ts +77 -7
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +104 -15
- package/dist/plugin.js.map +1 -1
- package/dist/registry.d.ts +1 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +6 -1
- package/dist/registry.js.map +1 -1
- package/dist/styles/atlas.css +99 -0
- package/dist/styles/atlas.min.css +1 -0
- package/dist/styles/atlasDark.css +99 -0
- package/dist/styles/atlasDark.min.css +1 -0
- package/dist/styles/atlasSepia.css +99 -0
- package/dist/styles/atlasSepia.min.css +1 -0
- package/dist/styles/aurora.css +97 -4
- package/dist/styles/aurora.min.css +1 -1
- package/dist/styles/brutalist.css +5 -0
- package/dist/styles/brutalist.min.css +1 -1
- package/dist/styles/calm.css +0 -4
- package/dist/styles/calm.min.css +1 -1
- package/dist/styles/candy.css +71 -0
- package/dist/styles/candy.min.css +1 -0
- package/dist/styles/clay.css +13 -0
- package/dist/styles/clay.min.css +1 -1
- package/dist/styles/core.css +239 -36
- package/dist/styles/core.min.css +1 -1
- package/dist/styles/graphite.css +29 -0
- package/dist/styles/graphite.min.css +1 -0
- package/dist/styles/morph.css +12 -0
- package/dist/styles/morph.min.css +1 -1
- package/dist/styles/neon.css +8 -0
- package/dist/styles/neon.min.css +1 -1
- package/dist/styles/sketchy.css +4 -0
- package/dist/styles/sketchy.min.css +1 -1
- package/dist/styles/soft.css +1 -12
- package/dist/styles/soft.min.css +1 -1
- package/dist/styles.css +577 -52
- package/dist/styles.min.css +1 -1
- package/dist/themes/atlas.d.ts +38 -0
- package/dist/themes/atlas.d.ts.map +1 -0
- package/dist/themes/atlas.js +203 -0
- package/dist/themes/atlas.js.map +1 -0
- package/dist/themes/atlasDark.d.ts +8 -0
- package/dist/themes/atlasDark.d.ts.map +1 -0
- package/dist/themes/atlasDark.js +64 -0
- package/dist/themes/atlasDark.js.map +1 -0
- package/dist/themes/atlasSepia.d.ts +11 -0
- package/dist/themes/atlasSepia.d.ts.map +1 -0
- package/dist/themes/atlasSepia.js +60 -0
- package/dist/themes/atlasSepia.js.map +1 -0
- package/dist/themes/aurora.d.ts.map +1 -1
- package/dist/themes/aurora.js +27 -2
- package/dist/themes/aurora.js.map +1 -1
- package/dist/themes/brutalist.d.ts.map +1 -1
- package/dist/themes/brutalist.js +26 -0
- package/dist/themes/brutalist.js.map +1 -1
- package/dist/themes/calm.d.ts.map +1 -1
- package/dist/themes/calm.js +22 -2
- package/dist/themes/calm.js.map +1 -1
- package/dist/themes/candy.d.ts +20 -0
- package/dist/themes/candy.d.ts.map +1 -0
- package/dist/themes/candy.js +142 -0
- package/dist/themes/candy.js.map +1 -0
- package/dist/themes/classic.d.ts.map +1 -1
- package/dist/themes/classic.js +2 -0
- package/dist/themes/classic.js.map +1 -1
- package/dist/themes/clay.d.ts.map +1 -1
- package/dist/themes/clay.js +22 -0
- package/dist/themes/clay.js.map +1 -1
- package/dist/themes/darkGlass.d.ts.map +1 -1
- package/dist/themes/darkGlass.js +21 -0
- package/dist/themes/darkGlass.js.map +1 -1
- package/dist/themes/graphite.d.ts +13 -0
- package/dist/themes/graphite.d.ts.map +1 -0
- package/dist/themes/graphite.js +147 -0
- package/dist/themes/graphite.js.map +1 -0
- package/dist/themes/index.d.ts +5 -0
- package/dist/themes/index.d.ts.map +1 -1
- package/dist/themes/index.js +5 -0
- package/dist/themes/index.js.map +1 -1
- package/dist/themes/liquidGlass.d.ts.map +1 -1
- package/dist/themes/liquidGlass.js +27 -3
- package/dist/themes/liquidGlass.js.map +1 -1
- package/dist/themes/lux.d.ts.map +1 -1
- package/dist/themes/lux.js +21 -2
- package/dist/themes/lux.js.map +1 -1
- package/dist/themes/morph.d.ts.map +1 -1
- package/dist/themes/morph.js +23 -3
- package/dist/themes/morph.js.map +1 -1
- package/dist/themes/neon.d.ts.map +1 -1
- package/dist/themes/neon.js +22 -0
- package/dist/themes/neon.js.map +1 -1
- package/dist/themes/paper.d.ts.map +1 -1
- package/dist/themes/paper.js +16 -0
- package/dist/themes/paper.js.map +1 -1
- package/dist/themes/sketchy.d.ts.map +1 -1
- package/dist/themes/sketchy.js +17 -0
- package/dist/themes/sketchy.js.map +1 -1
- package/dist/themes/slate.d.ts.map +1 -1
- package/dist/themes/slate.js +22 -1
- package/dist/themes/slate.js.map +1 -1
- package/dist/themes/soft.d.ts.map +1 -1
- package/dist/themes/soft.js +21 -2
- package/dist/themes/soft.js.map +1 -1
- package/dist/types.d.ts +40 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/util/defaults.d.ts.map +1 -1
- package/dist/util/defaults.js +11 -1
- package/dist/util/defaults.js.map +1 -1
- package/dist/util/defineTheme.d.ts.map +1 -1
- package/dist/util/defineTheme.js +11 -5
- package/dist/util/defineTheme.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +8 -2
- package/src/plugin.ts +214 -21
- package/src/registry.ts +10 -0
- package/src/styles/core.css +563 -35
- package/src/styles/index.css +4 -0
- package/src/styles/themes/_atlas.css +194 -0
- package/src/styles/themes/atlas.css +2 -0
- package/src/styles/themes/atlasDark.css +2 -0
- package/src/styles/themes/atlasSepia.css +2 -0
- package/src/styles/themes/aurora.css +151 -7
- package/src/styles/themes/brutalist.css +5 -3
- package/src/styles/themes/calm.css +0 -7
- package/src/styles/themes/candy.css +113 -0
- package/src/styles/themes/clay.css +24 -0
- package/src/styles/themes/graphite.css +63 -0
- package/src/styles/themes/liquidGlass.css +0 -2
- package/src/styles/themes/lux.css +0 -4
- package/src/styles/themes/morph.css +22 -0
- package/src/styles/themes/neon.css +8 -3
- package/src/styles/themes/paper.css +0 -2
- package/src/styles/themes/sketchy.css +9 -0
- package/src/styles/themes/slate.css +0 -4
- package/src/styles/themes/soft.css +1 -12
- package/src/themes/atlas.ts +211 -0
- package/src/themes/atlasDark.ts +64 -0
- package/src/themes/atlasSepia.ts +60 -0
- package/src/themes/aurora.ts +30 -2
- package/src/themes/brutalist.ts +29 -0
- package/src/themes/calm.ts +25 -2
- package/src/themes/candy.ts +144 -0
- package/src/themes/classic.ts +3 -0
- package/src/themes/clay.ts +24 -0
- package/src/themes/darkGlass.ts +24 -0
- package/src/themes/graphite.ts +150 -0
- package/src/themes/index.ts +5 -0
- package/src/themes/liquidGlass.ts +30 -3
- package/src/themes/lux.ts +24 -2
- package/src/themes/morph.ts +25 -3
- package/src/themes/neon.ts +25 -0
- package/src/themes/paper.ts +19 -0
- package/src/themes/sketchy.ts +20 -0
- package/src/themes/slate.ts +25 -1
- package/src/themes/soft.ts +24 -2
- package/src/types.ts +41 -0
- package/src/util/defaults.ts +12 -1
- package/src/util/defineTheme.ts +11 -5
package/src/styles/index.css
CHANGED
|
@@ -13,9 +13,13 @@
|
|
|
13
13
|
/* Everyday */
|
|
14
14
|
@import './themes/paper.css';
|
|
15
15
|
@import './themes/slate.css';
|
|
16
|
+
@import './themes/graphite.css';
|
|
17
|
+
/* One stylesheet for the three Atlas variants. */
|
|
18
|
+
@import './themes/_atlas.css';
|
|
16
19
|
@import './themes/calm.css';
|
|
17
20
|
@import './themes/lux.css';
|
|
18
21
|
@import './themes/soft.css';
|
|
22
|
+
@import './themes/candy.css';
|
|
19
23
|
|
|
20
24
|
/* Tactile */
|
|
21
25
|
@import './themes/clay.css';
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Atlas — shared by the three variants, because they are one design with
|
|
3
|
+
* three grounds rather than three themes that resemble each other.
|
|
4
|
+
*
|
|
5
|
+
* The theme says most of what it has to say through variables; what is left
|
|
6
|
+
* are the two structures a panel needs and a `ThemeDefinition` cannot
|
|
7
|
+
* express: a header that separates from its rows, and a card whose title
|
|
8
|
+
* separates from its content. Both are hairlines. Nothing here casts a
|
|
9
|
+
* shadow — on a screen this quiet a shadow is the loudest thing on it.
|
|
10
|
+
*/
|
|
11
|
+
.v-theme--atlas,
|
|
12
|
+
.v-theme--atlasDark,
|
|
13
|
+
.v-theme--atlasSepia {
|
|
14
|
+
/**
|
|
15
|
+
* The frame reads as a frame: the navigation takes the muted band, the
|
|
16
|
+
* content keeps the white. It is the oldest console layout there is, and
|
|
17
|
+
* the reason a panel on a white page still looks like an application.
|
|
18
|
+
*/
|
|
19
|
+
& .v-navigation-drawer {
|
|
20
|
+
background-color: rgb(var(--v-theme-surface-light));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* A table header that keeps its own ground, so a sticky one does not have
|
|
25
|
+
* rows sliding through it, and a rule under it that reads as structure
|
|
26
|
+
* rather than as a border round the table.
|
|
27
|
+
*/
|
|
28
|
+
& :is(.v-table thead th, .v-data-table__th) {
|
|
29
|
+
/* A shade off the rows rather than the same white: the header of a
|
|
30
|
+
console table is a band, and a band you cannot see is a caption. */
|
|
31
|
+
background-color: rgb(var(--v-theme-surface-light));
|
|
32
|
+
border-bottom: 1px solid rgba(var(--v-border-color), calc(var(--v-border-opacity) * 1.6));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* The title block of a panel, ruled off from what it introduces. */
|
|
36
|
+
& .v-card--variant-outlined > .v-card-item:not(:last-child) {
|
|
37
|
+
border-block-end: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
|
38
|
+
padding-block-end: 12px;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Vuetify zeroes the top padding of a `v-card-text` that follows a
|
|
43
|
+
* `v-card-item`, which is right when nothing separates them and wrong the
|
|
44
|
+
* moment the rule above is drawn: the content ends up sitting on the line.
|
|
45
|
+
*/
|
|
46
|
+
& .v-card--variant-outlined > .v-card-item + :is(.v-card-text, .v-card-actions) {
|
|
47
|
+
padding-top: 12px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Data runs a size smaller than prose.
|
|
52
|
+
*
|
|
53
|
+
* Vuetify sets one body size for the whole application, which is right
|
|
54
|
+
* for a page someone reads and wrong for a grid someone scans: at 16px a
|
|
55
|
+
* table of twelve columns stops fitting, and every admin tool worth
|
|
56
|
+
* copying runs its rows at 13 or 14. The reduction is scoped to the
|
|
57
|
+
* places that hold records — tables and lists — so forms and prose keep
|
|
58
|
+
* the size they were designed at.
|
|
59
|
+
*/
|
|
60
|
+
& :is(.v-table, .v-data-table) {
|
|
61
|
+
font-size: 0.875rem;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
& :is(.v-list-item-title, .v-list-item-subtitle) {
|
|
65
|
+
font-size: 0.875rem;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* A panel title is a label for what is under it, not a headline. Vuetify's
|
|
70
|
+
* 1.25rem belongs on a marketing card; a screen with nine panels on it
|
|
71
|
+
* needs them to sit down.
|
|
72
|
+
*/
|
|
73
|
+
& .v-card-title {
|
|
74
|
+
font-size: 1rem;
|
|
75
|
+
font-weight: 600;
|
|
76
|
+
letter-spacing: 0;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* The pickers, at a size that fits a form.
|
|
81
|
+
*
|
|
82
|
+
* Vuetify sizes them for a touch dialog: 328px wide with 44px day cells,
|
|
83
|
+
* which next to a compact field looks like a component from another
|
|
84
|
+
* application. 36px cells still clear the 24px minimum for a pointer
|
|
85
|
+
* target and take a third off the height.
|
|
86
|
+
*/
|
|
87
|
+
& :is(.v-date-picker, .v-picker) {
|
|
88
|
+
/* 306, not 296: the month and year controls need that much, and a
|
|
89
|
+
picker narrower than its own header is a picker that wraps. */
|
|
90
|
+
width: 306px;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/* The time picker sets its own floor, and it is the same 328. */
|
|
94
|
+
& .v-time-picker {
|
|
95
|
+
min-width: 296px;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
& .v-date-picker-month__day {
|
|
99
|
+
height: 32px;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* The date grid is a table of numbers, so it takes the table's size. */
|
|
103
|
+
& :is(.v-date-picker-month, .v-date-picker-years, .v-date-picker-months) {
|
|
104
|
+
font-size: 0.8125rem;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* The clock face is sized for a thumb on a phone: 256px next to a
|
|
108
|
+
compact field is a component from another application. */
|
|
109
|
+
& .v-time-picker-clock {
|
|
110
|
+
max-width: 208px;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
& .v-date-picker-controls {
|
|
114
|
+
padding-block: 4px;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Two nested paddings around five boxes on a control that is one line —
|
|
119
|
+
* and boxes sized for a thumb on a phone. A code entered with a keyboard
|
|
120
|
+
* beside compact fields should match them.
|
|
121
|
+
*/
|
|
122
|
+
& .v-otp-input {
|
|
123
|
+
padding-block: 0;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
& .v-otp-input__content {
|
|
127
|
+
max-width: 240px;
|
|
128
|
+
padding: 0;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
& .v-otp-input .v-field {
|
|
132
|
+
height: 40px;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* A panel header is a row, and rows here are 40 to 44. Vuetify's 48
|
|
137
|
+
* growing to 64 on open makes the list jump as much as it discloses.
|
|
138
|
+
*/
|
|
139
|
+
& .v-expansion-panel-title {
|
|
140
|
+
min-height: 44px;
|
|
141
|
+
/* The height comes from the padding, not the minimum: 16px above and
|
|
142
|
+
below a 24px line is 56 whatever the minimum says. */
|
|
143
|
+
padding-block: 10px;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
& .v-expansion-panel-title--active {
|
|
147
|
+
min-height: 52px;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Vuetify's empty state fills its container, which is right for a
|
|
152
|
+
* full-page one and wrong for the panel-sized ones an admin screen is
|
|
153
|
+
* full of.
|
|
154
|
+
*/
|
|
155
|
+
& .v-empty-state {
|
|
156
|
+
min-height: 0;
|
|
157
|
+
padding-block: 24px;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Vuetify sets an alert title at 24px with a 28px glyph beside it, which
|
|
162
|
+
* on a console page is a headline announcing a footnote. Ant Design runs
|
|
163
|
+
* its alerts at 16 and 14, and that is the register a notice belongs in
|
|
164
|
+
* when the screen behind it is full of data.
|
|
165
|
+
*/
|
|
166
|
+
& .v-alert-title {
|
|
167
|
+
font-size: 1rem;
|
|
168
|
+
line-height: 1.5;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
& .v-alert .v-alert__content {
|
|
172
|
+
font-size: 0.875rem;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
& .v-alert .v-alert__prepend .v-icon {
|
|
176
|
+
font-size: 20px;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* A breadcrumb trail is orientation, not content: it sits above the page
|
|
181
|
+
* title saying where you are, and Vuetify runs it at body size, which
|
|
182
|
+
* puts it in the same voice as the text it introduces. Every console this
|
|
183
|
+
* theme is measured against sets it a step down.
|
|
184
|
+
*/
|
|
185
|
+
& .v-breadcrumbs {
|
|
186
|
+
font-size: 0.875rem;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/* Dense screens read better when the rules between rows are lighter than
|
|
190
|
+
the ones around the panels that hold them. */
|
|
191
|
+
& :is(.v-table tbody td, .v-data-table__td) {
|
|
192
|
+
border-color: rgba(var(--v-border-color), calc(var(--v-border-opacity) * 0.7));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
@@ -12,14 +12,38 @@
|
|
|
12
12
|
* restyles the entire theme.
|
|
13
13
|
*/
|
|
14
14
|
.v-theme--aurora {
|
|
15
|
-
/* The lit ground the glows sit on
|
|
15
|
+
/* The lit ground the glows sit on, now closed at the bottom by the third
|
|
16
|
+
colour of the gradient so the page is lit from every corner. */
|
|
16
17
|
&.v-application {
|
|
17
18
|
background-image:
|
|
18
19
|
radial-gradient(60rem 40rem at 15% -10%, rgba(124, 92, 255, 0.16), transparent 60%),
|
|
19
|
-
radial-gradient(50rem 35rem at 95% 5%, rgba(0, 212, 255, 0.12), transparent 60%)
|
|
20
|
+
radial-gradient(50rem 35rem at 95% 5%, rgba(0, 212, 255, 0.12), transparent 60%),
|
|
21
|
+
radial-gradient(45rem 30rem at 50% 105%, rgba(255, 92, 170, 0.1), transparent 60%);
|
|
20
22
|
background-attachment: fixed;
|
|
21
23
|
}
|
|
22
24
|
|
|
25
|
+
/**
|
|
26
|
+
* The aurora itself: a second field of light that drifts behind the
|
|
27
|
+
* content for half a minute at a time.
|
|
28
|
+
*
|
|
29
|
+
* Only `transform` is animated, so the whole thing lives on the
|
|
30
|
+
* compositor — the page never repaints for it. It is `position: fixed`
|
|
31
|
+
* and behind the content, which on a theme this dark means it shows
|
|
32
|
+
* through every translucent surface rather than over any of them.
|
|
33
|
+
*/
|
|
34
|
+
&.v-application::before {
|
|
35
|
+
content: '';
|
|
36
|
+
position: fixed;
|
|
37
|
+
inset: -20%;
|
|
38
|
+
z-index: 0;
|
|
39
|
+
pointer-events: none;
|
|
40
|
+
background-image:
|
|
41
|
+
radial-gradient(35rem 28rem at 25% 25%, rgba(124, 92, 255, 0.14), transparent 60%),
|
|
42
|
+
radial-gradient(30rem 24rem at 75% 40%, rgba(0, 212, 255, 0.1), transparent 60%),
|
|
43
|
+
radial-gradient(28rem 22rem at 55% 85%, rgba(255, 92, 170, 0.09), transparent 60%);
|
|
44
|
+
animation: vw-aurora-drift 34s ease-in-out infinite alternate;
|
|
45
|
+
}
|
|
46
|
+
|
|
23
47
|
& .v-card.v-card--variant-elevated {
|
|
24
48
|
background-image: radial-gradient(
|
|
25
49
|
36rem 18rem at 0% 0%,
|
|
@@ -30,7 +54,7 @@
|
|
|
30
54
|
}
|
|
31
55
|
|
|
32
56
|
/* An iridescent rim, drawn in the border box only. */
|
|
33
|
-
& :is(.v-card, .v-alert)::after {
|
|
57
|
+
& :is(.v-card, .v-alert, :is(.v-list, .v-sheet, .v-banner):not(:is(.v-card, .v-overlay__content, .v-navigation-drawer, .v-expansion-panels, .v-list) *))::after {
|
|
34
58
|
content: '';
|
|
35
59
|
position: absolute;
|
|
36
60
|
inset: 0;
|
|
@@ -45,9 +69,10 @@
|
|
|
45
69
|
pointer-events: none;
|
|
46
70
|
}
|
|
47
71
|
|
|
48
|
-
/* Filled buttons are the gradient itself
|
|
72
|
+
/* Filled buttons are the gradient itself — the deep one, since they
|
|
73
|
+
carry a label. */
|
|
49
74
|
& .v-btn.v-btn--variant-flat.bg-primary {
|
|
50
|
-
background-image: var(--v-vw-gradient);
|
|
75
|
+
background-image: var(--v-vw-gradient-btn, var(--v-vw-gradient));
|
|
51
76
|
box-shadow: 0 6px 24px rgba(124, 92, 255, 0.45);
|
|
52
77
|
}
|
|
53
78
|
|
|
@@ -77,10 +102,129 @@
|
|
|
77
102
|
box-shadow: 0 0 0 1px rgba(155, 140, 255, 0.16), 0 24px 64px rgba(0, 0, 0, 0.7);
|
|
78
103
|
}
|
|
79
104
|
|
|
80
|
-
/*
|
|
81
|
-
&
|
|
105
|
+
/* Progress is the one element that is literally a moving gradient. */
|
|
106
|
+
& :is(.v-progress-linear__determinate, .v-progress-linear__indeterminate) {
|
|
107
|
+
background-image: var(--v-vw-gradient);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Tonal surfaces are a flat wash of one colour in stock Vuetify, which on
|
|
112
|
+
* this theme reads as the one place the palette gave up. The underlay is
|
|
113
|
+
* a separate element precisely so it can be repainted.
|
|
114
|
+
*/
|
|
115
|
+
& :is(.v-alert__underlay, .v-chip__underlay) {
|
|
116
|
+
background-image: var(--v-vw-gradient);
|
|
117
|
+
opacity: 0.2;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/* The chrome is lit from the leading edge, like the ground under it. */
|
|
121
|
+
& :is(.v-app-bar, .v-toolbar, .v-navigation-drawer) {
|
|
122
|
+
background-image: linear-gradient(
|
|
123
|
+
100deg,
|
|
124
|
+
rgba(124, 92, 255, 0.16),
|
|
125
|
+
rgba(0, 212, 255, 0.06) 55%,
|
|
126
|
+
transparent
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* A rule that fades out at both ends rather than stopping dead.
|
|
132
|
+
*
|
|
133
|
+
* `border-image` rather than a background: `VDivider` is an `<hr>` pinned
|
|
134
|
+
* at `max-height: 0` and drawn entirely by its top border, so a
|
|
135
|
+
* background has no box to paint in. The image lands on the one edge
|
|
136
|
+
* that has a width, and a divider is straight, so the usual objection to
|
|
137
|
+
* `border-image` — that it cannot follow a rounded corner — does not
|
|
138
|
+
* apply here. The opacity is baked into the gradient because Vuetify
|
|
139
|
+
* fades the whole element by `--v-border-opacity`.
|
|
140
|
+
*/
|
|
141
|
+
& .v-divider:not(.v-divider--vertical) {
|
|
142
|
+
opacity: 1;
|
|
143
|
+
border-image: linear-gradient(
|
|
144
|
+
90deg,
|
|
145
|
+
transparent,
|
|
146
|
+
rgba(155, 140, 255, 0.45) 25%,
|
|
147
|
+
rgba(0, 212, 255, 0.35) 75%,
|
|
148
|
+
transparent
|
|
149
|
+
) 1;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/* Only the bottom border carries a width, so the image paints there
|
|
153
|
+
alone — and a table header is square, so the corner problem above
|
|
154
|
+
never comes up. */
|
|
155
|
+
& :is(.v-table thead th, .v-data-table__th) {
|
|
156
|
+
border-bottom: 1px solid transparent;
|
|
157
|
+
border-image: var(--v-vw-gradient) 1;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/* The active row is lit from its leading edge instead of barred. */
|
|
161
|
+
& .v-list-item.v-list-item--active {
|
|
162
|
+
background-image: linear-gradient(
|
|
163
|
+
90deg,
|
|
164
|
+
rgba(124, 92, 255, 0.22),
|
|
165
|
+
transparent 45%
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/* A badge is a number on a gradient, so it takes the deep one too. */
|
|
170
|
+
& .v-badge__badge {
|
|
171
|
+
background-image: var(--v-vw-gradient-btn, var(--v-vw-gradient));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* A focused field gets the same rim the cards wear. */
|
|
175
|
+
& .v-field.v-field--variant-solo-filled.v-field--focused::after {
|
|
176
|
+
content: '';
|
|
177
|
+
position: absolute;
|
|
178
|
+
inset: 0;
|
|
179
|
+
border-radius: inherit;
|
|
180
|
+
padding: var(--v-vw-border-width);
|
|
181
|
+
background: var(--v-vw-gradient);
|
|
182
|
+
opacity: 0.7;
|
|
183
|
+
mask:
|
|
184
|
+
linear-gradient(#000 0 0) content-box,
|
|
185
|
+
linear-gradient(#000 0 0);
|
|
186
|
+
mask-composite: exclude;
|
|
187
|
+
pointer-events: none;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/* The display and headline sizes carry the gradient; body text stays
|
|
191
|
+
legible, which is the whole reason the line is drawn here. */
|
|
192
|
+
& :is([class*='-display-'], [class*='-headline-large']) {
|
|
82
193
|
background: var(--v-vw-gradient);
|
|
83
194
|
background-clip: text;
|
|
84
195
|
color: transparent;
|
|
85
196
|
}
|
|
197
|
+
|
|
198
|
+
/* The dot is a bead of the same light the line carries. */
|
|
199
|
+
& .v-timeline-divider__dot {
|
|
200
|
+
background-image: var(--v-vw-gradient);
|
|
201
|
+
box-shadow: 0 0 16px rgba(124, 92, 255, 0.55);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* The dot above is the gradient, so its inner disc has to be clear for
|
|
206
|
+
* that to show. Vuetify writes this one inline when `dot-color` is a
|
|
207
|
+
* plain colour, which is the single place in the package where nothing
|
|
208
|
+
* but `!important` reaches — and the `bg-` guard keeps it off a dot whose
|
|
209
|
+
* colour the author did name, since that one arrives as a class.
|
|
210
|
+
*/
|
|
211
|
+
& .v-timeline-divider__inner-dot:not([class*='bg-']) {
|
|
212
|
+
background-color: transparent !important;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
@keyframes vw-aurora-drift {
|
|
217
|
+
from {
|
|
218
|
+
transform: translate3d(-3%, -2%, 0) scale(1.06);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
to {
|
|
222
|
+
transform: translate3d(3%, 2%, 0) scale(1.14);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
@media (prefers-reduced-motion: reduce) {
|
|
227
|
+
.v-theme--aurora.v-application::before {
|
|
228
|
+
animation: none;
|
|
229
|
+
}
|
|
86
230
|
}
|
|
@@ -38,14 +38,16 @@
|
|
|
38
38
|
font-weight: 700;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
41
|
/* Panels are cards here, so they wear the same rule as one. */
|
|
44
42
|
& .v-expansion-panels {
|
|
45
43
|
border: var(--v-vw-border-width) solid rgb(var(--v-shadow-color));
|
|
46
44
|
}
|
|
47
45
|
|
|
48
|
-
|
|
46
|
+
/* The dot is a block on a beam. */
|
|
47
|
+
& .v-timeline-divider__dot {
|
|
48
|
+
border: var(--v-vw-border-width) solid rgb(var(--v-shadow-color));
|
|
49
|
+
box-shadow: var(--vw-brut-offset) var(--vw-brut-offset) 0 rgb(var(--v-shadow-color));
|
|
50
|
+
}
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -7,23 +7,16 @@
|
|
|
7
7
|
box-shadow: none;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
/* Surfaces separate by tone alone, at the smallest step that still reads. */
|
|
11
|
-
& .v-card.v-card--variant-flat {
|
|
12
|
-
background-color: rgb(var(--v-theme-surface));
|
|
13
|
-
}
|
|
14
|
-
|
|
15
10
|
& :is(.v-menu, .v-dialog) > .v-overlay__content {
|
|
16
11
|
border: var(--v-vw-border-width) solid rgba(var(--v-border-color), 0.09);
|
|
17
12
|
box-shadow: 0 16px 48px rgba(58, 58, 54, 0.06);
|
|
18
13
|
}
|
|
19
14
|
|
|
20
|
-
|
|
21
15
|
& :is(.v-table thead th, .v-data-table__th) {
|
|
22
16
|
font-weight: 500;
|
|
23
17
|
border-bottom: var(--v-vw-border-width) solid rgba(var(--v-border-color), 0.09);
|
|
24
18
|
}
|
|
25
19
|
|
|
26
|
-
|
|
27
20
|
/* Room to breathe is the theme's only real ornament. */
|
|
28
21
|
& .v-card-text {
|
|
29
22
|
line-height: 1.7;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Candy — everything on screen is a stuffed cushion.
|
|
3
|
+
*
|
|
4
|
+
* Three layers separate cloth from plastic. A white highlight along the top
|
|
5
|
+
* inside edge, where light catches a padded surface. A shading along the
|
|
6
|
+
* bottom inside edge, where the padding rolls away from it. And a wide,
|
|
7
|
+
* low-contrast drop that spreads far more than it darkens, the way
|
|
8
|
+
* something soft resting on a table casts light rather than a hard edge.
|
|
9
|
+
*
|
|
10
|
+
* Pressing squashes: the shape sinks, gives up a little width, and its
|
|
11
|
+
* shadow shortens with it — plush deforms, it does not click.
|
|
12
|
+
*
|
|
13
|
+
* The padding is the ink colour at low alpha rather than a darker shade of
|
|
14
|
+
* each element: it has to sit under six theme colours at once, and the pink
|
|
15
|
+
* of `--v-shadow-color` reads as a halo under the teal and the green.
|
|
16
|
+
*/
|
|
17
|
+
.v-theme--candy {
|
|
18
|
+
--vw-candy-pad:
|
|
19
|
+
inset 0 2px 0 rgba(255, 255, 255, 0.55),
|
|
20
|
+
inset 0 -3px 0 rgba(var(--v-theme-on-surface), 0.08);
|
|
21
|
+
--vw-candy-rest:
|
|
22
|
+
0 3px 6px rgba(var(--v-shadow-color), 0.16),
|
|
23
|
+
0 10px 22px rgba(var(--v-shadow-color), 0.13);
|
|
24
|
+
--vw-candy-squash:
|
|
25
|
+
0 1px 3px rgba(var(--v-shadow-color), 0.2),
|
|
26
|
+
0 3px 9px rgba(var(--v-shadow-color), 0.12);
|
|
27
|
+
/* The soft drop reaches past the chip it lifts — see core.css. */
|
|
28
|
+
--v-vw-relief-inset: 4px;
|
|
29
|
+
|
|
30
|
+
& .v-btn.v-btn:is(.v-btn--variant-flat, .v-btn--variant-elevated):not(.v-btn--disabled) {
|
|
31
|
+
box-shadow: var(--vw-candy-pad), var(--vw-candy-rest);
|
|
32
|
+
transition: box-shadow var(--v-vw-motion-duration) var(--v-vw-motion-ease);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* The squash itself is `vw-press-scale` and `vw-press-shift` in core; all
|
|
36
|
+
this has to do is take the shadow down with it. */
|
|
37
|
+
& .v-btn.v-btn:is(.v-btn--variant-flat, .v-btn--variant-elevated):not(.v-btn--disabled):active {
|
|
38
|
+
box-shadow: var(--vw-candy-pad), var(--vw-candy-squash);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/* Pills are small enough that the full pad closes up on them, so they
|
|
42
|
+
take the highlight and a short drop only. */
|
|
43
|
+
& .v-chip.v-chip:not(.v-chip--variant-text, .v-chip--variant-plain) {
|
|
44
|
+
box-shadow:
|
|
45
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.5),
|
|
46
|
+
0 2px 5px rgba(var(--v-shadow-color), 0.14);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
& :is(.v-card.v-card--variant-elevated, .v-alert.v-alert--variant-tonal) {
|
|
50
|
+
box-shadow:
|
|
51
|
+
inset 0 2px 0 rgba(255, 255, 255, 0.6),
|
|
52
|
+
0 6px 16px rgba(var(--v-shadow-color), 0.12),
|
|
53
|
+
0 20px 44px rgba(var(--v-shadow-color), 0.1);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
& .v-card.v-card--variant-elevated {
|
|
57
|
+
transition: box-shadow var(--v-vw-motion-duration) var(--v-vw-motion-ease);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* The lift is `vw-hover-lift`, on the theme's own overshooting easing —
|
|
61
|
+
something soft that is picked up bounces past where it settles. */
|
|
62
|
+
& .v-card.v-card--variant-elevated.v-card--link:hover {
|
|
63
|
+
box-shadow:
|
|
64
|
+
inset 0 2px 0 rgba(255, 255, 255, 0.6),
|
|
65
|
+
0 10px 22px rgba(var(--v-shadow-color), 0.14),
|
|
66
|
+
0 28px 60px rgba(var(--v-shadow-color), 0.12);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Inputs are the one place the padding goes the other way: a dent pressed
|
|
71
|
+
* into the cushion, shaded at the top where the surface falls in. Without
|
|
72
|
+
* it `solo-filled` is the same white as the card it sits on.
|
|
73
|
+
*/
|
|
74
|
+
& .v-field.v-field--variant-solo-filled {
|
|
75
|
+
box-shadow: inset 0 2px 5px rgba(var(--v-shadow-color), 0.16);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
& .v-field.v-field--variant-solo-filled .v-field__overlay {
|
|
79
|
+
background-color: rgb(var(--v-theme-surface-light));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
& :is(.v-switch__track, .v-slider-track__background) {
|
|
83
|
+
box-shadow: inset 0 2px 4px rgba(var(--v-shadow-color), 0.22);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* The thumbs are the plushest things on screen: a lit top, a soft body,
|
|
87
|
+
and a halo standing in for the fibres a real one would have. */
|
|
88
|
+
& :is(.v-switch__thumb, .v-slider-thumb__surface) {
|
|
89
|
+
box-shadow:
|
|
90
|
+
inset 0 2px 0 rgba(255, 255, 255, 0.65),
|
|
91
|
+
0 2px 5px rgba(var(--v-shadow-color), 0.32),
|
|
92
|
+
0 0 0 5px rgba(var(--v-theme-primary), 0.14);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* `VTabs` runs inset here, so the pill behind the active tab is the
|
|
96
|
+
indicator, and it is padded like everything else. */
|
|
97
|
+
& .v-tabs--inset .v-tab__slider {
|
|
98
|
+
box-shadow:
|
|
99
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.5),
|
|
100
|
+
0 4px 12px rgba(var(--v-theme-primary), 0.24);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* The timeline is a ribbon, so it gets ends rather than corners. */
|
|
104
|
+
& :is(.v-timeline-divider__before, .v-timeline-divider__after) {
|
|
105
|
+
border-radius: 999px;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
& .v-timeline-divider__dot {
|
|
109
|
+
box-shadow:
|
|
110
|
+
inset 0 2px 0 rgba(255, 255, 255, 0.6),
|
|
111
|
+
0 3px 8px rgba(var(--v-shadow-color), 0.22);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -26,6 +26,19 @@
|
|
|
26
26
|
-2px -2px 5px rgba(255, 255, 255, 0.6);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* The lift is composed against this theme's own ground: a white
|
|
31
|
+
* highlight top-left, a dark shadow bottom-right. Inside a surface that
|
|
32
|
+
* paints its own colour — `color=` on a card, a coloured bar, a filled
|
|
33
|
+
* alert — the highlight has nothing to blend into and reads as a halo
|
|
34
|
+
* around the control, so the relief is dropped there and the control
|
|
35
|
+
* keeps its flat fill. Vuetify only emits `bg-*` when an author asked
|
|
36
|
+
* for a colour, so untouched surfaces are unaffected.
|
|
37
|
+
*/
|
|
38
|
+
& [class*='bg-'] :is(.v-btn.v-btn, .v-chip.v-chip) {
|
|
39
|
+
box-shadow: none;
|
|
40
|
+
}
|
|
41
|
+
|
|
29
42
|
& .v-btn:active:not(.v-btn--disabled) {
|
|
30
43
|
box-shadow:
|
|
31
44
|
4px 4px 10px rgba(var(--v-shadow-color), 0.16),
|
|
@@ -57,4 +70,15 @@
|
|
|
57
70
|
& .v-tab__slider {
|
|
58
71
|
border-radius: 5px;
|
|
59
72
|
}
|
|
73
|
+
|
|
74
|
+
/* The line is a channel pressed into the ground, not drawn on it. */
|
|
75
|
+
& :is(.v-timeline-divider__before, .v-timeline-divider__after) {
|
|
76
|
+
box-shadow:
|
|
77
|
+
inset 2px 2px 5px rgba(var(--v-shadow-color), 0.18),
|
|
78
|
+
inset -2px -2px 5px rgba(255, 255, 255, 0.8);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
& .v-timeline-divider__dot {
|
|
82
|
+
box-shadow: var(--vw-clay-lift);
|
|
83
|
+
}
|
|
60
84
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graphite — the theme is one subtraction and one rule.
|
|
3
|
+
*
|
|
4
|
+
* The subtraction: nothing casts a shadow. On a near-black ground a drop
|
|
5
|
+
* shadow has nothing to fall on, so every elevation Vuetify draws reads as
|
|
6
|
+
* a grey smudge. Take them all away and depth has to come from the two
|
|
7
|
+
* things that survive at this contrast — a surface a few percent lighter,
|
|
8
|
+
* and a one-pixel line. Floating overlays are the exception and keep a
|
|
9
|
+
* shadow through `--v-vw-overlay-shadow`, because they have to separate
|
|
10
|
+
* from the page rather than sit on it.
|
|
11
|
+
*
|
|
12
|
+
* The second rule: anything the interface says about itself — a column
|
|
13
|
+
* name, a status, a path — is set in mono at a small size, and anything the
|
|
14
|
+
* user wrote is not. It is the oldest convention in developer tooling and it
|
|
15
|
+
* costs nothing but a font, while carrying the whole "built by engineers"
|
|
16
|
+
* reading that a colour cannot.
|
|
17
|
+
*/
|
|
18
|
+
.v-theme--graphite {
|
|
19
|
+
--vw-graphite-label: 'JetBrains Mono', ui-monospace, 'SF Mono', 'Menlo', monospace;
|
|
20
|
+
|
|
21
|
+
& :is(
|
|
22
|
+
.v-card.v-card,
|
|
23
|
+
.v-btn.v-btn,
|
|
24
|
+
.v-chip.v-chip,
|
|
25
|
+
.v-alert.v-alert,
|
|
26
|
+
.v-table.v-table,
|
|
27
|
+
.v-expansion-panels.v-expansion-panels,
|
|
28
|
+
.v-list.v-list,
|
|
29
|
+
.v-sheet.v-sheet
|
|
30
|
+
) {
|
|
31
|
+
box-shadow: none;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* An elevated card lost the only edge it had, so it draws the line the
|
|
36
|
+
* outlined variant would have. `border` rather than a ring shadow: the
|
|
37
|
+
* card owns its box here, and a hairline that rounds with the corner is
|
|
38
|
+
* the whole visual language of the theme.
|
|
39
|
+
*/
|
|
40
|
+
& .v-card.v-card--variant-elevated {
|
|
41
|
+
border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* Column names are labels the table gives itself: mono, small, spaced. */
|
|
45
|
+
& :is(.v-table thead th, .v-data-table__th) {
|
|
46
|
+
font-family: var(--vw-graphite-label);
|
|
47
|
+
font-size: 0.6875rem;
|
|
48
|
+
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
|
|
49
|
+
border-bottom: 1px solid rgba(var(--v-border-color), 0.2);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* A status is a label too, and a breadcrumb trail is a path. */
|
|
53
|
+
& :is(.v-chip.v-chip--size-x-small, .v-chip.v-chip--size-small, .v-breadcrumbs-item) {
|
|
54
|
+
font-family: var(--vw-graphite-label);
|
|
55
|
+
font-size: 0.6875rem;
|
|
56
|
+
letter-spacing: 0.02em;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
& .v-breadcrumbs-divider {
|
|
60
|
+
font-family: var(--vw-graphite-label);
|
|
61
|
+
opacity: 0.5;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -115,7 +115,6 @@
|
|
|
115
115
|
0 2px 8px rgba(var(--v-shadow-color), 0.28);
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
|
|
119
118
|
& [class*='-title-'] {
|
|
120
119
|
letter-spacing: -0.01em;
|
|
121
120
|
}
|
|
@@ -146,7 +145,6 @@
|
|
|
146
145
|
color: rgba(var(--v-theme-on-surface), 0.5);
|
|
147
146
|
border-bottom: 1px solid rgba(var(--v-border-color), 0.14);
|
|
148
147
|
}
|
|
149
|
-
|
|
150
148
|
}
|
|
151
149
|
|
|
152
150
|
@media (prefers-reduced-transparency: reduce) {
|