| 1 |
/** |
| 2 |
* Window links — visual ties between related windows. |
| 3 |
* |
| 4 |
* The link layer sits inside `#os-area`, absolutely |
| 5 |
* positioned over the whole desktop. At rest it stacks BETWEEN the |
| 6 |
* widget layer (z 1) and the windows (z 100+) — wires on the desk, |
| 7 |
* visible in the gaps. While a relation-group member is focused, the |
| 8 |
* render host lifts the layer to the group's z-ceiling via an inline |
| 9 |
* z-index so the ties draw over every window except the top one. |
| 10 |
* `pointer-events: none` throughout — the layer must never steal a |
| 11 |
* click from the desktop or a window. |
| 12 |
* |
| 13 |
* Tuning knobs live in `variables.css` as |
| 14 |
* `--os-window-link-*`; the SVG structure comes from the |
| 15 |
* built-in `svg-splines` renderer (`src/window-links/renderers/`). |
| 16 |
* Third-party renderers mount their own children into the same layer |
| 17 |
* and are free to ignore all of this. |
| 18 |
* |
| 19 |
* @since 0.9.4 |
| 20 |
*/ |
| 21 |
|
| 22 |
.os-window-links { |
| 23 |
position: absolute; |
| 24 |
inset: 0; |
| 25 |
z-index: var(--os-z-window-links, 50); |
| 26 |
pointer-events: none; |
| 27 |
opacity: 0; |
| 28 |
transition: opacity 0.25s ease; |
| 29 |
} |
| 30 |
|
| 31 |
/* |
| 32 |
* Toggled by the render host per the `windowLinkVisibility` OS |
| 33 |
* setting: always on under `always`, tracking group focus under |
| 34 |
* `focus`. The fade lives here so every renderer inherits it. |
| 35 |
*/ |
| 36 |
.os-window-links--visible { |
| 37 |
opacity: 1; |
| 38 |
} |
| 39 |
|
| 40 |
@media (prefers-reduced-motion: reduce) { |
| 41 |
.os-window-links { |
| 42 |
transition: none; |
| 43 |
} |
| 44 |
} |
| 45 |
|
| 46 |
.os-window-links__svg { |
| 47 |
display: block; |
| 48 |
width: 100%; |
| 49 |
height: 100%; |
| 50 |
} |
| 51 |
|
| 52 |
.os-window-link__path { |
| 53 |
fill: none; |
| 54 |
/* Solid scheme color + opacity for the resting dimming. No |
| 55 |
color-mix() anywhere in this chain: when a custom property's |
| 56 |
value can't resolve, the consuming declaration goes invalid at |
| 57 |
computed-value time and an SVG stroke resets to `none` — |
| 58 |
invisible lines under floating black endpoint markers. The var() |
| 59 |
fallback covers a missing token outright. */ |
| 60 |
stroke: var(--os-window-link-color, #2271b1); |
| 61 |
stroke-opacity: 0.55; |
| 62 |
stroke-width: var(--os-window-link-width, 1.5px); |
| 63 |
stroke-linecap: round; |
| 64 |
} |
| 65 |
|
| 66 |
/* |
| 67 |
* Endpoint dots (inside <defs><marker>). Circles rather than |
| 68 |
* arrowheads — rotation-invariant, so a tie meeting a border at any |
| 69 |
* angle looks right. Two variants because a marker can't read the |
| 70 |
* class of the path referencing it — the renderer swaps |
| 71 |
* marker-end/-start between them on focus. Direction survives as |
| 72 |
* size: the larger dot sits on the root/referenced window; |
| 73 |
* bidirectional reference edges get large dots on both ends. |
| 74 |
*/ |
| 75 |
.os-window-link__endpoint { |
| 76 |
fill: var(--os-window-link-color, #2271b1); |
| 77 |
fill-opacity: 0.55; |
| 78 |
} |
| 79 |
|
| 80 |
.os-window-link__endpoint--active { |
| 81 |
fill: var(--os-window-link-color-active, #2271b1); |
| 82 |
fill-opacity: 1; |
| 83 |
} |
| 84 |
|
| 85 |
/* Edges touching the focused window get the emphasized stroke. */ |
| 86 |
.os-window-link--active .os-window-link__path { |
| 87 |
stroke: var(--os-window-link-color-active, #2271b1); |
| 88 |
stroke-opacity: 1; |
| 89 |
stroke-width: calc(var(--os-window-link-width, 1.5px) + 0.5px); |
| 90 |
} |
| 91 |
|
| 92 |
/* |
| 93 |
* Related-window chrome cue — stamped by the render host on every |
| 94 |
* OTHER member of the focused window's relation group. Two parts: |
| 95 |
* |
| 96 |
* - an accent outline (follows the window's border-radius on every |
| 97 |
* modern engine); |
| 98 |
* - a soft halo. box-shadow is one property, so the window's |
| 99 |
* elevation shadow is re-declared behind the glow — dropping it |
| 100 |
* would flatten linked windows against the wallpaper. A linked |
| 101 |
* window is by definition not the focused one, so the unfocused |
| 102 |
* elevation token is the right one to compose with. |
| 103 |
* |
| 104 |
* The base window chrome already transitions box-shadow, so the halo |
| 105 |
* fades in and out with focus changes for free. |
| 106 |
*/ |
| 107 |
.os-window--linked { |
| 108 |
outline: 2px solid var(--os-window-link-accent, var(--wp-admin-theme-color, #2271b1)); |
| 109 |
outline-offset: 1px; |
| 110 |
box-shadow: |
| 111 |
0 0 18px 4px var(--os-window-link-glow, rgba(34, 113, 177, 0.45)), |
| 112 |
var(--os-window-shadow); |
| 113 |
} |
| 114 |
|