| @@ -1,57 +1,113 @@ | ||
| 1 | 1 | /** |
| 2 | - * Desktop Mode — Window styles (entry point). | |
| 2 | + * OpenStation — Window styles (entry point). | |
| 3 | 3 | * |
| 4 | 4 | * The window stylesheet used to be 1,500 lines of chrome, states, |
| 5 | - * overview, and OS Settings mixed together. It now imports four | |
| 5 | + * overview, and OS Settings mixed together. It is now split into | |
| 6 | 6 | * focused files so each concern lives on its own: |
| 7 | 7 | * |
| 8 | 8 | * - window-chrome.css — base window, title bar, icon, title, |
| 9 | - * controls, focused/unfocused variants, | |
| 9 | + * controls, focused / unfocused variants, | |
| 10 | 10 | * menu panel, screen-meta buttons, tabs, |
| 11 | 11 | * window body, primary iframe, native body. |
| 12 | 12 | * - window-states.css — resize handle, drag/resize overlays, |
| 13 | 13 | * maximized, fullscreen, opening animation, |
| 14 | 14 | * minimized, closing, reduced-motion, RTL. |
| 15 | + * - effects.css — unfocused-window effects. | |
| 16 | + * - window-links.css — relation ties between windows. | |
| 15 | 17 | * - window-overview.css — zoom-out overview grid + floating labels |
| 16 | 18 | * + per-desktop top bar + dock-collapse. |
| 17 | 19 | * - os-settings.css — the OS Settings native panel (wallpaper |
| 18 | 20 | * picker, accent, dock size, uploader, |
| 19 | - * Media Library grid). Will move to its own | |
| 20 | - * enqueue once it stops being coupled to the | |
| 21 | - * window chrome loading order. | |
| 21 | + * Media Library grid). | |
| 22 | 22 | * |
| 23 | - * The `desktop-mode-windows` script handle registers this file as its | |
| 24 | - * CSS source, so all four sub-sheets ship with a single handle — no | |
| 25 | - * changes required to `includes/assets.php` or `includes/render.php`. | |
| 23 | + * ## Every sub-sheet is its own enqueued handle — NOT an `@import` | |
| 26 | 24 | * |
| 25 | + * They used to be `@import url( … )`ed from this file, and that was a | |
| 26 | + * standing cache bug. An `@import` URL carries no `?ver=`, so when a | |
| 27 | + * sub-sheet changed there was no URL anywhere for the browser to | |
| 28 | + * notice. `openstation_css_subtree_version()` stamped THIS file with | |
| 29 | + * the max mtime of the whole subtree, which made the browser re-fetch | |
| 30 | + * and re-parse `windows.css` — and then request the sub-sheet at a | |
| 31 | + * completely unchanged URL, free to serve it from its heuristic | |
| 32 | + * cache. A parent's stamp can never invalidate its children. | |
| 33 | + * | |
| 34 | + * The symptom was edits to a sub-sheet not landing until a hard | |
| 35 | + * refresh, and the workaround was to relocate rules INTO this file — | |
| 36 | + * which happened twice and was turning this into a junk drawer. | |
| 37 | + * | |
| 38 | + * Each sub-sheet is now registered in `includes/assets.php` with its | |
| 39 | + * own `filemtime` stamp, chained by dependency so the cascade order | |
| 40 | + * is preserved exactly: | |
| 41 | + * | |
| 42 | + * window-chrome → window-states → effects → window-links | |
| 43 | + * → windows (this file) → window-overview → os-settings | |
| 44 | + * | |
| 45 | + * The last two sit AFTER this file and load **deferred** (the | |
| 46 | + * `media="print"` + onload swap driven by | |
| 47 | + * `openstation_deferred_styles`): the UI they style is lazy-loaded | |
| 48 | + * JS that can never be on screen at first paint, so ~47 KB of CSS has | |
| 49 | + * no business blocking render. | |
| 50 | + * | |
| 51 | + * Rules in this file still win ties against the four critical | |
| 52 | + * sub-sheets, exactly as they did when the `@import`s sat at the top. | |
| 53 | + * But there is no longer any reason to put a rule here for cache | |
| 54 | + * reasons — put it in the sheet it belongs to. | |
| 55 | + * | |
| 56 | + * Dropping the `@import`s also removes a request waterfall: the | |
| 57 | + * browser could not discover the sub-sheets until it had fetched and | |
| 58 | + * parsed this file. They are now all in the initial HTML. | |
| 59 | + * | |
| 27 | 60 | * @since 6.9.0 |
| 28 | 61 | */ |
| 29 | 62 | |
| 30 | -@import url( "window-chrome.css" ); | |
| 31 | -@import url( "window-states.css" ); | |
| 32 | -@import url( "window-overview.css" ); | |
| 33 | -@import url( "os-settings.css" ); | |
| 34 | - | |
| 35 | 63 | /* |
| 36 | - * Cross-window drag drop highlight — kept INLINE in this file | |
| 37 | - * (not in any of the @import'd sub-sheets) so the mtime-stamped | |
| 38 | - * `?ver=…` on `windows.css` reliably invalidates the rules along | |
| 39 | - * with the parent stylesheet. Sub-sheets are fetched without an | |
| 40 | - * explicit version query and can be served from the browser's | |
| 41 | - * heuristic cache even after a hard reload. | |
| 64 | + * Cross-window drag drop highlight. | |
| 42 | 65 | * |
| 66 | + * Lives here for historical reasons: sub-sheets used to be | |
| 67 | + * `@import`s with no `?ver=`, so cache-sensitive rules were kept in | |
| 68 | + * the stamped parent. Every sheet now carries its own filemtime | |
| 69 | + * stamp, so this could move to `window-chrome.css` alongside the | |
| 70 | + * rest of the window-body rules whenever someone is in the area. | |
| 71 | + * | |
| 43 | 72 | * The cross-window pointer routing itself is driven from |
| 44 | 73 | * JavaScript by `src/drag/iframe-drop-targets.ts` — on drag |
| 45 | 74 | * START with a shortcut payload, every iframe element gets an |
| 46 | 75 | * inline `style.pointerEvents = 'none'` so pointer events fall |
| 47 | - * through to the iframe's parent (`.desktop-mode-window__body`), | |
| 76 | + * through to the iframe's parent (`.os-window__body`), | |
| 48 | 77 | * which is registered as the drop target. No CSS rule is needed |
| 49 | 78 | * to make the routing work — this stylesheet only paints the |
| 50 | 79 | * visual feedback for whichever window is currently the active |
| 51 | 80 | * drop target. |
| 52 | 81 | */ |
| 53 | -.desktop-mode-window__body[data-desktop-mode-iframe-drop-active] { | |
| 54 | - outline: 2px dashed var(--desktop-mode-accent, #2271b1); | |
| 82 | +.os-window__body[data-os-iframe-drop-active] { | |
| 83 | + outline: 2px dashed var(--os-ui-accent, #2271b1); | |
| 55 | 84 | outline-offset: -6px; |
| 56 | - background: color-mix(in srgb, var(--desktop-mode-accent, #2271b1) 8%, transparent); | |
| 85 | + background: color-mix(in srgb, var(--os-ui-accent, #2271b1) 8%, transparent); | |
| 86 | +} | |
| 87 | + | |
| 88 | +/* | |
| 89 | + * Title-bar meta-button dashicon centring — same cache-busting | |
| 90 | + * reason: Dashicons inherits `display: inline-block` from core | |
| 91 | + * which positions the glyph via text-layout, and the font's | |
| 92 | + * baseline isn't the geometric centre of its em-box, so the | |
| 93 | + * visible `?` drifts off-centre inside the 28×28 button. | |
| 94 | + * Re-flexing the dashicon span re-anchors the glyph regardless | |
| 95 | + * of the font's intrinsic metrics. | |
| 96 | + * | |
| 97 | + * Also here for the old cache reason rather than a styling one — | |
| 98 | + * see the note above; it can move back to `window-chrome.css`. | |
| 99 | + */ | |
| 100 | +.os-window__meta-btn .dashicons { | |
| 101 | + display: inline-flex; | |
| 102 | + align-items: center; | |
| 103 | + justify-content: center; | |
| 104 | + line-height: 1; | |
| 105 | + /* Reset any inherited `top` / `left` offset that bleeds in | |
| 106 | + * from wp-admin or third-party stylesheets that style icons | |
| 107 | + * by their glyph class (e.g. `.dashicons-editor-help` with | |
| 108 | + * `top: 5px; left: 6px;` — leftover from contextual-help | |
| 109 | + * styling that doesn't belong in our title bar). Without this | |
| 110 | + * the glyph drifts off-centre inside the button. */ | |
| 111 | + top: 0 !important; | |
| 112 | + left: 0 !important; | |
| 57 | 113 | } |