PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / trunk
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin vtrunk
1.1.9 1.1.8 1.1.7 1.1.6 1.1.5 1.1.4 1.1.3 1.1.2 1.1.1 1.1.0 1.0.1 1.0.0 0.9.8 0.9.7 0.9.6 0.9.4 0.9.5 0.9.3 0.9.2 0.9.1 0.9.0 0.8.9 0.8.8 0.8.7 0.8.6 All 33 releases
desktop-mode / assets / css / app-runtime.css

app-runtime.css in OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin trunk, at assets/css/app-runtime.css

359 lines 9.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * OpenStation — App Framework runtime styles.
3 *
4 * The root every `.os.php` window mounts into. Fills the window
5 * body, declares itself a container so an app's stylesheet can use
6 * `@container` queries against the window's width, and centres the
7 * first-paint spinner until the `mount` render lands.
8 */
9
10 .os-app {
11 display: flex;
12 flex-direction: column;
13 inline-size: 100%;
14 block-size: 100%;
15 min-block-size: 0;
16 overflow: hidden;
17 background: var( --os-ui-surface, #f0f0f1 );
18 color: var( --os-ui-fg, #1d2327 );
19 font-family: var(
20 --os-ui-font,
21 -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
22 'Helvetica Neue', Arial, sans-serif
23 );
24 container-type: inline-size;
25 }
26
27 .os-app__loading {
28 display: flex;
29 flex: 1;
30 align-items: center;
31 justify-content: center;
32 }
33
34 /* A dispatch is in flight: dim nothing, just signal it to AT and
35 let an app style `[aria-busy]` if it wants a visible cue. */
36 .os-app[aria-busy='true'] {
37 cursor: progress;
38 }
39
40 /* The flex-row gap filler every toolbar ends up needing. */
41 .os-app__spacer {
42 flex: 1;
43 }
44
45 /* The drawn selection box `createMarquee()` appends to the body —
46 the same canonical selection tokens the shell's tiles wear. */
47 .os-app__marquee {
48 position: fixed;
49 z-index: 100000;
50 border: 1px solid
51 var( --os-tile-focus-ring, var( --wp-admin-theme-color, #2271b1 ) );
52 border-radius: 2px;
53 background: var(
54 --os-selection-marquee-bg,
55 var( --os-ui-accent-soft, rgba( 34, 113, 177, 0.14 ) )
56 );
57 pointer-events: none;
58 }
59
60 /* ---------- The ⋯ menu section --------------------------------------- */
61
62 /* A checkbox section `mountMenuCheckboxes()` appends to the window's
63 title-bar ⋯ menu ("Show columns"). The label is a small-caps
64 separator; the toggles are real <os-menu-item role="menuitemcheckbox">
65 nodes, so they pick up the menu's own styling. */
66 .os-app__menu-section {
67 margin-top: 4px;
68 padding: 6px 12px 2px;
69 font-size: 11px;
70 font-weight: 600;
71 letter-spacing: 0.04em;
72 text-transform: uppercase;
73 color: var( --os-ui-fg-muted, #50575e );
74 border-top: 1px solid var( --os-ui-border, #dcdcde );
75 pointer-events: none;
76 }
77
78 /* ---------- List windows --------------------------------------------- */
79
80 /* The layout every list window shares (Posts, Pages, Users, and any
81 list a plugin ships): a toolbar across the top, a flex-1 body that
82 hosts an <os-table>, a footer pager. The table is told to size to
83 the body via `--os-ui-table-max-height: 100%` so its sticky header
84 engages without an outer scrollbar. Cell-content styles are NOT
85 here — <os-table> renders into its own shadow DOM, which document
86 stylesheets never reach; cells carry inline styles. */
87 .os-app-list {
88 display: flex;
89 flex-direction: column;
90 /* A query container, so the narrow rules below track the WINDOW's
91 width — a phone, or a desktop window pulled in. */
92 container-type: inline-size;
93 height: 100%;
94 width: 100%;
95 min-height: 0;
96 background: var( --os-ui-surface, #fff );
97 color: var( --os-ui-fg, #1d2327 );
98 }
99
100 /* Tabs strip — auto-height; only the active panel below grows. */
101 .os-app-list__tabs {
102 flex: 0 0 auto;
103 }
104
105 /* Sibling panels under one flex column. The hidden ones are UA
106 display:none via the `hidden` attribute; the visible one stretches
107 to fill the remaining height. */
108 .os-app-list__panel {
109 flex: 1 1 auto;
110 min-height: 0;
111 min-width: 0;
112 display: flex;
113 flex-direction: column;
114 }
115
116 .os-app-list__panel[hidden] {
117 display: none;
118 }
119
120 .os-app-list__toolbar {
121 display: flex;
122 flex-wrap: wrap;
123 align-items: center;
124 gap: 12px;
125 padding: 10px 14px;
126 border-bottom: 1px solid var( --os-ui-border, rgba( 0, 0, 0, 0.08 ) );
127 background: var( --os-ui-surface-elevated, #f6f7f7 );
128 }
129
130 .os-app-list__toolbar-left,
131 .os-app-list__toolbar-right,
132 .os-app-list__toolbar-trailing {
133 display: flex;
134 align-items: center;
135 gap: 8px;
136 }
137
138 /* Honour the `hidden` attribute over the explicit `display: flex`. */
139 .os-app-list__toolbar-right[hidden] {
140 display: none;
141 }
142
143 .os-app-list__toolbar-trailing {
144 margin-inline-start: auto;
145 }
146
147 .os-app-list__count {
148 font-size: 12px;
149 font-weight: 600;
150 color: var( --os-ui-fg-muted, #50575e );
151 font-variant-numeric: tabular-nums;
152 padding-inline-end: 4px;
153 }
154
155 .os-app-list__body {
156 flex: 1 1 auto;
157 /* `min-width: 0` is the load-bearing piece — without it the flex
158 item's intrinsic width (the table's column sum) becomes its hard
159 minimum, pushes the table past the window's edge and turns the
160 WHOLE WINDOW into a horizontal scroller. With it the item shrinks
161 and the table's own scroll container takes the overflow. */
162 min-width: 0;
163 min-height: 0;
164 display: flex;
165 padding: 8px 12px;
166 }
167
168 .os-app-list__body os-table {
169 flex: 1 1 auto;
170 min-width: 0;
171 --os-ui-table-max-height: 100%;
172 }
173
174 .os-app-list__empty {
175 display: flex;
176 flex-direction: column;
177 align-items: center;
178 justify-content: center;
179 gap: 12px;
180 padding: 48px 24px;
181 color: var( --os-ui-fg-muted, #50575e );
182 text-align: center;
183 }
184
185 .os-app-list__empty .dashicons {
186 font-size: 40px;
187 width: 40px;
188 height: 40px;
189 color: var( --os-ui-fg-faint, #a7aaad );
190 }
191
192 .os-app-list__empty p {
193 margin: 0;
194 }
195
196 .os-app-list__empty-hint {
197 font-size: 13px;
198 color: var( --os-ui-fg-muted, #50575e );
199 }
200
201 .os-app-list__pager {
202 display: flex;
203 align-items: center;
204 justify-content: space-between;
205 gap: 12px;
206 padding: 10px 14px;
207 border-top: 1px solid var( --os-ui-border, rgba( 0, 0, 0, 0.08 ) );
208 background: var( --os-ui-surface-elevated, #f6f7f7 );
209 font-size: 13px;
210 }
211
212 .os-app-list__pager-meta {
213 color: var( --os-ui-fg-muted, #50575e );
214 font-variant-numeric: tabular-nums;
215 }
216
217 .os-app-list__pager-nav {
218 display: flex;
219 align-items: center;
220 gap: 8px;
221 }
222
223 .os-app-list__pager-perpage {
224 display: inline-flex;
225 align-items: center;
226 gap: 6px;
227 color: var( --os-ui-fg-muted, #50575e );
228 font-size: 12px;
229 margin-inline-start: 8px;
230 }
231
232 /* Narrow windows — a phone, or a desktop window pulled in. The toolbar
233 gives the status control and the search a row each instead of
234 squeezing them beside the buttons, the insets shrink to what a 360px
235 screen can spare, and the pager wraps rather than clipping its
236 per-page control. */
237 @container ( max-width: 600px ) {
238 .os-app-list__toolbar {
239 gap: 8px;
240 padding: 8px 10px;
241 }
242 .os-app-list__toolbar-left {
243 flex: 1 1 100%;
244 flex-wrap: wrap;
245 }
246 .os-app-list__toolbar-left > .os-app-list__status {
247 flex: 1 1 100%;
248 min-width: 0;
249 }
250 .os-app-list__toolbar-left > .os-app-list__search {
251 flex: 1 1 160px;
252 min-width: 0;
253 }
254 .os-app-list__toolbar-right {
255 flex: 1 1 100%;
256 flex-wrap: wrap;
257 }
258 .os-app-list__body {
259 padding: 6px 8px 8px;
260 }
261 .os-app-list__pager {
262 flex-wrap: wrap;
263 gap: 8px;
264 padding: 8px 10px;
265 }
266 }
267
268 /* The same declarations, keyed on the shell's phone mode: the phone
269 experience at any width (a wide browser previewing it, a phone
270 turned sideways), which no size query can express. A container
271 query and a stamp selector cannot share one rule list, so the
272 block is repeated on purpose — keep the two in step. */
273 html[data-os-mode="mobile"] .os-app-list__toolbar {
274 gap: 8px;
275 padding: 8px 10px;
276 }
277 html[data-os-mode="mobile"] .os-app-list__toolbar-left {
278 flex: 1 1 100%;
279 flex-wrap: wrap;
280 }
281 html[data-os-mode="mobile"] .os-app-list__toolbar-left > .os-app-list__status {
282 flex: 1 1 100%;
283 min-width: 0;
284 }
285 html[data-os-mode="mobile"] .os-app-list__toolbar-left > .os-app-list__search {
286 flex: 1 1 160px;
287 min-width: 0;
288 }
289 html[data-os-mode="mobile"] .os-app-list__toolbar-right {
290 flex: 1 1 100%;
291 flex-wrap: wrap;
292 }
293 /* The phone's list is a card per row running edge to edge. */
294 html[data-os-mode="mobile"] .os-app-list__body {
295 padding: 0;
296 }
297 html[data-os-mode="mobile"] .os-app-list__pager {
298 flex-wrap: wrap;
299 gap: 8px;
300 padding: 8px 10px;
301 }
302
303 /* The phone's list is a card per row (<os-table stacked>, set through
304 `stack-on-phone.ts`) running edge to edge, and the selection's
305 actions are a bar along the bottom of the panel — where the thumb
306 is, and still there once the toolbar has scrolled away. The bar is
307 a flex sibling of the body, so the cards end where it begins; it
308 clears the home indicator on an installed app. */
309 .os-app-list__toolbar-right.os-app-list__bulk--footer {
310 flex: 0 0 auto;
311 flex-wrap: wrap;
312 gap: 8px;
313 padding: 10px 12px calc( 10px + env( safe-area-inset-bottom, 0px ) );
314 border-block-start: 1px solid var( --os-ui-border, rgba( 0, 0, 0, 0.08 ) );
315 background: var( --os-ui-surface-elevated, #f6f7f7 );
316 box-shadow: var( --os-ui-shadow-sheet, 0 -6px 18px rgba( 0, 0, 0, 0.06 ) );
317 }
318
319 .os-app-list__toolbar-right.os-app-list__bulk--footer[hidden] {
320 display: none;
321 }
322
323 .os-app-list__toolbar-right.os-app-list__bulk--footer .os-app-list__count {
324 flex: 1 1 100%;
325 }
326
327 .os-app-list__toolbar-right.os-app-list__bulk--footer .os-app-list__bulk-actions {
328 display: flex;
329 flex: 1 1 100%;
330 flex-wrap: wrap;
331 gap: 8px;
332 }
333
334 .os-app-list__toolbar-right.os-app-list__bulk--footer .os-app-list__bulk-actions > * {
335 flex: 1 1 auto;
336 }
337
338 /* ---------- Tone contract -------------------------------------------- */
339
340 /* Any element inside an app root may carry `data-tone` and read the
341 matching status colour back through `--os-app-tone` (a swatch fill, a
342 row's accent border). Scoped to `.os-app` so the mapping never
343 retints shell chrome or admin pages outside an app window. */
344 .os-app [data-tone='danger'] {
345 --os-app-tone: var( --os-ui-danger, #d63638 );
346 }
347
348 .os-app [data-tone='warning'] {
349 --os-app-tone: var( --os-ui-warning, #dba617 );
350 }
351
352 .os-app [data-tone='neutral'] {
353 --os-app-tone: var( --os-ui-fg-muted, #646970 );
354 }
355
356 .os-app [data-tone='info'] {
357 --os-app-tone: var( --os-ui-info-fg, #72aee6 );
358 }
359