Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
739 changes: 621 additions & 118 deletions assets/css/os-settings.css

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions assets/css/variables.css
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,23 @@ body.os-active {
--os-ui-context-menu-bg: #1a1721;
--os-ui-context-menu-separator-color: rgba(255, 251, 255, 0.1);
--os-ui-flyout-shadow: 0 16px 48px rgba(0, 0, 0, 0.6);
/*
* A card at rest, and the same card under the pointer. The hover
* half has been here since `<os-card>`; the resting half is its
* missing sibling, added because the Themes library needed a
* settled elevation and inventing one at the use site would have
* put it out of reach of every theme.
*/
--os-ui-card-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
--os-ui-card-shadow-hover: 0 4px 16px rgba(0, 0, 0, 0.45);
/*
* The badge a card wears ON its preview art, which is why this is
* its own name rather than the resting shadow above: it is read
* against arbitrary imagery, not against the panel, so it wants a
* heavier shadow than the card it sits on. Sharing one token
* collapsed the two the moment the palette declared it.
*/
--os-ui-card-mark-shadow: 0 3px 10px rgba(0, 0, 0, 0.5);
--os-ui-ribbon-shadow: 0 2px 4px rgba(0, 0, 0, 0.45);

/* Tables. */
Expand Down
2 changes: 2 additions & 0 deletions assets/desktop-themes/legacy/theme.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@
"--os-ui-card-padding-compact": "10px",
"--os-ui-card-radius": "12px",
"--os-ui-card-radius-compact": "8px",
"--os-ui-card-mark-shadow": "0 3px 10px rgba( 0, 0, 0, 0.3 )",
"--os-ui-card-shadow": "0 3px 10px rgba( 0, 0, 0, 0.07 )",
"--os-ui-card-shadow-hover": "0 4px 16px rgba( 0, 0, 0, 0.08 )",
"--os-ui-card-shadow-selected": "0 0 0 1px #2271b1 inset",
"--os-ui-cat-check-border": "#8c8f94",
Expand Down
55 changes: 35 additions & 20 deletions docs/desktop-themes.md
Original file line number Diff line number Diff line change
Expand Up @@ -1081,11 +1081,12 @@ activates it — and never again.**
- **A later change by the user always wins.** Pick the theme, put the
dock back to compact, re-pick the theme — it stays compact.

The way back is the user's to take: **OpenStation Preferences → Themes** shows an
**Apply &lt;theme&gt;'s recommended layout and effects** button for the
active theme when it recommends something, and that is the only path
that applies a recommendation a second time. It sets the settings and
nothing else — the dock resizing under the cursor is the feedback.
The way back is the user's to take: **OpenStation Preferences → Themes** shows a
**Restore recommended layout & effects** button on the stage that
carries the active theme, when that theme recommends something, and
that is the only path that applies a recommendation a second time. It
sets the settings and nothing else — the dock resizing under the
cursor is the feedback.

This is the same posture as [wallpapers](#it-is-a-pick-not-an-act),
for the same reason. Dock size and layout are stored user
Expand Down Expand Up @@ -1636,9 +1637,13 @@ from an empty manifest.

## Installing and activating

**Install:** OpenStation Preferences → Themes → drop a `.zip` on the upload tile.
Requires `manage_options` by default (filterable via
`openstation_desktop_theme_upload_capability`).
**Install:** OpenStation Preferences → Themes → **Manage theme
packages** → drop a `.zip` on the upload area, or choose one from your
computer. Installing and removing packages is site-wide work, so the
whole drawer — and it alone — requires `manage_options` by default
(filterable via `openstation_desktop_theme_upload_capability`).
Choosing which installed theme to *wear* is personal and needs no
capability at all; that is the library above the drawer.

**Window controls.** These are title-bar chrome, so they follow the
title bar's own colours rather than the body palette, and each focus
Expand Down Expand Up @@ -1690,25 +1695,35 @@ including users who cannot upload. The library is site-wide;
activation is per-user, stored as `desktopTheme` in the
`desktop_mode_os_settings` user meta.

The first card in the grid is **OpenStation** — the shell's own look,
stored as the empty string. It is not a theme in the registry (its
palette is `assets/css/variables.css`, not a manifest), but the picker
treats it as a peer of everything beside it: it carries the same
"Apply …'s recommended layout and effects" button, and what it
recommends is the accent its palette was drawn against (Pulse) and the
layout it was drawn for (`classic`).

The switch is live: no reload. The stylesheet swaps, the shell
The first choice in the library is **OpenStation** — the shell's own
look, stored as the empty string. It is not a theme in the registry
(its palette is `assets/css/variables.css`, not a manifest), but the
picker treats it as a peer of everything beside it: it gets the same
stage and the same "Restore recommended layout & effects" button when
it is the one being worn, and what it recommends is the accent its
palette was drawn against (Pulse) and the layout it was drawn for
(`classic`).

The library is a radio group, but **activation is manual**: arrow keys
move focus between choices, and Space, Enter or a click is what
actually switches theme. Selection deliberately does not follow focus.
Switching is not editing a preference — it swaps the stylesheet,
repaints every themed icon, and on a first wearing seeds that theme's
recommendations over the user's own arrangement — so arrowing across
the library on the way to one theme must not fire that for every
theme it passes.

The switch itself is live: no reload. The stylesheet swaps, the shell
attribute and body class flip, and every themed icon repaints. On a
fresh page load PHP stamps the attribute, prints the body class, and
enqueues the stylesheet before the shell script runs, so there is no
flash of the default palette.

If the theme ships
[`recommendedOsSettings`](#recommended-os-settings), the user's first
activation of it also seeds those preferences — once — and the tab
grows an **Apply &lt;theme&gt;'s recommended layout** button for going
back to them later.
activation of it also seeds those preferences — once — and the stage
grows a **Restore recommended layout & effects** button for going back
to them later.

### From JavaScript

Expand Down
2 changes: 1 addition & 1 deletion docs/javascript-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -3078,7 +3078,7 @@ Whatever wins, `edgeLag` is scaled by the same ratio, so the edge band keeps its
- **It replays on every load edge** the spinner replays on — a reload, an in-window navigation, a tab switch — not only on first open.
- **`prefers-reduced-motion` skips the animation** and uncovers the content directly. Same for environments without the Web Animations API.
- **The colours are theme tokens**: `--os-window-reveal-surface` (white) and `--os-window-reveal-edge` (`transparent` — no edge). A def can override them with `surfaceColor` / `edgeColor`, or per layer with `layers[].color`, but should not unless the paint is the point. `obturator` is the only built-in that does, and only per layer: its six leaves have to differ from one another or the mechanism reads as a single shape.
- **A desktop theme can recommend a reveal**, via `recommendedOsSettings.windowReveal` and `recommendedOsSettings.windowRevealDuration` — applied once on first activation, or on demand from the Themes tab's "Apply recommended layout and effects" button.
- **A desktop theme can recommend a reveal**, via `recommendedOsSettings.windowReveal` and `recommendedOsSettings.windowRevealDuration` — applied once on first activation, or on demand from the Themes tab's "Restore recommended layout & effects" button.
- **Registration is JS-only.** Unlike unfocus effects, there is no `openstation_register_window_reveal_script()` PHP companion yet, so a reveal registered by a plugin activated mid-session appears in the selector only after a reload — and a deactivated plugin's reveal stays listed until a reload too (`owner` is recorded, but nothing sweeps by it on deactivation yet). Same known gap as palettes.

The raw `os.window-reveals` JS filter receives the registry array on every read, mirroring `os.unfocus-effects` — use it to reorder, remove, or conditionally swap reveals. The user's selection persists in the `windowReveal` OS-settings key (reveal id or `'none'`, the default — reveals are opt-in), readable via `getOsSettings().windowReveal`. An unknown id (a deactivated plugin's reveal still named in user meta) resolves to no reveal rather than to a substitute, and starts working again the moment that plugin re-registers it.
Expand Down
Loading
Loading