PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.10
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.10
1.1.10 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 All 34 releases
← All changes | assets/css/variables.css +502 -74 1.1.01.1.10 View file →
@@ -82,8 +82,38 @@
82 82 font-display: swap;
83 83 }
84 84
85 85 /*
86 + * ---- Registered, so "undeclared" never means transparent ---------
87 + *
88 + * The scope note below keeps this palette out of iframe documents on
89 + * purpose: an admin page inside a window renders with the values its
90 + * own stylesheets were written with. That promise has one hole CSS
91 + * digs by itself — a stylesheet that consumes
92 + * `var(--wp-admin-theme-color)` with no fallback, in a document where
93 + * nothing declares it, does not fall back to an earlier declaration
94 + * in the cascade. An unresolved `var()` is invalid at computed-value
95 + * time, so the property computes to `initial` — and an unregistered
96 + * custom property's initial value is the guaranteed-invalid value,
97 + * which for a `background` means transparent. Core's own scheme files
98 + * declare the property, but a third-party admin scheme that consumes
99 + * it without declaring it renders `.button-primary` white-on-white
100 + * inside every chromeless window (#702).
101 + *
102 + * Registering the property gives "undeclared" a real answer:
103 + * WordPress's default admin colour, the same value Core's fallbacks
104 + * reach for. Declarations are untouched — a scheme, the palette
105 + * below, or the accent picker's inline style all keep winning exactly
106 + * as before. Registration only decides what the absence of all of
107 + * them computes to.
108 + */
109 +@property --wp-admin-theme-color {
110 + syntax: "<color>";
111 + inherits: true;
112 + initial-value: #3858e9;
113 +}
114 +
115 +/*
86 116 * ---- Scope: the shell document, and nothing else -----------------
87 117 *
88 118 * `body.os-active` rather than `:root`, and that is
89 119 * load-bearing rather than tidy.
@@ -110,8 +140,22 @@
110 140 * Do not remove that dependency; see the note in
111 141 * `openstation_enqueue_desktop_theme_style()`.
112 142 */
113 143 body.os-active {
144 + /* MIO's conversation follows desktop themes through these public tokens. */
145 + --os-mio-chat-bg: var(--os-ui-modal-bg, #15151e);
146 + --os-mio-chat-fg: var(--os-ui-modal-text, #f4f4fb);
147 + --os-mio-chat-muted: var(--os-ui-modal-text-muted, #b4b4c6);
148 + --os-mio-chat-hover-bg: color-mix(in srgb, var(--os-mio-chat-bg, #fff) 90%, var(--os-mio-chat-fg, #1d2327));
149 + --os-mio-chat-border: color-mix(in srgb, var(--os-ui-accent, #a855f7) 40%, transparent);
150 + --os-mio-chat-user-bg: color-mix(in srgb, var(--os-ui-accent, #3f6dff) 15%, transparent);
151 + --os-mio-chat-glow: color-mix(in srgb, var(--os-ui-accent-dim, #ff4fd8) 10%, transparent);
152 + --os-mio-launcher-bg: color-mix(in srgb, var(--os-mio-chat-bg, #fff) 62%, transparent);
153 + --os-mio-callout-bg: var(--os-mio-chat-bg, #15151e);
154 + --os-mio-callout-fg: var(--os-mio-chat-fg, #f4f4fb);
155 + --os-mio-callout-border: color-mix(in srgb, var(--os-ui-accent-dim, #a855f7) 32%, transparent);
156 + --os-mio-chat-radius: max(18px, var(--os-window-radius, 22px));
157 +
114 158 /*
115 159 * ---- Desk --------------------------------------------------
116 160 *
117 161 * `Space`, the brand's quiet deep-space backdrop: a linear
@@ -386,8 +430,45 @@
386 430 --os-ui-surface-subtle: rgba(255, 251, 255, 0.03);
387 431 --os-ui-bg: #1a1721;
388 432 --os-ui-bg-subtle: rgba(255, 251, 255, 0.03);
389 433
434 + /*
435 + * Fields — the surface an input paints, for markup in the LIGHT
436 + * DOM.
437 + *
438 + * The kit's own controls don't need these: `<os-text-field>` and
439 + * friends resolve `--os-window-bg` inside their shadow roots,
440 + * which the window chrome sets. A plugin writing a plain
441 + * `<input>` into a native window's body has neither, and the
442 + * palette had no general answer — no `surface` variant means
443 + * "input". What it had was `--os-ui-modal-field-bg`, which is a
444 + * MODAL token: right value, wrong scope, and the sort of thing a
445 + * plugin author finds by grepping for a colour that looks close.
446 + *
447 + * Consumers keep the pre-brand WordPress-admin literals as their
448 + * fallbacks — `#fff`, `#8c8f94`, `#2c3338` — so an unstyled page
449 + * lands on the classic admin's own field, not on nothing:
450 + *
451 + * background: var( --os-ui-field-bg, #fff );
452 + * border: 1px solid var( --os-ui-field-border, #8c8f94 );
453 + * color: var( --os-ui-field-fg, #2c3338 );
454 + */
455 + --os-ui-field-bg: #33303a;
456 + --os-ui-field-border: #4d4a52;
457 + --os-ui-field-fg: #fffbff;
458 +
459 + /*
460 + * Field sizing. The kit's own `<os-text-field>` and `<os-textarea>`
461 + * (and every kit control that hosts a typing input) read these for
462 + * the control's type size and corner. The phone layer raises the
463 + * size to 16px — below that, iOS zooms the whole page into a
464 + * focused control and never zooms back — and rounds its search;
465 + * a theme may do the same anywhere.
466 + */
467 + --os-ui-field-font-size: 13px;
468 + --os-ui-field-font-size-compact: 12px;
469 + --os-ui-field-radius: 6px;
470 +
390 471 /* Text — Starlight down through the Shade ramp. */
391 472 --os-ui-fg: #fffbff;
392 473 --os-ui-fg-muted: #b3afb5;
393 474 --os-ui-fg-faint: #66636b;
@@ -451,8 +532,18 @@
451 532 --os-ui-selection-fg: #fffbff;
452 533
453 534 /* Accent — the identity moment. */
454 535 --os-ui-accent: #f252fc;
536 + /*
537 + * Ink on the accent FILL: the tick in a checked box, the dot in a
538 + * radio, the label of a primary button. Distinct from
539 + * `--os-ui-fg-on-accent`, which the shell reads as "light text on
540 + * a dark surface" in seventy-odd places that are not the accent.
541 + * Starlight here for Pulse; the accent picker rewrites it inline
542 + * to Void whenever the chosen accent is light (Starlight, Sirius,
543 + * Nebula, Lagoon), so the pair always agree.
544 + */
545 + --os-ui-accent-ink: #fffbff;
455 546 --os-ui-accent-strong: #ec9bff;
456 547 --os-ui-accent-soft: color-mix(in srgb, var(--os-ui-accent-dim) 14%, transparent);
457 548 /*
458 549 * Pulse, one step back — and the single knob for how loud the
@@ -571,8 +662,47 @@
571 662
572 663 /* The fill itself. Holomesh, so the mesh is the default look. */
573 664 --os-ui-holo-fill: var(--os-mesh-holo);
574 665 /*
666 + * A hero FIELD, as distinct from a hero control.
667 + *
668 + * `--os-ui-holo-fill` is sized for a surface a control wears — a
669 + * button, a chip, a progress bar. Stretch that same value across
670 + * a few hundred square pixels of panel and a theme's answer stops
671 + * working: Legacy's `#f0f6fc -> #f6f7f7` reads as "on" on a 40px
672 + * chip and as nothing at all on a rail, where it lands within a
673 + * few units of the surface behind it.
674 + *
675 + * So a large decorative field reads THIS instead, and a theme
676 + * gets to answer the two cases separately — how a control looks
677 + * when it is on, and how much of itself the station shows in the
678 + * background. Legacy sets a flat pre-brand wash here while
679 + * leaving its control fill alone.
680 + *
681 + * The default is an aurora, and it is built differently from the
682 + * five meshes on purpose. Those are OPAQUE light surfaces — the
683 + * darkest stop in Holomesh still sits above 60% luminance — which
684 + * is right for a control that has to read as lit against whatever
685 + * is behind it. Spread one across a rail and the only way to calm
686 + * it down is `opacity`, which drags every hue toward the surface
687 + * underneath: on Void that is grey, and the mesh dies as a
688 + * grey-mauve smear.
689 + *
690 + * So the alpha lives in the COLOUR STOPS here, over transparent.
691 + * The desk shows through instead of being covered, the hues keep
692 + * their chroma at any strength, and the field stays dark the way
693 + * an aurora is dark — light added to a night sky, not a pale
694 + * sheet laid over one. Hues are the brand's: violet and Nebula
695 + * through the upper curtains, Sirius cyan and Holomesh's mint
696 + * below, one wide Pulse bloom tying them together.
697 + */
698 + --os-ui-hero-mesh:
699 + radial-gradient(ellipse 62% 38% at 34% 20%, rgba(170, 103, 255, 0.58) 0%, rgba(170, 103, 255, 0) 74%),
700 + radial-gradient(ellipse 54% 33% at 58% 36%, rgba(236, 155, 255, 0.45) 0%, rgba(236, 155, 255, 0) 76%),
701 + radial-gradient(ellipse 68% 30% at 26% 50%, rgba(125, 239, 245, 0.32) 0%, rgba(125, 239, 245, 0) 74%),
702 + radial-gradient(ellipse 58% 28% at 46% 66%, rgba(147, 240, 198, 0.26) 0%, rgba(147, 240, 198, 0) 76%),
703 + radial-gradient(ellipse 96% 62% at 40% 42%, rgba(242, 82, 252, 0.18) 0%, rgba(242, 82, 252, 0) 82%);
704 + /*
575 705 * Glyphs and text ON that fill. Void, not Starlight — every mesh
576 706 * in the brand is a LIGHT surface (its darkest stop, Holomesh's
577 707 * #afa2e8, still sits at 62% luminance), so Starlight on it is a
578 708 * white-on-lilac 1.4:1 that looks fine in a mock and is unreadable
@@ -654,22 +784,21 @@
654 784 * satisfy WCAG 1.4.11.
655 785 */
656 786 --os-ui-holo-track-edge: #66636b;
657 787 /*
658 - * Focus. One ring for the whole kit — Pulse, offset, over a soft
659 - * halo, so it reads on Obsidian, on a mesh, and on the near-white
788 + * Focus. One ring for the whole kit — the accent, offset by a Void
789 + * gap, so it reads on Obsidian, on a mesh, and on the near-white
660 790 * of a legacy theme alike.
661 791 *
662 - * Note which layer dims and which does not. The RING is full Pulse
663 - * and stays there: it is the only thing on screen saying where the
664 - * keyboard is, and a focus indicator is the last place to trade
665 - * legibility for calm. Only the bloom behind it comes down, from
666 - * 45% to 30%, and onto the dim — which is the layer that was
667 - * making a focused control look like it was on fire.
792 + * The RING is full accent and stays there: it is the only thing on
793 + * screen saying where the keyboard is, and a focus indicator is the
794 + * last place to trade legibility for calm. The bloom that used to
795 + * sit behind it is gone: it was the layer that made a focused
796 + * control look like it was on fire, and the Void gap already does
797 + * the work of separating the ring from whatever it lands on.
668 798 */
669 799 --os-ui-focus-ring: 0 0 0 2px rgba(12, 11, 15, 0.9),
670 - 0 0 0 4px var(--os-ui-accent, #f252fc),
671 - 0 0 12px 2px color-mix(in srgb, var(--os-ui-accent-dim) 30%, transparent);
800 + 0 0 0 4px var(--os-ui-accent, #f252fc);
672 801 /*
673 802 * …and one for FIELDS, which is a different problem. A text input
674 803 * already has a border to thicken and it sits in a column of other
675 804 * inputs, so the ring above — designed to survive landing on a
@@ -685,27 +814,27 @@
685 814 * The selected row of a VERTICAL `<os-tabs>`: the sidebar in
686 815 * OpenStation Preferences, and any native window that lays its
687 816 * pages down the side rather than across the top.
688 817 *
689 - * Three layers, and the split is the whole point. Colour repeated
690 - * down nine rows is wallpaper, so the accent is spent as a
691 - * two-pixel EDGE and the row itself gets only a wash that falls
692 - * away: it appears where it is cheap to look at and expensive to
693 - * ignore.
818 + * The one selection on the station that keeps the accent. The row
819 + * runs full-bleed and says "this one" with a 2px accent line at its
820 + * leading edge, the bloom that line throws back across the row, and
821 + * a wash fading out towards the label. Everywhere else a selection
822 + * is a surface (a grey key, an outline, a flat fill); the sidebar is
823 + * where you are, and the brand marks it.
694 824 *
695 - * `-edge` is the accent the user picked, flat. It used to be
696 - * Miomesh, and a mesh does hold up at 2px where a radial one
697 - * would crop to an arbitrary lilac — but the edge is the loudest
698 - * thing on the page that says "this row", and a row that says it
699 - * in Pulse while the controls beside it say it in the chosen
700 - * accent reads as two systems.
701 - *
702 - * `-wash` and `-bloom` are AMBIENT accent, so both resolve through
703 - * `--os-ui-accent-dim` like every other glow in the kit. Turning
704 - * the station down is still one edit. The Starlight stop in the
705 - * middle of the wash is what keeps the row from reading as a pink
706 - * smear: it lifts the surface under the label rather than tinting
707 - * it, and it is gone by the time the row ends.
825 + * The three coloured layers are DERIVED from the accent: `-edge` is
826 + * the accent flat, `-wash` and `-bloom` resolve through
827 + * `--os-ui-accent-dim` like every other ambient use, so a picked
828 + * accent reaches the row on this palette and on Legacy alike (see
829 + * `desktopThemesLegacy.php`: a theme cannot answer a derived token,
830 + * so a derivation is shared). How much of each shows, and the row's
831 + * shape, are literals a theme answers on its own: edge width, wash
832 + * and bloom opacity, and a fill, radius and inset that together
833 + * would turn the row into a lifted pill. The wash's opacity scales
834 + * every stop of the gradient, because a background image has no
835 + * opacity of its own and both of the row's pseudo-elements are
836 + * already spent on the edge and the bloom.
708 837 */
709 838 --os-ui-tab-edge: linear-gradient(
710 839 var(--os-ui-accent, #f252fc),
711 840 var(--os-ui-accent, #f252fc)
@@ -711,10 +840,15 @@
711 840 var(--os-ui-accent, #f252fc)
712 841 );
713 842 --os-ui-tab-wash: linear-gradient(
714 843 90deg,
715 - color-mix(in srgb, var(--os-ui-accent-dim) 16%, transparent) 0%,
716 - rgba(255, 251, 255, 0.04) 42%,
844 + color-mix(
845 + in srgb,
846 + var(--os-ui-accent-dim) calc(16% * var(--os-ui-tab-wash-opacity, 1)),
847 + transparent
848 + )
849 + 0%,
850 + rgba(255, 251, 255, calc(0.04 * var(--os-ui-tab-wash-opacity, 1))) 42%,
717 851 transparent 100%
718 852 );
719 853 --os-ui-tab-bloom: linear-gradient(
720 854 90deg,
@@ -720,10 +854,64 @@
720 854 90deg,
721 855 color-mix(in srgb, var(--os-ui-accent-dim) 26%, transparent),
722 856 transparent
723 857 );
858 + --os-ui-tab-edge-width: 2px;
859 + --os-ui-tab-wash-opacity: 1;
860 + --os-ui-tab-bloom-opacity: 1;
861 + --os-ui-tab-fill: transparent;
862 + --os-ui-tab-radius: 0px;
863 + --os-ui-tab-inset: 0px;
724 864
725 865 /*
866 + * `<os-segmented>`, same split again. The thumb and its label still
867 + * mix from the accent, so Legacy and any theme that answers 100%
868 + * keep a coloured pill that follows the picker. This palette answers
869 + * 0%: a Void track with the chosen option as a mid-grey key and a
870 + * Starlight label, whatever accent is picked.
871 + *
872 + * The key's grey is set by contrast, not by taste. The first pass
873 + * used the sidebar row's grey, and it sat at 1.37:1 against the
874 + * track and 1.15:1 against the card around it, so the key read as a
875 + * hole in the track rather than a thing pressed into it. This grey
876 + * clears 3:1 against Void, what a selected state needs against its
877 + * neighbours, and still carries its Starlight label at 5.7:1. A
878 + * small shadow under it and a hairline around the track do the
879 + * rest: without the hairline, a Void track on the page behind the
880 + * dock options measured 1.05:1 and all but disappeared.
881 + *
882 + * Under the pointer an unselected option takes a faint Starlight
883 + * lift instead of the holographic film.
884 + */
885 + --os-ui-segmented-bg: #0c0b0f;
886 + --os-ui-segmented-edge: inset 0 0 0 1px rgba(255, 251, 255, 0.1);
887 + --os-ui-segmented-selected-accent: 0%;
888 + --os-ui-segmented-selected-base: #67636e;
889 + --os-ui-segmented-selected-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
890 + --os-ui-segmented-hover-bg: rgba(255, 251, 255, 0.06);
891 + --os-ui-segmented-hover-sheen: none;
892 +
893 + /*
894 + * The chosen tile in a swatch grid (wallpapers, the theme and
895 + * layout cards in Preferences, and any grid a plugin builds from
896 + * `<os-swatch>`), same split. The ring is the accent and stays
897 + * derived; this palette sets its width to 0 and lifts the tile
898 + * instead: a solid Starlight stroke outlines it, a shadow sets it
899 + * above the grid, and a Starlight disc with a tick cut out of it
900 + * sits in the corner. The stroke is Starlight rather than the
901 + * accent, like the badge, so the chosen tile stands out the same
902 + * way whichever accent is picked; a translucent hairline was too
903 + * faint on the dark theme cards. Legacy answers 2px, no lift, no
904 + * badge. The accent chips in the colour row keep their ring
905 + * whatever these say: a colour is the whole content there, and a
906 + * lift on a 28px square is invisible.
907 + */
908 + --os-ui-swatch-ring-width: 0px;
909 + --os-ui-swatch-lift: 0 0 0 1px #fffbff,
910 + 0 12px 24px -12px rgba(0, 0, 0, 0.8);
911 + --os-ui-swatch-badge-bg: #fffbff;
912 +
913 + /*
726 914 * ---- Motion --------------------------------------------------
727 915 *
728 916 * Four durations and three curves, and every animated thing in the
729 917 * kit picks from them. Not for tidiness: a panel where the switch
@@ -795,9 +983,9 @@
795 983
796 984 /*
797 985 * Dialogs, menus and flyouts.
798 986 *
799 - * The five `--os-ui-modal-*` names below are the escape hatch
987 + * The `--os-ui-modal-*` names below are the escape hatch
800 988 * `<os-modal>` needs. Its dialog surface is dark whatever the
801 989 * admin colour scheme says, so it re-points `--os-ui-fg`,
802 990 * `--os-ui-fg-muted`, `--os-ui-border`, `--os-window-bg` and
803 991 * `--os-ui-button-bg-hover` on its own `:host` — and a declaration
@@ -804,8 +992,22 @@
804 992 * on the host outranks anything the host inherits, which is how
805 993 * the palette used to stop at the dialog's edge. It reads these
806 994 * instead, so the station owns the dialog again and the literals
807 995 * behind them stay as the no-stylesheet floor.
996 + *
997 + * The set has to cover a dark context COMPLETELY, and the four
998 + * added last are the ones that proved it. A dialog re-pointing
999 + * only its text colours is fine while the palette around it is
1000 + * dark too — every unre-pointed token happens to agree. Put a
1001 + * LIGHT palette outside it (any theme in the admin's own colours,
1002 + * Legacy included) and the halves come apart: `--os-ui-surface`
1003 + * stays white, so `<os-select>` inside the dialog painted a white
1004 + * trigger and the re-pointed `--os-ui-fg` wrote near-white text
1005 + * onto it. `--os-ui-hover` was a black wash over a dark row.
1006 + *
1007 + * So the rule for anything added here: if a token names a SURFACE
1008 + * or a wash on one, the dialog owns it. Leaving one out is not
1009 + * "inherit the theme", it is "disagree with the other five".
808 1010 */
809 1011 --os-ui-modal-bg: #1a1721;
810 1012 --os-ui-modal-text: #fffbff;
811 1013 --os-ui-modal-text-muted: #b3afb5;
@@ -811,8 +1013,12 @@
811 1013 --os-ui-modal-text-muted: #b3afb5;
812 1014 --os-ui-modal-border: #4d4a52;
813 1015 --os-ui-modal-field-bg: #33303a;
814 1016 --os-ui-modal-button-bg-hover: rgba(255, 251, 255, 0.14);
1017 + --os-ui-modal-surface: #1a1721;
1018 + --os-ui-modal-surface-elevated: #33303a;
1019 + --os-ui-modal-border-strong: #4d4a52;
1020 + --os-ui-modal-hover: rgba(255, 251, 255, 0.06);
815 1021 --os-ui-confirm-dialog-bg: #1a1721;
816 1022 --os-ui-context-menu-bg: #1a1721;
817 1023 --os-ui-context-menu-separator-color: rgba(255, 251, 255, 0.1);
818 1024 --os-ui-flyout-shadow: 0 16px 48px rgba(0, 0, 0, 0.6);
@@ -855,10 +1061,10 @@
855 1061 * only from the component's own `::slotted( a )`. See the comment
856 1062 * there: a slotted link is a document-tree element, so wp-admin's
857 1063 * bare `a` rule outranks anything the shadow root says about it.
858 1064 */
859 - --os-ui-notice-link: #ec9bff;
860 - --os-ui-notice-link-hover: #fffbff;
1065 + --os-ui-notice-link: #fffbff;
1066 + --os-ui-notice-link-hover: #ccc8ce;
861 1067 --os-ui-badge-danger-bg: rgba(255, 90, 90, 0.16);
862 1068 --os-ui-badge-success-bg: rgba(147, 240, 198, 0.16);
863 1069 --os-ui-badge-warning-bg: rgba(248, 242, 182, 0.16);
864 1070 --os-ui-badge-info-bg: rgba(194, 241, 241, 0.16);
@@ -953,9 +1159,8 @@
953 1159 /* Search-match highlight inside a label. A WASH, not a fill: the
954 1160 text keeps its own colour, so the wash has to stay light enough
955 1161 for Starlight to carry over it. */
956 1162 --os-ui-search-highlight-bg: rgba(248, 242, 182, 0.3);
957 - --os-ui-color-accent: #f252fc;
958 1163 /*
959 1164 * The content graph's cluster hue is NOT retinted. Graph node
960 1165 * colours are composed artwork that encodes meaning — the docs list
961 1166 * them under "what stays fixed" — and moving this one to Nebula put
@@ -961,18 +1166,82 @@
961 1166 * them under "what stays fixed" — and moving this one to Nebula put
962 1167 * white cluster labels on a pale lilac chip at 1.9:1. It keeps its
963 1168 * own colour, and the label keeps carrying on it.
964 1169 *
965 - * The graph's toolbar is chrome, though, and it does follow. The
966 - * count pill on an ACTIVE filter chip is a 70%-white fill, and it
967 - * was carrying `--os-ui-accent-strong` numerals — Nebula on white,
968 - * ~1.7:1. It is one more bright fill naming its own dark text, the
969 - * same escape hatch `--os-ui-ribbon-fg` and `--os-ui-step-chip-fg`
970 - * take, and for the same reason.
1170 + * The graph's toolbar is chrome, though, and it follows the same
1171 + * split as selection everywhere else: the accent stays derived, a
1172 + * literal says how much of it shows. An ON filter chip mixes its
1173 + * edge, wash and text from the accent by `-accent`, towards the
1174 + * neutrals below; this palette answers 0%, so an on chip reads like
1175 + * the selected theme card in Preferences, a Starlight outline around
1176 + * the dark surface. Legacy answers 100%. An OFF chip sits on the
1177 + * toolbar with the strong border as its edge, because the plain
1178 + * border is the toolbar's own colour and a chip drawn with it has no
1179 + * outline at all.
1180 + *
1181 + * The count pill is the strong border's grey on both, with Starlight
1182 + * numerals: muted numerals on that grey land at 4.0:1, under what
1183 + * 12px text needs.
971 1184 */
972 - --os-ui-cg-chip-count-fg-active: #0c0b0f;
1185 + --os-ui-cg-chip-accent: 0%;
1186 + --os-ui-cg-chip-border: #4d4a52;
1187 + --os-ui-cg-chip-border-active: #fffbff;
1188 + --os-ui-cg-chip-fill-active: #1a1721;
1189 + --os-ui-cg-chip-count-bg: #4d4a52;
1190 + --os-ui-cg-chip-count-fg: #fffbff;
1191 + --os-ui-cg-chip-count-bg-active: #4d4a52;
1192 + --os-ui-cg-chip-count-fg-active: #fffbff;
973 1193
974 1194 /*
1195 + * ---- The widget card's public token contract ----------------
1196 + *
1197 + * Five names a third-party widget stylesheet is told to read.
1198 + * The list lives in `src/plugins/starter-widget/styles.css`,
1199 + * which is the file plugin authors copy — so it is a contract,
1200 + * not a convenience, and four of the five were documented
1201 + * without ever being declared. Every consumer fell through to
1202 + * the light-mode grey in its own `var()` fallback, on a card
1203 + * whose glass is dark: Post Stats' metadata measured 3.81:1
1204 + * where `.os-widgets__title` on the same surface measures 18.4.
1205 + *
1206 + * They are mostly literals rather than aliases of the text ramp,
1207 + * and that is the point. `.os-widgets__card` paints a fixed dark
1208 + * glass — `--os-ui-color-surface` below IS that colour, and the
1209 + * card reads it — under every desktop theme, so a name that
1210 + * flips with the theme is the wrong chain here: Legacy's
1211 + * `--os-ui-fg-muted` is `#50575e`, which lands at 2.54:1 on the
1212 + * glass and makes the bug WORSE for anyone wearing it. The two
1213 + * text names below do chain, but through the two names Legacy
1214 + * keeps light — the ones describing the same on-dark chrome
1215 + * this card is.
1216 + *
1217 + * A theme that wants to move a widget card declares these names
1218 + * itself, the way Legacy already declares the accent.
1219 + */
1220 + --os-ui-color-surface: rgba(20, 20, 22, 0.55);
1221 + /* What the card's own `color` already resolves to — so a widget
1222 + asking for "primary text" gets the text it inherited. */
1223 + --os-ui-color-text: var(--os-ui-fg-on-accent, #fffbff);
1224 + /* The shell's muted-on-dark. 9.2:1 on the glass, and Legacy
1225 + keeps it at `rgba( 255, 255, 255, 0.7 )`. */
1226 + --os-ui-color-text-subtle: var(--os-fg-muted, rgba(255, 251, 255, 0.7));
1227 + /* A hairline INSIDE the card, so a touch stronger than the
1228 + card's own 0.08 edge, which is drawn against the wallpaper.
1229 + Literal because no general on-dark hairline exists: the ones
1230 + Legacy keeps light are `--os-dock-border` and
1231 + `--os-cn-border`, and borrowing either is the right value at
1232 + the wrong scope. It reads quieter than what it replaces —
1233 + the widgets' own fallback was `#e5e7eb`, a light-theme
1234 + divider that on dark glass drew the loudest line in the
1235 + station. 0.12 is what the window and dock edges use. */
1236 + --os-ui-color-border: rgba(255, 251, 255, 0.12);
1237 + /* The one name that has to reach the accent picker. It was a
1238 + hard `#f252fc`, so a widget told to "use the accent for
1239 + buttons and links" stayed brand pink after the user chose
1240 + teal, while every control around it moved. */
1241 + --os-ui-color-accent: var(--os-ui-accent, #f252fc);
1242 +
1243 + /*
975 1244 * ---- Typography --------------------------------------------
976 1245 *
977 1246 * Geist for everything human — headlines, UI copy, body text — and
978 1247 * Geist Mono for the instrument voice: labels, metadata, statuses,
@@ -1104,11 +1373,10 @@
1104 1373
1105 1374 /*
1106 1375 * ---- Tooltips ---------------------------------------------
1107 1376 *
1108 - * Two tokens own every tooltip in the shell — the dock tile
1109 - * tooltip, the content-graph satellite tooltip, and the My
1110 - * WordPress entity hover card.
1377 + * Two tokens own every tooltip CHIP in the shell — the dock tile
1378 + * tooltip and the content-graph satellite tooltip.
1111 1379 *
1112 1380 * They are worth naming rather than leaving derived. Without them
1113 1381 * tooltips borrow their colours from unrelated families —
1114 1382 * `--os-ui-scrim` (an overlay BACKDROP) or `--os-ui-surface-elevated`
@@ -1116,10 +1384,16 @@
1116 1384 * pairings come apart the moment the palette moves. On this
1117 1385 * palette `--os-ui-fg-on-accent` is Void, which would have rendered
1118 1386 * near-black text on a near-black chip.
1119 1387 *
1120 - * Secondary text inside the richer tooltips — the hover card's
1121 - * excerpt — still follows `--os-ui-fg-muted`.
1388 + * A chip is deliberately the SAME dark lozenge on every desktop
1389 + * theme, which is why these two are flat values and not derived
1390 + * from anything. That is right for one line of text pinned to a
1391 + * control, and wrong for a rich card: the My WordPress entity
1392 + * hover card used to read them and showed up Obsidian over a white
1393 + * Legacy window. It has its own derived family now —
1394 + * `--os-my-wordpress-card-*`, further down — and it still names
1395 + * these two as its last fallback.
1122 1396 */
1123 1397 --os-tooltip-bg: #33303a;
1124 1398 --os-tooltip-fg: #fffbff;
1125 1399
@@ -1141,17 +1415,36 @@
1141 1415 * rule and so must read the same two tokens).
1142 1416 */
1143 1417 --os-dock-width: 56px;
1144 1418 --os-dock-icon-size: 20px;
1419 + /*
1420 + * The indicator line a dynamic dock collapses into while parked
1421 + * (Preferences → Appearance → Desktop layout → Dock behavior):
1422 + * the iOS home indicator, painted in the accent at partial alpha
1423 + * so it reads as a mark on the wallpaper rather than a control.
1424 + * `-length` runs along the rail's edge, `-thickness` across it; a
1425 + * theme retunes any of the three.
1426 + */
1427 + --os-dock-indicator-length: 180px;
1428 + --os-dock-indicator-thickness: 5px;
1429 + --os-dock-indicator-bg: color-mix( in srgb, var( --os-ui-accent, #f252fc ) 72%, transparent );
1145 1430 --os-dock-bg: rgba(12, 11, 15, 0.72);
1146 1431 --os-dock-icon-color: rgba(255, 251, 255, 0.72);
1147 1432 --os-dock-icon-color-hover: #fffbff;
1148 - --os-dock-item-bg-hover: rgba(242, 82, 252, 0.18);
1433 + --os-dock-item-bg-hover: rgba(255, 251, 255, 0.08);
1149 1434 /*
1435 + * The tile whose window is in front sits on a lit plate: the same
1436 + * Starlight wash the hover uses, one step brighter, so "this is the
1437 + * app you are in" reads as depth rather than as a coloured mark.
1438 + * The running dot under every open app stays; a lit plate says
1439 + * which one is in front, the dots say which ones are open.
1440 + */
1441 + --os-dock-item-bg-focused: rgba(255, 251, 255, 0.1);
1442 + /*
1150 1443 * The status indicator and the focus ring, and both say "this
1151 1444 * one" about a tile the user chose — so they read the accent
1152 - * rather than a fixed Pulse. Pulse is still what an untouched
1153 - * install shows, because that is what the picker starts on.
1445 + * rather than a fixed colour. Starlight is what an untouched
1446 + * install shows, because that is the accent the picker starts on.
1154 1447 */
1155 1448 --os-dock-item-outline: var(--os-ui-accent, #f252fc);
1156 1449 /*
1157 1450 * Hairline between the dock and the desktop. Reaches the side
@@ -1190,8 +1483,30 @@
1190 1483 --os-dock-floating-highlight: rgba(255, 251, 255, 0.1);
1191 1484 --os-dock-floating-shadow: rgba(0, 0, 0, 0.55);
1192 1485
1193 1486 /*
1487 + * The phone layer (`mobile.css`). Its surfaces are the dock's
1488 + * family — translucent glass over the wallpaper, light glyphs —
1489 + * and read the dock tokens above for fill, text and lines. What
1490 + * the dock has no word for is declared here: the glass a tile, a
1491 + * round control and a switcher card are cut from, its pressed
1492 + * state, the shadow under a tile, the scrim behind the switcher,
1493 + * and the label shadow that keeps text legible over any wallpaper.
1494 + * A desktop theme that reskins the dock reskins the phone with it;
1495 + * one that wants the phone alone has these.
1496 + */
1497 + --os-mobile-glass: rgba(255, 251, 255, 0.1);
1498 + --os-mobile-glass-strong: rgba(255, 251, 255, 0.16);
1499 + --os-mobile-glass-border: rgba(255, 251, 255, 0.14);
1500 + --os-mobile-tile-shadow: 0 8px 20px rgba(0, 0, 0, 0.35);
1501 + --os-mobile-card-shadow: 0 -8px 24px rgba(0, 0, 0, 0.4);
1502 + --os-mobile-sheet-shadow: 0 -12px 40px rgba(0, 0, 0, 0.45);
1503 + --os-mobile-window-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
1504 + --os-mobile-scrim: rgba(0, 0, 0, 0.55);
1505 + --os-mobile-top-scrim: rgba(0, 0, 0, 0.45);
1506 + --os-mobile-label-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
1507 +
1508 + /*
1194 1509 * ---- The OpenStation layout ---------------------------------
1195 1510 *
1196 1511 * The constellation: the flyout that fans a menu's submenu out of
1197 1512 * its tile on hover, on every rail in every layout. The rail's
@@ -1264,10 +1579,68 @@
1264 1579 --os-folder-window-bg: #1a1721;
1265 1580 --os-my-wordpress-bg: #1a1721;
1266 1581 --os-my-wordpress-fg: #fffbff;
1267 1582 --os-my-wordpress-surface: rgba(255, 251, 255, 0.06);
1583 + /*
1584 + * The entity hover card — the "thumb" that floats over a tile with
1585 + * a title, a featured image and an excerpt.
1586 + *
1587 + * It is NOT a dock chip, and it used to be painted as one.
1588 + * `--os-tooltip-bg` is a fixed dark lozenge on every theme by
1589 + * design — one line of text, always the same object, no reason to
1590 + * follow anything. The card borrowed it, so a light desktop theme
1591 + * summoned an Obsidian card over a white window, with a border in
1592 + * `--os-ui-border` and an excerpt in `--os-ui-fg-muted` that both
1593 + * followed the WINDOW instead. Three families, one surface.
1594 + *
1595 + * The card is window furniture: it belongs to the surface it was
1596 + * summoned from, so it follows the theme that paints that surface.
1597 + * Every value below is DERIVED rather than declared flat, which is
1598 + * what makes that true — a theme that names only
1599 + * `--os-my-wordpress-bg` (Legacy names exactly that, `#fff`) moves
1600 + * the card with the window for free, and a theme that wants the
1601 + * card alone names a `-card-` token.
1602 + *
1603 + * A card lands on the same colour as the window under it, so the
1604 + * border and the shadow are the whole reason it reads as a
1605 + * separate object. Neither is decoration here and neither may
1606 + * collapse into the background — which is exactly what the border
1607 + * did: `--os-ui-border` is #33303a on this palette, the SAME value
1608 + * `--os-tooltip-bg` had, so the card had no edge at all.
1609 + *
1610 + * The shadow is the one flat value in the family. A drop shadow is
1611 + * cast light, dark on a light theme and dark on a dark one, so
1612 + * there is no window token for it to follow; it is named so a
1613 + * theme can still reach it.
1614 + */
1615 + --os-my-wordpress-card-bg: var(--os-my-wordpress-bg, #1a1721);
1616 + --os-my-wordpress-card-fg: var(--os-my-wordpress-fg, #fffbff);
1617 + --os-my-wordpress-card-fg-muted: var(--os-ui-fg-muted, #b3afb5);
1618 + --os-my-wordpress-card-border: var(--os-ui-border, #33303a);
1619 + --os-my-wordpress-card-shadow: 0 8px 28px rgba(0, 0, 0, 0.45);
1620 + --os-my-wordpress-card-thumb-bg: var(
1621 + --os-media-tile-bg,
1622 + rgba(255, 251, 255, 0.05)
1623 + );
1624 + --os-my-wordpress-card-lock-bg: var(
1625 + --os-ui-badge-danger-bg,
1626 + rgba(255, 90, 90, 0.16)
1627 + );
1268 1628 --os-ai-panel-bg: rgba(26, 23, 33, 0.97);
1269 1629 /*
1630 + * The Site assistant, the same split as selection everywhere else:
1631 + * its header tint and mark, search icon, lit row and icon tiles still
1632 + * mix from the accent, and so does its send button; --os-ai-accent
1633 + * says how much. This palette
1634 + * answers 0%, so the chrome is neutral and a lit row is the flat 8%
1635 + * Starlight of the Preferences sidebar; Legacy answers 100%. The
1636 + * command icons keep the accent here too: they read it directly, so
1637 + * the colour stays in the pictures and out of the chrome.
1638 + */
1639 + --os-ai-accent: 0%;
1640 + --os-ai-row-fill: rgba(255, 251, 255, 0.08);
1641 + --os-ai-tile-fill: rgba(255, 251, 255, 0.06);
1642 + /*
1270 1643 * ---- Window tab strip ---------------------------------------
1271 1644 *
1272 1645 * A window with sub-pages reads as three surfaces stacked in
1273 1646 * depth, and the values below are that ramp: Astro on the focused
@@ -1346,46 +1719,54 @@
1346 1719 #f4eff9 0%,
1347 1720 #ffffff 58%
1348 1721 );
1349 1722 /*
1350 - * The crown. Holomesh, masked away before the joint for the same
1351 - * reason. It is on exactly ONE tab at a time — that is what keeps
1352 - * the mesh an identity moment instead of wallpaper, and it is the
1353 - * rule the rest of the kit follows. Set it to `none` to get the
1354 - * plain frosted plate back.
1723 + * The crown. Holomesh over the top of the plate, masked away before
1724 + * the joint, on exactly ONE tab at a time. Off in this palette: the
1725 + * plain frosted plate is the tab, and the one identity moment on a
1726 + * window is left to the wallpaper behind it. A theme that wants the
1727 + * mesh back declares `var(--os-mesh-holo)` here, at around 0.3.
1355 1728 */
1356 - --os-tabs-active-crown: var(--os-mesh-holo);
1729 + --os-tabs-active-crown: none;
1357 1730 --os-tabs-active-crown-opacity: 0.3;
1358 1731 /*
1359 1732 * The rail: one continuous line around the silhouette of
1360 - * page-plus-tab.
1733 + * page-plus-tab, painted as a background-image through a mask,
1734 + * which is why it is a gradient and not a colour. It is the accent
1735 + * the user picked, flat, and it stays derived so the pick reaches
1736 + * it on every theme.
1361 1737 *
1362 - * This is the one place the accent is spent on the tab strip, and
1363 - * spending it here is what lets the tab itself stay uncoloured —
1364 - * so it is the accent the user picked, flat, and not Pulsemesh.
1365 - * A mesh here would be the accent everywhere else on the tab
1366 - * strip disagreeing with the one line that carries it. Written as
1367 - * a gradient rather than a colour because the rail is painted as
1368 - * a background-image through a mask.
1369 - *
1370 - * Set it to `none` for the plain frosted plate with no line.
1738 + * On this palette it is drawn at 0 opacity. The plate already
1739 + * reads as "this tab" by being the one white shape on an Obsidian
1740 + * strip that joins the page below it; a coloured line around that
1741 + * silhouette was saying the same thing a second time, on every
1742 + * window on the desk. The opacity is the literal a theme answers
1743 + * (Legacy: 1), and the width stays at 2px because the strip's
1744 + * geometry is built on it: the plate sits on the rail whether or
1745 + * not the rail is visible, so turning it back on costs no seam.
1371 1746 */
1372 1747 --os-tabs-rail: linear-gradient(
1373 1748 var(--os-ui-accent, #f252fc),
1374 1749 var(--os-ui-accent, #f252fc)
1375 1750 );
1751 + --os-tabs-rail-opacity: 0;
1376 1752 --os-tabs-rail-width: 2px;
1377 1753 --os-media-tile-bg: rgba(255, 251, 255, 0.05);
1378 1754 --os-media-visual-bg: rgba(255, 251, 255, 0.04);
1379 1755 --os-skeleton-low: rgba(255, 251, 255, 0.05);
1380 1756 --os-skeleton-high: rgba(255, 251, 255, 0.13);
1381 - --os-drop-preview-bg: rgba(242, 82, 252, 0.1);
1382 - --os-drop-preview-border: rgba(242, 82, 252, 0.55);
1757 + --os-drop-preview-bg: rgba(255, 251, 255, 0.08);
1758 + --os-drop-preview-border: rgba(255, 251, 255, 0.45);
1383 1759
1384 1760 /*
1385 1761 * File tiles — anywhere a `.os-file-tile` (or sibling
1386 1762 * canvas tile) renders. The defaults match the desk: Starlight
1387 - * labels over a dark sky, with a Pulse selection wash.
1763 + * labels over a dark sky, and a selected tile is a lifted
1764 + * Starlight plate, the same language as the selected row in the
1765 + * Preferences sidebar, one step brighter than the hover wash so
1766 + * the two states stay apart. The accent ring around it is a
1767 + * derived colour with a literal width; this palette sets the
1768 + * width to 0 (Legacy keeps 1px) so selection is depth, not colour.
1388 1769 *
1389 1770 * Surfaces that are light in their own right override these in
1390 1771 * their own scope, e.g.:
1391 1772 *
@@ -1399,9 +1780,10 @@
1399 1780 */
1400 1781 --os-tile-fg: var(--os-fg, #fffbff);
1401 1782 --os-tile-fg-muted: rgba(255, 251, 255, 0.7);
1402 1783 --os-tile-hover-bg: rgba(255, 251, 255, 0.12);
1403 - --os-tile-selected-bg: rgba(242, 82, 252, 0.24);
1784 + --os-tile-selected-bg: rgba(255, 251, 255, 0.16);
1785 + --os-tile-selected-ring-width: 0px;
1404 1786 --os-tile-focus-ring: var(--wp-admin-theme-color, #f252fc);
1405 1787 --os-tile-shortcut-bg: rgba(12, 11, 15, 0.7);
1406 1788 --os-tile-shortcut-fg: #fffbff;
1407 1789 --os-tile-shortcut-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
@@ -1456,14 +1838,22 @@
1456 1838 * the dock (200) so it never covers navigation.
1457 1839 */
1458 1840 --os-z-mio: 190;
1459 1841 /*
1460 - * The notch — above every window and above the dock, because it
1461 - * overlaps the shell's top edge deliberately and must stay legible
1462 - * over a maximized window's title bar. Scoped inside the shell's
1463 - * own stacking context, so it never competes with the admin bar.
1842 + * The desktop-name caption. Same reasoning as Mio, one step up:
1843 + * above every window so a maximized Dashboard cannot hide it, and
1844 + * above the companion, since a momentary message should not be
1845 + * the thing that gets perched on. Still under the dock (200).
1464 1846 */
1465 - --os-z-notch: 9000;
1847 + --os-z-desktop-name: 195;
1848 + /*
1849 + * The notch — on the desk, under the windows (100 + stack index),
1850 + * above the window-link wires (50) so a tie never draws across the
1851 + * pill. It hangs over the strip a window's title bar occupies, and
1852 + * a pill floating above someone's window is the shell talking over
1853 + * the thing they are working in.
1854 + */
1855 + --os-z-notch: 60;
1466 1856
1467 1857 /*
1468 1858 * Window-link ties (relation splines between windows). The accent
1469 1859 * follows the admin color scheme. Solid colors only — the resting
@@ -1540,4 +1930,42 @@
1540 1930 * user who wants their admin scheme's hue picks it in the same panel.
1541 1931 * The `data-os-scheme` attribute is still stamped on the
1542 1932 * shell root for plugins and themes that key off it.
1543 1933 */
1934 +
1935 +/* The chat is a MIO surface even when its owning window wears a light theme.
1936 + * Component colours remain reachable through the public MIO token family. */
1937 +body.os-active .os-mio-chat,
1938 +body.os-active .os-mio-chat-launcher {
1939 + --os-ui-fg: var(--os-mio-chat-fg, #1d2327);
1940 + --os-ui-fg-muted: var(--os-mio-chat-muted, #646970);
1941 + --os-window-bg: var(--os-mio-chat-bg, #fff);
1942 + --os-ui-border: var(--os-mio-chat-border, #c3c4c7);
1943 +}
1944 +
1945 +/* Ghost labels sit on the chat; the hero button owns a lighter mesh. */
1946 +body.os-active .os-mio-chat os-button[variant="ghost"],
1947 +body.os-active .os-mio-chat-launcher {
1948 + --os-ui-button-fg: var(--os-mio-chat-fg, #1d2327);
1949 + --os-ui-button-bg-hover: var(--os-mio-chat-hover-bg, #f0f0f1);
1950 +}
1951 +
1952 +body.os-active .os-mio-chat os-button[variant="primary"],
1953 +body.os-active .os-mio-chat os-button[variant="holo"] {
1954 + --os-ui-button-fg: var(--os-ui-holo-ink, #1d2327);
1955 +}
1956 +
1957 +/* The component owns the launcher's single border and rounded surface. */
1958 +body.os-active .os-mio-chat-launcher {
1959 + --os-ui-button-bg: var(--os-mio-launcher-bg, #ffffffa0);
1960 + --os-ui-button-border: 1px solid var(--os-mio-chat-border, #c3c4c7);
1961 + --os-ui-button-border-radius: var(--os-mio-chat-radius, 22px);
1962 +}
1963 +
1964 +body.os-active .os-mio-callout {
1965 + --os-ui-button-border: 0;
1966 + --os-ui-button-border-radius: 50%;
1967 + --os-ui-button-padding: 0;
1968 + --os-ui-button-bg: transparent;
1969 + --os-ui-button-fg: var(--os-mio-callout-fg, #382b38);
1970 + --os-ui-button-bg-hover: color-mix(in srgb, var(--os-mio-callout-fg, #382b38) 10%, transparent);
1971 +}