mirror of
https://github.com/MichaelScottsman/LiquidAss-Frame.git
synced 2026-10-17 18:02:42 +02:00
1335 lines
62 KiB
CSS
1335 lines
62 KiB
CSS
/* Glass Shell primitives (package C4a, Phase 2 T1).
|
||
Concept: docs/phase2/concepts/controls.md (CTL) §4-§10, §13; PLAN §1.3,
|
||
§1.4, §1.16; tokens and hooks: docs/phase2/contracts/tokens.md (P4);
|
||
motion tokens and keyframes: docs/phase2/contracts/motion.md (P5).
|
||
Wrapped as html.lgs-on { ... } by the bundler ("&" is html.lgs-on).
|
||
|
||
What this file does: it opts Steam's shared primitives into P4's hooks
|
||
(--lgs-ill: the light layer on ::after; --lgs-edge: the specular arc on
|
||
::before; the state numbers --lgs-hover/-focus/-within/-press/-dis),
|
||
gives them visionOS sizes, overrides Steam's own focus fills and rings,
|
||
and adds what is specific to each control (rows and the control inside
|
||
them, switch knob and track, slider fill and knob, check circles).
|
||
|
||
Rules for areas (CTL §0.1): areas place these primitives and never restyle
|
||
them; a subtree that draws its own control forms opts out with
|
||
[data-lgs-noprim] on its root. Every look is keyed on P3's input mode:
|
||
laser looks on :hover (html:not(.lgs-input-pad)), gamepad looks on
|
||
.gpfocus (html:not(.lgs-input-laser)); rules that name .gpfocus without a
|
||
mode only put a control back to its rest look (Steam paints focus white).
|
||
|
||
Sections
|
||
1. Buttons (DialogButton family) 6. Pop-up buttons (dropdowns)
|
||
2. Rows and platters (G>Field) 7. Segmented controls
|
||
3. Switches (G>Toggle) 8. Text fields
|
||
4. Check circles (.DialogCheckbox) 9. Progress bars
|
||
5. Sliders 10. Pop-up labels in C1c's menus
|
||
11. Markup classes (.lgs-btn, ...) 12. High Contrast
|
||
Menus, alerts, sheets and the scrim are C1c's (22-presentations.css). */
|
||
|
||
|
||
/* ======================================================================
|
||
1. Buttons: button.DialogButton + G>Button (CTL §5)
|
||
Capsule 60 (label 24 Semibold, padding 24), icon-only circle 60.
|
||
Rest = raised fill + lit lip; the light layer (::after, under the label)
|
||
and the specular arc (::before) are P4's hooks. Press swells glass
|
||
controls by min(1.06, 1 + 6 / longest side) on the independent `scale`.
|
||
====================================================================== */
|
||
|
||
button.DialogButton%{*GamepadDialogContent>Button}:not([data-lgs-noprim] *) {
|
||
min-height: var(--lgs-btn);
|
||
padding: 0 var(--lgs-btn-pad);
|
||
border: 0;
|
||
border-radius: var(--lgs-r-capsule);
|
||
font: var(--lgs-type-headline);
|
||
letter-spacing: var(--lgs-track-headline);
|
||
text-transform: none;
|
||
text-shadow: none;
|
||
background: var(--lgs-raised-bg);
|
||
box-shadow: var(--lgs-raised-shadow);
|
||
color: var(--lgs-text-1);
|
||
/* the light layer under the label (VP P-10), the arc on ::before */
|
||
isolation: isolate;
|
||
--lgs-ill: raised;
|
||
--lgs-ill-z: -1;
|
||
--lgs-edge: control;
|
||
/* a softer pointer spot on a capsule keeps laser hover within VP P-03's
|
||
+10..+25 L (P4's .12 measured +26.3 on /zoo/buttons; C4a-D16) */
|
||
--lgs-hover-spot: .10;
|
||
/* press swell: longest side of a typical capsule (CTL C-D12) */
|
||
--lgs-c4a-side: 160;
|
||
scale: calc(1 + (min(var(--lgs-press-max), 1 + var(--lgs-press-grow) / var(--lgs-c4a-side)) - 1) * var(--lgs-press));
|
||
transition:
|
||
scale var(--lgs-d-snappy) var(--lgs-ease-b15),
|
||
background-color var(--lgs-d-fade) var(--lgs-ease-b0),
|
||
color var(--lgs-d-fade) var(--lgs-ease-b0);
|
||
}
|
||
/* press in on `interactive`, release on `snappy` (CTL §4.4) */
|
||
button.DialogButton%{*GamepadDialogContent>Button}:not([data-lgs-noprim] *):is(:active, .lgs-pressed) {
|
||
transition:
|
||
scale var(--lgs-d-interactive) var(--lgs-ease-b15),
|
||
background-color var(--lgs-d-fade) var(--lgs-ease-b0),
|
||
color var(--lgs-d-fade) var(--lgs-ease-b0);
|
||
}
|
||
/* Steam paints focus, hover and press white (and Primary blue on hover):
|
||
back to the rest look in every mode, so the light layer carries every
|
||
state (tokens.md §3.2). Neutral only: no look keys on .gpfocus here. */
|
||
button.DialogButton%{*GamepadDialogContent>Button}:not([data-lgs-noprim] *):is(.gpfocus, :hover, :active, :focus, .Primary, .Destructive) {
|
||
background: var(--lgs-raised-bg) !important;
|
||
box-shadow: var(--lgs-raised-shadow) !important;
|
||
color: var(--lgs-text-1) !important;
|
||
}
|
||
/* glyph buttons darken their icon for Steam's white focus; ours is not white */
|
||
button.DialogButton%{*GamepadDialogContent>Button}.Glyph:not([data-lgs-noprim] *) {
|
||
filter: none !important;
|
||
}
|
||
|
||
/* icon-only buttons: 60 px circles, 26 px symbol (CTL §5, VP P-83) */
|
||
button.DialogButton%{*GamepadDialogContent>Button}:is(%{ShowKeyboardButton}, %{BuiltInLayoutButton}, %{BackButtonContent>BackButton}):not([data-lgs-noprim] *) {
|
||
width: var(--lgs-btn);
|
||
height: var(--lgs-btn);
|
||
min-width: var(--lgs-btn);
|
||
padding: 0;
|
||
border-radius: 50%;
|
||
display: inline-grid;
|
||
place-items: center;
|
||
--lgs-c4a-side: 60;
|
||
& svg {
|
||
width: var(--lgs-symbol);
|
||
height: var(--lgs-symbol);
|
||
}
|
||
}
|
||
|
||
/* the one tinted action: a dialog's confirm. Steam marks other buttons
|
||
Primary too (row actions such as Disconnect): those stay raised, so a
|
||
screen keeps a single tinted capsule (CTL §5 roles). White on blue. */
|
||
:is(.DialogFooter, %{ModalButtonRow}, .DialogTwoColLayout) button.DialogButton%{*GamepadDialogContent>Button}.Primary:not(.Disabled, [disabled]):not([data-lgs-noprim] *) {
|
||
background: linear-gradient(180deg, rgb(255 255 255 / .16), rgb(255 255 255 / 0) 55%), var(--lgs-tint-primary) !important;
|
||
box-shadow: inset 0 1.5px 1.5px -1px rgb(255 255 255 / .35), 0 3px 8px rgb(0 0 0 / .22) !important;
|
||
color: var(--lgs-text-on-tint) !important;
|
||
--lgs-ill: white;
|
||
}
|
||
/* destructive confirm inside a dialog: red whole fill, dark label (C-D21) */
|
||
:is(.DialogFooter, %{ModalButtonRow}, .DialogTwoColLayout) button.DialogButton%{*GamepadDialogContent>Button}.Destructive:not(.Disabled, [disabled]):not([data-lgs-noprim] *) {
|
||
background: linear-gradient(180deg, rgb(255 255 255 / .16), rgb(255 255 255 / 0) 55%), var(--lgs-fill-danger) !important;
|
||
box-shadow: inset 0 1.5px 1.5px -1px rgb(255 255 255 / .35), 0 3px 8px rgb(0 0 0 / .22) !important;
|
||
color: var(--lgs-text-on-color) !important;
|
||
--lgs-ill: white;
|
||
}
|
||
/* Play: green, dark label and glyph (C-D21, CC §7) */
|
||
button.DialogButton.GreenPlay:not(.Disabled, [disabled]):not([data-lgs-noprim] *) {
|
||
background: linear-gradient(180deg, rgb(255 255 255 / .16), rgb(255 255 255 / 0) 55%), var(--lgs-tint-play) !important;
|
||
box-shadow: inset 0 1.5px 1.5px -1px rgb(255 255 255 / .35), 0 3px 8px rgb(0 0 0 / .22) !important;
|
||
color: var(--lgs-text-on-color) !important;
|
||
--lgs-ill: white;
|
||
& svg { color: var(--lgs-text-on-color); fill: currentColor; }
|
||
}
|
||
/* a destructive action outside a dialog footer (<= 2 per screen): a red
|
||
Semibold label at rest and under the laser; gamepad focus turns it into a
|
||
red whole fill with a dark label and the outer glow (PLAN §1.12) */
|
||
button.DialogButton%{*GamepadDialogContent>Button}.Destructive:not(.Disabled, [disabled]):not(:is(.DialogFooter, %{ModalButtonRow}, .DialogTwoColLayout) *):not([data-lgs-noprim] *) {
|
||
color: var(--lgs-text-danger) !important;
|
||
}
|
||
&:not(.lgs-input-laser) button.DialogButton%{*GamepadDialogContent>Button}.Destructive.gpfocus:not(.Disabled, [disabled]):not(:is(.DialogFooter, %{ModalButtonRow}, .DialogTwoColLayout) *):not([data-lgs-noprim] *) {
|
||
background: var(--lgs-fill-danger) !important;
|
||
color: var(--lgs-text-on-color) !important;
|
||
--lgs-ill: white;
|
||
}
|
||
|
||
/* disabled (CTL §4.7): label white .40, fill white .04, no lip. Steam's
|
||
opacity .4 is lifted so the focus layers are not dimmed; Steam keeps
|
||
disabled buttons focusable, and P4's hook shows disabled + focus */
|
||
button.DialogButton%{*GamepadDialogContent>Button}:is(.Disabled, [disabled]):not([data-lgs-noprim] *) {
|
||
opacity: 1 !important;
|
||
background: rgb(255 255 255 / .04) !important;
|
||
box-shadow: none !important;
|
||
/* .55, not PLAN §1.4's .40: Steam's own disabled label measures 3.8:1,
|
||
and G-AUD forbids less over the bright room (.40 gave 2.9:1; C4a-D11) */
|
||
color: rgb(255 255 255 / .55) !important;
|
||
& svg { opacity: .55; }
|
||
}
|
||
|
||
|
||
/* ======================================================================
|
||
2. Rows and platters: G>Field, non-Classic (CTL §10, §4.3)
|
||
Rows with Background form one platter (black .14, radius 30) of
|
||
contiguous 80 px rows; the lit pill is inset 6 (P4's `row` hook, drawn
|
||
under the content); a 2 px separator inset 26 sits between rows and hides
|
||
next to a lit row. Classic rows (desktop, Quick Access) are left to their
|
||
areas.
|
||
====================================================================== */
|
||
|
||
%{*GamepadDialogContent>Field}:not(%{*GamepadDialogContent>Classic}):not([data-lgs-noprim] *) {
|
||
box-sizing: border-box;
|
||
min-height: var(--lgs-row-platter);
|
||
padding-block: 10px;
|
||
padding-inline: calc(var(--lgs-sep-inset) + var(--indent-level, 0) * 20px) var(--lgs-sep-inset);
|
||
color: var(--lgs-text-1);
|
||
isolation: isolate;
|
||
--lgs-ill: row;
|
||
--lgs-ill-z: -1;
|
||
& %{*GamepadDialogContent>FieldLabel} {
|
||
font: var(--lgs-type-body);
|
||
color: var(--lgs-text-1);
|
||
}
|
||
& %{*GamepadDialogContent>FieldDescription} {
|
||
font: var(--lgs-type-subhead);
|
||
color: var(--lgs-text-2);
|
||
margin-top: 4px;
|
||
}
|
||
& %{*GamepadDialogContent>LabelFieldValue} {
|
||
font: var(--lgs-type-callout);
|
||
color: var(--lgs-text-2);
|
||
}
|
||
& %{*GamepadDialogContent>FieldIcon} {
|
||
color: var(--lgs-text-1);
|
||
}
|
||
/* the label column keeps at least 30 % of the row next to a long value */
|
||
& > %{*GamepadDialogContent>FieldLeftColumn} {
|
||
min-width: 30%;
|
||
}
|
||
/* controls below the label (Below layouts, sliders) keep 10 px clear of the
|
||
label and the note, so their 80 px hit box stays theirs (P-08) */
|
||
& > %{*GamepadDialogContent>FieldLeftColumn} > %{*GamepadDialogContent>FieldChildrenWithIcon} {
|
||
margin-block: 10px;
|
||
}
|
||
/* plain value text in the control column: Callout 22, text-2 (CTL §10) */
|
||
& %{*GamepadDialogContent>FieldChildrenInner} > div:not([class]) {
|
||
font: var(--lgs-type-callout);
|
||
color: var(--lgs-text-2) !important;
|
||
}
|
||
}
|
||
|
||
/* the control column sits on the row's centre line, like the label */
|
||
%{*GamepadDialogContent>Field}%{*GamepadDialogContent>VerticalAlignCenter}:not(%{*GamepadDialogContent>Classic}):not([data-lgs-noprim] *) > %{*GamepadDialogContent>FieldRightColumn} {
|
||
align-self: center;
|
||
}
|
||
|
||
/* the platter: consecutive rows with Background, contiguous */
|
||
%{*GamepadDialogContent>Field}%{*GamepadDialogContent>Background}:not(%{*GamepadDialogContent>Classic}):not([data-lgs-noprim] *) {
|
||
background: var(--lgs-fill-regular);
|
||
border-radius: 0;
|
||
}
|
||
%{*GamepadDialogContent>Field}%{*GamepadDialogContent>Background}:not(%{*GamepadDialogContent>Classic}) + %{*GamepadDialogContent>Field}%{*GamepadDialogContent>Background}:not(%{*GamepadDialogContent>Classic}):not([data-lgs-noprim] *) {
|
||
margin-top: 0;
|
||
}
|
||
/* first row of a run */
|
||
:not(%{*GamepadDialogContent>Field}%{*GamepadDialogContent>Background}) + %{*GamepadDialogContent>Field}%{*GamepadDialogContent>Background}:not(%{*GamepadDialogContent>Classic}):not([data-lgs-noprim] *),
|
||
%{*GamepadDialogContent>Field}%{*GamepadDialogContent>Background}:not(%{*GamepadDialogContent>Classic}):first-child:not([data-lgs-noprim] *) {
|
||
border-start-start-radius: var(--lgs-r-platter);
|
||
border-start-end-radius: var(--lgs-r-platter);
|
||
}
|
||
/* last row of a run */
|
||
%{*GamepadDialogContent>Field}%{*GamepadDialogContent>Background}:not(%{*GamepadDialogContent>Classic}):not(:has(+ %{*GamepadDialogContent>Field}%{*GamepadDialogContent>Background})):not([data-lgs-noprim] *) {
|
||
border-end-start-radius: var(--lgs-r-platter);
|
||
border-end-end-radius: var(--lgs-r-platter);
|
||
}
|
||
/* separators: 2 px white .08, inset 26, on the top edge of a following row */
|
||
%{*GamepadDialogContent>Field}%{*GamepadDialogContent>Background}:not(%{*GamepadDialogContent>Classic}) + %{*GamepadDialogContent>Field}%{*GamepadDialogContent>Background}:not(%{*GamepadDialogContent>Classic}):not([data-lgs-noprim] *)::before {
|
||
content: "";
|
||
position: absolute;
|
||
top: -1px;
|
||
inset-inline: var(--lgs-sep-inset);
|
||
height: 2px;
|
||
border-radius: 1px;
|
||
background: var(--lgs-separator);
|
||
pointer-events: none;
|
||
transition: opacity var(--lgs-d-fade) var(--lgs-ease-b0);
|
||
}
|
||
/* hidden on both sides of a lit row (laser hover, gamepad focus) */
|
||
&:not(.lgs-input-pad) %{*GamepadDialogContent>Field}%{*GamepadDialogContent>Background}:hover::before,
|
||
&:not(.lgs-input-pad) %{*GamepadDialogContent>Field}%{*GamepadDialogContent>Background}:hover + %{*GamepadDialogContent>Field}::before,
|
||
&:not(.lgs-input-laser) %{*GamepadDialogContent>Field}%{*GamepadDialogContent>Background}:is(.gpfocus, .gpfocuswithin)::before,
|
||
&:not(.lgs-input-laser) %{*GamepadDialogContent>Field}%{*GamepadDialogContent>Background}:is(.gpfocus, .gpfocuswithin) + %{*GamepadDialogContent>Field}::before {
|
||
opacity: 0;
|
||
}
|
||
|
||
/* Steam's focus fill is a `forwards` animation on the row: back to rest */
|
||
%{*GamepadDialogContent>Field}:not(%{*GamepadDialogContent>Classic})%{*GamepadDialogContent>HighlightOnFocus}:is(.gpfocus, .gpfocuswithin):not([data-lgs-noprim] *) {
|
||
background: transparent !important;
|
||
color: var(--lgs-text-1) !important;
|
||
}
|
||
%{*GamepadDialogContent>Field}%{*GamepadDialogContent>Background}:not(%{*GamepadDialogContent>Classic})%{*GamepadDialogContent>HighlightOnFocus}:is(.gpfocus, .gpfocuswithin):not([data-lgs-noprim] *) {
|
||
background: var(--lgs-fill-regular) !important;
|
||
}
|
||
|
||
/* Focus inside a row (CTL C-D14). Steam focuses the control and marks the
|
||
row .gpfocuswithin. A single-control row carries the focus (+ the full
|
||
focus light, its arc, the 60 % first frame) and its control is "lifted"
|
||
(a partial light, below); a multi-control row only warms (P4's row hook,
|
||
.06) and its control carries the focus. T2 tags rows data-lgs-ctl="1|n";
|
||
without the tag, rows holding Steam's toggle pairs or check columns are
|
||
multi-control. */
|
||
&:not(.lgs-input-laser) %{*GamepadDialogContent>Field}:not(%{*GamepadDialogContent>Classic}).gpfocuswithin:not([data-lgs-ctl="n"]):not(:has(%{SettingTogglesCtn}, %{Toggles})):not([data-lgs-noprim] *) {
|
||
--lgs-focus: 1;
|
||
&::after {
|
||
animation: lgs-focus-in var(--lgs-ill-d-in) var(--lgs-ill-ease) backwards;
|
||
}
|
||
/* the lifted control: + .10 of light and its own arc instead of the full
|
||
focus look, so one thing is lit, not two (VP P-13); a slider is lifted
|
||
by its knob alone */
|
||
& button.DialogButton%{*GamepadDialogContent>Button}.gpfocus,
|
||
& %{*GamepadDialogContent>Toggle}.gpfocus > %{*GamepadDialogContent>ToggleRail} {
|
||
--lgs-focus: calc(.10 / var(--lgs-focus-add));
|
||
}
|
||
& :is(%{*SliderControlAndNotches>SliderControlPanelGroup}, %{*SliderControlPanelGroup>SliderControlAndNotches}).gpfocus %{*SliderControlPanelGroup>SliderTrack} {
|
||
--lgs-focus: 0;
|
||
}
|
||
}
|
||
|
||
/* laser: when the pointer is on the control inside a row, the control is
|
||
the one lit thing; the row lights only while the pointer is elsewhere on
|
||
it (VP P-13; the row light under a translucent control doubled the hover
|
||
to +42 L, over VP P-03's +25) */
|
||
&:not(.lgs-input-pad) %{*GamepadDialogContent>Field}:not(%{*GamepadDialogContent>Classic}):has(:is(button.DialogButton, %{*GamepadDialogContent>Toggle}, %{*SliderControlAndNotches>SliderControlPanelGroup}, .DialogCheckbox, input, textarea, %{Group>Button}):hover):not([data-lgs-noprim] *) {
|
||
--lgs-hover: 0;
|
||
}
|
||
|
||
/* disabled rows: content at 40 % (CTL §4.7) */
|
||
%{*GamepadDialogContent>Field}%{*GamepadDialogContent>Disabled}:not(%{*GamepadDialogContent>Classic}):not([data-lgs-noprim] *) {
|
||
& :is(%{*GamepadDialogContent>FieldLabel}, %{*GamepadDialogContent>FieldDescription}, %{*GamepadDialogContent>LabelFieldValue}, %{*GamepadDialogContent>FieldIcon}) {
|
||
color: rgb(255 255 255 / var(--lgs-dis-content));
|
||
}
|
||
}
|
||
/* P3 tags a focused disabled control; its row shows disabled + focus */
|
||
%{*GamepadDialogContent>Field}:not(%{*GamepadDialogContent>Classic}):has(.lgs-focus-disabled):not([data-lgs-noprim] *) {
|
||
--lgs-dis: 1;
|
||
}
|
||
|
||
/* section headers above a platter: 22 px Semibold, text-2, title case */
|
||
.SettingsDialogSubHeader:not([data-lgs-noprim] *) {
|
||
font-size: var(--lgs-fs-callout);
|
||
font-weight: 600;
|
||
line-height: 1.3;
|
||
padding-block: 4px 12px;
|
||
padding-inline-start: var(--lgs-sep-inset);
|
||
color: var(--lgs-text-2);
|
||
text-transform: none;
|
||
letter-spacing: 0;
|
||
}
|
||
|
||
/* free text between platters ("Flash window when I receive…") and the
|
||
small explanatory notes: Subhead 20 and Footnote 18, text-2 (VP P-38) */
|
||
%{SettingsDialogBodyText}:not([data-lgs-noprim] *) {
|
||
font: var(--lgs-type-subhead);
|
||
color: var(--lgs-text-2);
|
||
}
|
||
%{SettingsDialogDescriptionText}:not([data-lgs-noprim] *) {
|
||
font: var(--lgs-type-footnote);
|
||
color: var(--lgs-text-2);
|
||
}
|
||
|
||
/* a standalone separator: the row separator */
|
||
%{*GamepadDialogContent>StandaloneFieldSeparator} {
|
||
height: 2px;
|
||
background: var(--lgs-separator);
|
||
margin-inline: var(--lgs-sep-inset);
|
||
}
|
||
|
||
|
||
/* ======================================================================
|
||
3. Switches: G>Toggle > ToggleRail (+ Steam's ::before on-fill) +
|
||
ToggleSwitch (CTL §6.1). scale 1.75 → 66.5 x 38.5 (visionOS 51 x 31 pt);
|
||
the transparent ::before extender (-12px -6px before scaling) makes the
|
||
hit 87.5 x 80.5 (E-SWITCH, P-C3). Steam's transforms (knob position, fill
|
||
position) are never touched; only their timing and colours change.
|
||
The light layer lives on the rail's ::after (above the green fill, under
|
||
the knob), fed with the switch's state numbers.
|
||
====================================================================== */
|
||
|
||
%{*GamepadDialogContent>Toggle}:not([data-lgs-noprim] *) {
|
||
scale: 1.75;
|
||
margin: 8px 14px;
|
||
border-radius: 11px;
|
||
box-shadow: none !important;
|
||
transition: box-shadow var(--lgs-d-fade) var(--lgs-ease-b0);
|
||
&:dir(rtl) { scale: -1.75 1.75; }
|
||
/* the hit extender (free pseudo-element, P-C3) */
|
||
&::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: -12px -6px;
|
||
border-radius: 16px;
|
||
}
|
||
/* Steam's grey focus halo becomes the rail light (below) */
|
||
&::after {
|
||
content: none !important;
|
||
}
|
||
}
|
||
%{*GamepadDialogContent>Toggle}:not([data-lgs-noprim] *) > %{*GamepadDialogContent>ToggleRail} {
|
||
background: rgb(255 255 255 / .16);
|
||
box-shadow: inset 0 .6px 1.7px rgb(0 0 0 / .22);
|
||
--lgs-ill: raised;
|
||
--lgs-ill-r: 11px;
|
||
&::before {
|
||
/* Steam's on-fill: visionOS green with a top sheen, cross-fading at t50
|
||
(MO §4.15); off, it is gone so no sliver shows around the knob */
|
||
background: linear-gradient(180deg, rgb(255 255 255 / .14), rgb(255 255 255 / 0) 60%), var(--lgs-toggle-on) !important;
|
||
opacity: 0;
|
||
transition: opacity var(--lgs-d-interactive) linear var(--lgs-d-interactive), transform var(--lgs-d-snappy) var(--lgs-ease-b15) !important;
|
||
}
|
||
}
|
||
%{*GamepadDialogContent>Toggle}%{*GamepadDialogContent>On}:not([data-lgs-noprim] *) > %{*GamepadDialogContent>ToggleRail}::before {
|
||
opacity: 1;
|
||
}
|
||
/* the knob: a white disc drawn ~3 px inside the track (a gradient, not
|
||
`scale`: Steam positions the knob with `transform`, and an independent
|
||
scale would scale that offset too); its shadow follows the disc
|
||
(drop-shadow). Travel on `snappy` instead of Steam's overshoot */
|
||
%{*GamepadDialogContent>Toggle}:not([data-lgs-noprim] *) > %{*GamepadDialogContent>ToggleSwitch} {
|
||
--lgs-c4a-knob: #fff;
|
||
background: radial-gradient(circle closest-side, var(--lgs-c4a-knob) calc(100% - 1.8px), rgb(255 255 255 / 0) calc(100% - 1.1px)) !important;
|
||
border: 0 !important;
|
||
margin: 0 !important;
|
||
box-shadow: none;
|
||
filter: drop-shadow(0 1.1px 1.4px rgb(0 0 0 / .32));
|
||
transition: transform var(--lgs-d-snappy) var(--lgs-ease-b15), box-shadow var(--lgs-d-fade) var(--lgs-ease-b0) !important;
|
||
}
|
||
/* press: the knob lifts into clear glass (P5's keyframe swells it; the
|
||
disc turns to white .5 glass while pressed; the laser's :active, gamepad A
|
||
through C4a's T2 trigger class) */
|
||
%{*GamepadDialogContent>Toggle}:is(:active, .lgs-knob-lift):not(%{*GamepadDialogContent>Disabled}):not([data-lgs-noprim] *) > %{*GamepadDialogContent>ToggleSwitch} {
|
||
--lgs-c4a-knob: rgb(255 255 255 / .5);
|
||
animation: lgs-knob-lift var(--lgs-d-snappy) linear;
|
||
}
|
||
|
||
/* the switch's state numbers, carried to the rail's light layer */
|
||
&:not(.lgs-input-pad) %{*GamepadDialogContent>Toggle}:hover:not([data-lgs-noprim] *) > %{*GamepadDialogContent>ToggleRail} { --lgs-hover: 1; }
|
||
&:not(.lgs-input-laser) %{*GamepadDialogContent>Toggle}.gpfocus:not([data-lgs-noprim] *) > %{*GamepadDialogContent>ToggleRail} {
|
||
--lgs-focus: 1;
|
||
&::after {
|
||
transition: --lgs-hover var(--lgs-ill-d-in) var(--lgs-ill-ease), --lgs-focus 0s, --lgs-press var(--lgs-ill-d-press) var(--lgs-ill-ease-press);
|
||
animation: lgs-focus-in var(--lgs-ill-d-in) var(--lgs-ill-ease) backwards;
|
||
}
|
||
}
|
||
& %{*GamepadDialogContent>Toggle}:is(:active, .lgs-pressed):not([data-lgs-noprim] *) > %{*GamepadDialogContent>ToggleRail} { --lgs-press: 1; }
|
||
& %{*GamepadDialogContent>Toggle}%{*GamepadDialogContent>Disabled}:not([data-lgs-noprim] *) > %{*GamepadDialogContent>ToggleRail} { --lgs-dis: 1; }
|
||
/* gamepad focus: a soft glow on the knob (0 0 14px 3px white .42 after
|
||
scaling) */
|
||
&:not(.lgs-input-laser) %{*GamepadDialogContent>Toggle}.gpfocus:not([data-lgs-noprim] *) > %{*GamepadDialogContent>ToggleSwitch} {
|
||
box-shadow: 0 0 8px 1px rgb(255 255 255 / .42);
|
||
}
|
||
/* on + focus: green cannot get brighter; the outer glow (C-D22), authored
|
||
before scaling (÷ 1.75), and the inner light capped */
|
||
&:not(.lgs-input-laser) %{*GamepadDialogContent>Toggle}%{*GamepadDialogContent>On}.gpfocus:not([data-lgs-noprim] *) {
|
||
box-shadow: 0 0 calc(var(--lgs-white-glow-blur) / 1.75) calc(var(--lgs-white-glow-spread) / 1.75) rgb(255 255 255 / var(--lgs-white-glow-a)) !important;
|
||
& > %{*GamepadDialogContent>ToggleRail} { --lgs-focus: calc(.04 / var(--lgs-focus-add)); }
|
||
}
|
||
|
||
/* disabled (CTL §4.7): track white .07, knob white .42, no shadow */
|
||
%{*GamepadDialogContent>Toggle}%{*GamepadDialogContent>Disabled}:not([data-lgs-noprim] *) {
|
||
opacity: 1 !important;
|
||
& > %{*GamepadDialogContent>ToggleRail} {
|
||
background: rgb(255 255 255 / .07) !important;
|
||
&::before { opacity: 0 !important; }
|
||
}
|
||
& > %{*GamepadDialogContent>ToggleSwitch} {
|
||
--lgs-c4a-knob: rgb(255 255 255 / .42);
|
||
box-shadow: none !important;
|
||
filter: none;
|
||
}
|
||
}
|
||
|
||
|
||
/* ======================================================================
|
||
4. Check circles: .DialogCheckbox (CTL §6.2). scale 1.82 → 40 px circle;
|
||
the ::before extender (-11px before scaling) makes an 80 x 80 hit
|
||
(E-CHECK); cells widen 50 → 80. Off: a shallow well with the "circle"
|
||
symbol (the one spread shadow allowed on a control, C5). On: blue whole
|
||
fill, white check. Focus is P4's FocusRing plate; on a blue fill the
|
||
outer glow with a 12 px spread instead. Values before scaling are ÷ 1.82.
|
||
====================================================================== */
|
||
|
||
.DialogCheckbox:not([data-lgs-noprim] *) {
|
||
position: relative;
|
||
scale: 1.82;
|
||
margin: 9px;
|
||
border-radius: 50%;
|
||
background: rgb(0 0 0 / .22);
|
||
box-shadow: inset 0 0 0 1.4px rgb(255 255 255 / .34), inset 0 1.1px 2.2px rgb(0 0 0 / .30);
|
||
isolation: isolate;
|
||
--lgs-ill: raised;
|
||
--lgs-ill-z: -1;
|
||
--lgs-ill-r: 50%;
|
||
--lgs-hover-spot: .07;
|
||
transition: background-color var(--lgs-d-fade) var(--lgs-ease-b0);
|
||
&::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: -11px;
|
||
border-radius: 50%;
|
||
}
|
||
}
|
||
.DialogCheckbox.Active:not([data-lgs-noprim] *) {
|
||
background: linear-gradient(180deg, rgb(255 255 255 / .16), rgb(255 255 255 / 0) 60%), var(--lgs-check-on);
|
||
box-shadow: inset 0 .8px .8px -.5px rgb(255 255 255 / .35), 0 .5px 1.1px rgb(0 0 0 / .18);
|
||
--lgs-ill: white;
|
||
--lgs-white-glow-blur: calc(22px / 1.82);
|
||
--lgs-white-glow-spread: calc(12px / 1.82);
|
||
& .SVGIcon_DialogCheck path { stroke: #fff; }
|
||
}
|
||
/* Steam's own hover and focus paint (a near-black well) back to rest */
|
||
.DialogCheckbox:not(.Active):not([data-lgs-noprim] *):is(:hover, :focus, .gpfocus),
|
||
.DialogCheckbox_Container:hover .DialogCheckbox:not(.Active):not([data-lgs-noprim] *) {
|
||
background: rgb(0 0 0 / .22) !important;
|
||
}
|
||
.DialogCheckbox.Disabled:not([data-lgs-noprim] *) {
|
||
opacity: 1 !important;
|
||
background: rgb(0 0 0 / .09);
|
||
box-shadow: inset 0 0 0 1.4px rgb(255 255 255 / .14);
|
||
&.Active { background: rgb(0 145 255 / .34); }
|
||
}
|
||
/* the check matrix: 80 px cells and headers (CTL §6.2) */
|
||
%{CheckboxColumn}:not([data-lgs-noprim] *) {
|
||
width: var(--lgs-hit);
|
||
min-width: var(--lgs-hit);
|
||
flex: 0 0 var(--lgs-hit);
|
||
justify-content: center;
|
||
}
|
||
%{CheckboxHeaders} %{CheckboxColumn} {
|
||
font: var(--lgs-type-caption);
|
||
color: var(--lgs-text-1);
|
||
text-transform: none;
|
||
text-align: center;
|
||
}
|
||
%{CheckboxHeaders} %{NotifyViaHeader} {
|
||
font: var(--lgs-type-subhead);
|
||
font-style: normal;
|
||
color: var(--lgs-text-2);
|
||
}
|
||
|
||
|
||
/* ======================================================================
|
||
5. Sliders (CTL §7). A 64 px recessed capsule; Steam's handle widened to
|
||
64 (knob centre = value, P-C2); our white fill from Steam's origin to the
|
||
value on the track's free ::after, invisible at |v - o| = 0; the knob a
|
||
58 px white disc on the handle's free ::after, shown on hover, focus and
|
||
drag and always on stepped sliders; notch cells 64 px and the default
|
||
tick 20 px in (P-C8). The light layer is painted into the track's own
|
||
background, under the fill. Steam's inline variables, the handle
|
||
container's transform and the ::before fill geometry are untouched.
|
||
====================================================================== */
|
||
|
||
:is(%{*SliderControlPanelGroup>SliderControlAndNotches}, %{*SliderControlPanelGroup>SliderControl}):not([data-lgs-noprim] *) {
|
||
--slider-handle-width: var(--lgs-slider);
|
||
}
|
||
%{*SliderControlAndNotches>SliderControlPanelGroup}:not([data-lgs-noprim] *) {
|
||
padding-block: 8px;
|
||
}
|
||
%{*SliderControlPanelGroup>SliderControl}:not([data-lgs-noprim] *) {
|
||
height: var(--lgs-slider);
|
||
}
|
||
%{*SliderControlPanelGroup>SliderTrack}:not([data-lgs-noprim] *) {
|
||
height: var(--lgs-slider);
|
||
border-radius: calc(var(--lgs-slider) / 2);
|
||
--left-track-color: transparent;
|
||
--default-value-track-color: transparent;
|
||
box-shadow: var(--lgs-recessed-shadow), inset 0 -2px 3px -1px rgb(255 255 255 / .10);
|
||
background:
|
||
radial-gradient(circle at var(--hx, 50%) var(--hy, 30%),
|
||
rgb(255 255 255 / calc(var(--lgs-hover-spot) * var(--lgs-hover) * (1 - var(--lgs-dis)))) 0, rgb(255 255 255 / 0) 75%),
|
||
radial-gradient(circle at 50% 30%,
|
||
rgb(255 255 255 / calc(var(--lgs-focus-spot) * var(--lgs-focus) * (1 - var(--lgs-dis)))) 0, rgb(255 255 255 / 0) 75%),
|
||
linear-gradient(
|
||
rgb(255 255 255 / calc(var(--lgs-hover-add) * var(--lgs-hover) * (1 - var(--lgs-dis)) + var(--lgs-focus-add) * var(--lgs-focus) * (1 - var(--lgs-dis)) + var(--lgs-dis-focus-add) * var(--lgs-focus) * var(--lgs-dis))),
|
||
rgb(255 255 255 / calc(var(--lgs-hover-add) * var(--lgs-hover) * (1 - var(--lgs-dis)) + var(--lgs-focus-add) * var(--lgs-focus) * (1 - var(--lgs-dis)) + var(--lgs-dis-focus-add) * var(--lgs-focus) * var(--lgs-dis)))),
|
||
var(--lgs-fill-thick);
|
||
transition:
|
||
--lgs-hover var(--lgs-ill-d-out) var(--lgs-ill-ease),
|
||
--lgs-focus var(--lgs-ill-d-out) var(--lgs-ill-ease);
|
||
/* Steam's own fill stays (geometry), colourless */
|
||
&::before {
|
||
background-color: transparent !important;
|
||
background-image: none !important;
|
||
}
|
||
/* our fill: from min(origin, value) to max(origin, value), the knob's
|
||
width included, so it ends under the knob's far edge */
|
||
&::after {
|
||
content: "";
|
||
position: absolute;
|
||
top: 0;
|
||
bottom: 0;
|
||
inset-inline-start: calc(min(var(--normalized-slider-origin, 0), var(--normalized-slider-value, 0)) * (100% - var(--slider-handle-width)));
|
||
width: calc(var(--slider-handle-width) + (max(var(--normalized-slider-origin, 0), var(--normalized-slider-value, 0)) - min(var(--normalized-slider-origin, 0), var(--normalized-slider-value, 0))) * (100% - var(--slider-handle-width)));
|
||
border-radius: inherit;
|
||
background: linear-gradient(180deg, rgb(255 255 255 / .92), rgb(255 255 255 / .84));
|
||
opacity: clamp(0, max(var(--normalized-slider-value, 0) - var(--normalized-slider-origin, 0), var(--normalized-slider-origin, 0) - var(--normalized-slider-value, 0)) * 40, 1);
|
||
pointer-events: none;
|
||
}
|
||
}
|
||
/* the slider's state numbers on its track (light layer above) */
|
||
&:not(.lgs-input-pad) %{*SliderControlAndNotches>SliderControlPanelGroup}:hover %{*SliderControlPanelGroup>SliderTrack}:not([data-lgs-noprim] *) {
|
||
--lgs-hover: 1;
|
||
transition: --lgs-hover var(--lgs-ill-d-in) var(--lgs-ill-ease), --lgs-focus var(--lgs-ill-d-out) var(--lgs-ill-ease);
|
||
}
|
||
&:not(.lgs-input-laser) :is(%{*SliderControlAndNotches>SliderControlPanelGroup}, %{*SliderControlPanelGroup>SliderControlAndNotches}).gpfocus %{*SliderControlPanelGroup>SliderTrack}:not([data-lgs-noprim] *) {
|
||
--lgs-focus: 1;
|
||
transition: --lgs-hover var(--lgs-ill-d-in) var(--lgs-ill-ease), --lgs-focus 0s;
|
||
}
|
||
& %{*SliderControlPanelGroup>SliderControlAndNotches}%{*SliderControlPanelGroup>Disabled} %{*SliderControlPanelGroup>SliderTrack}:not([data-lgs-noprim] *) {
|
||
--lgs-dis: 1;
|
||
&::after { background: rgb(255 255 255 / .30); }
|
||
}
|
||
/* stepped sliders: the fill ends at the knob's centre (R5) */
|
||
%{*SliderControlPanelGroup>SliderControlAndNotches}:has(%{*SliderControlPanelGroup>SliderNotchContainer}) %{*SliderControlPanelGroup>SliderTrack}:not([data-lgs-noprim] *)::after {
|
||
width: calc(var(--slider-handle-width) / 2 + (max(var(--normalized-slider-origin, 0), var(--normalized-slider-value, 0)) - min(var(--normalized-slider-origin, 0), var(--normalized-slider-value, 0))) * (100% - var(--slider-handle-width)));
|
||
}
|
||
/* two-colour range sliders: Steam's own fill kept, recoloured (CTL §7.2) */
|
||
%{*SliderControlPanelGroup>DefaultValueIsColorRange} %{*SliderControlPanelGroup>SliderTrack}:not([data-lgs-noprim] *),
|
||
%{*SliderControlPanelGroup>SliderTrack}%{*SliderControlPanelGroup>DefaultValueIsColorRange}:not([data-lgs-noprim] *) {
|
||
--left-track-color: rgb(255 255 255 / .86);
|
||
--default-value-track-color: rgb(255 255 255 / .40);
|
||
&::before { background-color: var(--left-track-color) !important; background-image: revert !important; }
|
||
&::after { content: none; }
|
||
}
|
||
|
||
/* the knob: Steam's 64 x 64 handle, transparent; a 58 px white disc on its
|
||
::after, shown on hover, focus, drag and in a focused row */
|
||
%{*SliderControlPanelGroup>SliderHandle}:not([data-lgs-noprim] *) {
|
||
/* Steam positions it (absolute, at its container's end): never touched */
|
||
width: var(--slider-handle-width);
|
||
height: var(--slider-handle-width);
|
||
background: transparent !important;
|
||
box-shadow: none !important;
|
||
border: 0 !important;
|
||
margin: 0 !important;
|
||
animation: none !important;
|
||
&::after {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 3px;
|
||
border-radius: 50%;
|
||
background: #fff;
|
||
box-shadow: 0 2px 8px rgb(0 0 0 / .32);
|
||
opacity: 0;
|
||
pointer-events: none;
|
||
transition:
|
||
opacity var(--lgs-d-fade) var(--lgs-ease-b0),
|
||
scale var(--lgs-d-snappy) var(--lgs-ease-b15);
|
||
}
|
||
}
|
||
&:not(.lgs-input-pad) %{*SliderControlAndNotches>SliderControlPanelGroup}:hover %{*SliderControlPanelGroup>SliderHandle}:not([data-lgs-noprim] *)::after,
|
||
&:not(.lgs-input-laser) :is(%{*SliderControlAndNotches>SliderControlPanelGroup}, %{*SliderControlPanelGroup>SliderControlAndNotches}).gpfocus %{*SliderControlPanelGroup>SliderHandle}:not([data-lgs-noprim] *)::after,
|
||
&:not(.lgs-input-laser) %{*GamepadDialogContent>Field}.gpfocuswithin %{*SliderControlPanelGroup>SliderHandle}:not([data-lgs-noprim] *)::after,
|
||
& %{*SliderControlAndNotches>SliderControlPanelGroup}:active %{*SliderControlPanelGroup>SliderHandle}:not([data-lgs-noprim] *)::after,
|
||
& %{*SliderControlPanelGroup>SliderControlAndNotches}:has(%{*SliderControlPanelGroup>SliderNotchContainer}) %{*SliderControlPanelGroup>SliderHandle}:not([data-lgs-noprim] *)::after {
|
||
opacity: 1;
|
||
transition:
|
||
opacity var(--lgs-d-hover-in) var(--lgs-ease-b0),
|
||
scale var(--lgs-d-interactive) var(--lgs-ease-b15);
|
||
}
|
||
/* stepped: a 50 px disc with a stronger shadow */
|
||
%{*SliderControlPanelGroup>SliderControlAndNotches}:has(%{*SliderControlPanelGroup>SliderNotchContainer}) %{*SliderControlPanelGroup>SliderHandle}:not([data-lgs-noprim] *)::after {
|
||
inset: 7px;
|
||
box-shadow: 0 2px 8px rgb(0 0 0 / .38);
|
||
}
|
||
/* drag: the knob grows x1.25 as a bead of clear glass */
|
||
& %{*SliderControlAndNotches>SliderControlPanelGroup}:active %{*SliderControlPanelGroup>SliderHandle}:not([data-lgs-noprim] *)::after {
|
||
scale: 1.25;
|
||
background: radial-gradient(circle at 50% 30%, rgb(255 255 255 / .30), rgb(255 255 255 / .04) 70%);
|
||
backdrop-filter: blur(2px) saturate(1.8) brightness(.86);
|
||
box-shadow: 0 6px 16px rgb(0 0 0 / .30), inset 0 1.5px 1.5px -1px rgb(255 255 255 / .55);
|
||
}
|
||
/* disabled: the knob dimmed */
|
||
%{*SliderControlPanelGroup>SliderControlAndNotches}%{*SliderControlPanelGroup>Disabled} %{*SliderControlPanelGroup>SliderHandle}:not([data-lgs-noprim] *)::after {
|
||
background: rgb(255 255 255 / .45);
|
||
box-shadow: none;
|
||
}
|
||
|
||
/* notches: 64 px cells so every tick sits at its value (P-C8); ticks
|
||
become 8 px dots, labels 18 px Semibold title case (CTL §7.3) */
|
||
%{*SliderControlPanelGroup>SliderNotch}:not([data-lgs-noprim] *) {
|
||
width: var(--slider-handle-width);
|
||
min-width: var(--slider-handle-width);
|
||
flex-basis: var(--slider-handle-width);
|
||
}
|
||
/* the notch row rises into the track so its 8 px dots sit on the track's
|
||
centre line, above the fill and under the knob; its labels sit below the
|
||
track. Steam's notch row is a focus scope with no click handler of its
|
||
own (probed 2026-10-07: onContextMenu only), so a press on it still
|
||
reaches the slider group; 80 tall, so its own hit box is all its own
|
||
(P-80, P-08) */
|
||
%{*SliderControlPanelGroup>SliderNotchContainer}:not([data-lgs-noprim] *) {
|
||
position: relative;
|
||
z-index: 1;
|
||
box-sizing: border-box;
|
||
min-height: var(--lgs-hit);
|
||
margin-top: calc(-1 * var(--lgs-slider) / 2 - 4px);
|
||
}
|
||
%{*SliderControlPanelGroup>SliderHandleContainer}:not([data-lgs-noprim] *) {
|
||
z-index: 2;
|
||
}
|
||
%{*SliderControlPanelGroup>SliderNotchTick}:not([data-lgs-noprim] *) {
|
||
width: 8px;
|
||
height: 8px;
|
||
border-radius: 50%;
|
||
background-color: rgb(255 255 255 / .42);
|
||
}
|
||
%{*SliderControlPanelGroup>SliderNotchTick}%{*SliderControlPanelGroup>TickActive}:not([data-lgs-noprim] *) {
|
||
background-color: rgb(13 14 18 / .28);
|
||
}
|
||
%{*SliderControlPanelGroup>SliderNotchLabel}:not([data-lgs-noprim] *) {
|
||
font: 600 var(--lgs-fs-footnote)/1.2 var(--lgs-font);
|
||
text-transform: none;
|
||
letter-spacing: 0;
|
||
color: var(--lgs-text-2);
|
||
padding-top: calc(var(--lgs-slider) / 2 + 12px);
|
||
}
|
||
%{*SliderControlPanelGroup>SliderNotchTick} + %{*SliderControlPanelGroup>SliderNotchLabel}:not([data-lgs-noprim] *) {
|
||
padding-top: calc(var(--lgs-slider) / 2 + 4px);
|
||
}
|
||
/* the default-value tick: back on its value with the 64 px handle (P-C8) */
|
||
%{*SliderControlPanelGroup>DefaultValueTick}:not([data-lgs-noprim] *) {
|
||
inset-inline-end: calc((var(--slider-handle-width) - 24px) / 2);
|
||
& > svg { color: rgb(255 255 255 / .72); }
|
||
}
|
||
/* T2 (wp.c4a): a full-width slider whose row shows no value gets it as
|
||
decorative text in a 72 px trailing column (CTL §7.2; --lgs-c4a-val is
|
||
written by device/rt/10-controls.js, never focusable or clickable) */
|
||
%{*SliderControlAndNotches>SliderControlPanelGroup}[data-lgs-val]:not([data-lgs-noprim] *) {
|
||
position: relative;
|
||
padding-inline-end: 84px;
|
||
&::after {
|
||
content: var(--lgs-c4a-val, "");
|
||
position: absolute;
|
||
inset-inline-end: 0;
|
||
top: calc(8px + var(--lgs-slider) / 2);
|
||
translate: 0 -50%;
|
||
width: 72px;
|
||
text-align: end;
|
||
font: 600 var(--lgs-fs-callout)/1.3 var(--lgs-font);
|
||
font-variant-numeric: tabular-nums;
|
||
color: var(--lgs-text-2);
|
||
pointer-events: none;
|
||
}
|
||
}
|
||
/* value text and the value box */
|
||
%{*SliderControlPanelGroup>DescriptionValue}:not([data-lgs-noprim] *) {
|
||
font: 600 var(--lgs-fs-callout)/1.3 var(--lgs-font);
|
||
font-variant-numeric: tabular-nums;
|
||
color: var(--lgs-text-2);
|
||
}
|
||
%{*SliderControlPanelGroup>EditableValue}:not([data-lgs-noprim] *) {
|
||
box-sizing: border-box;
|
||
min-height: var(--lgs-btn);
|
||
min-width: 96px;
|
||
padding: 0 20px;
|
||
border: 0;
|
||
border-radius: var(--lgs-r-capsule);
|
||
font: 600 var(--lgs-fs-callout)/1.3 var(--lgs-font);
|
||
font-variant-numeric: tabular-nums;
|
||
background: var(--lgs-fill-thick) !important;
|
||
box-shadow: var(--lgs-recessed-shadow) !important;
|
||
color: var(--lgs-text-1) !important;
|
||
caret-color: var(--lgs-blue);
|
||
}
|
||
&:not(.lgs-input-laser) %{*SliderControlPanelGroup>EditableValue}.gpfocus:not([data-lgs-noprim] *),
|
||
& %{*SliderControlPanelGroup>EditableValue}:focus:not([data-lgs-noprim] *) {
|
||
box-shadow: var(--lgs-recessed-shadow), var(--lgs-field-focus) !important;
|
||
}
|
||
/* the inert glyph before a slider (speaker, sun): drawn inside the fill's
|
||
leading end; the difference blend makes it dark on the white fill and
|
||
light on the bare track, so level 0 still reads (C-D13). Never a target */
|
||
%{*GamepadDialogContent>FieldChildrenWithIcon}:has(%{*SliderControlAndNotches>SliderControlPanelGroup}):not([data-lgs-noprim] *) > %{*GamepadDialogContent>FieldIcon}:not(%{ClickableSliderIcon}, :has(%{ClickableSliderIcon})) {
|
||
position: relative;
|
||
z-index: 1;
|
||
box-sizing: border-box;
|
||
width: var(--lgs-slider);
|
||
min-width: var(--lgs-slider);
|
||
margin-inline-end: calc(-1 * var(--lgs-slider));
|
||
padding: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
color: #fff;
|
||
mix-blend-mode: difference;
|
||
pointer-events: none;
|
||
& svg { width: 26px; height: 26px; }
|
||
}
|
||
/* the mute glyph (Steam's clickable slider icon, not on this build's pages,
|
||
P-C9) is never inert: its own 64 px round zone before the track, raised,
|
||
lit like a button (CTL C-D13). T2's data-lgs-mute="muted" turns the zone
|
||
white with the dimmed level beside it */
|
||
%{*GamepadDialogContent>FieldChildrenWithIcon}:not([data-lgs-noprim] *) > %{*GamepadDialogContent>FieldIcon}:is(%{ClickableSliderIcon}, :has(%{ClickableSliderIcon})) {
|
||
position: relative;
|
||
box-sizing: border-box;
|
||
width: var(--lgs-slider);
|
||
height: var(--lgs-slider);
|
||
min-width: var(--lgs-slider);
|
||
margin-inline-end: 8px;
|
||
padding: 0;
|
||
display: grid;
|
||
place-items: center;
|
||
border-radius: 50%;
|
||
background: var(--lgs-raised-bg);
|
||
box-shadow: var(--lgs-raised-shadow);
|
||
color: var(--lgs-text-1);
|
||
isolation: isolate;
|
||
--lgs-ill: raised;
|
||
--lgs-ill-z: -1;
|
||
& svg { width: 26px; height: 26px; }
|
||
}
|
||
[data-lgs-mute="muted"] > %{*GamepadDialogContent>FieldIcon} {
|
||
background: var(--lgs-selected-fill) !important;
|
||
color: var(--lgs-text-on-selected) !important;
|
||
--lgs-ill: white;
|
||
}
|
||
[data-lgs-mute="muted"] %{*SliderControlPanelGroup>SliderTrack}::after {
|
||
background: rgb(255 255 255 / .24);
|
||
}
|
||
|
||
|
||
/* ======================================================================
|
||
6. Pop-up buttons: %{DropDownControlButton} (CTL §8.1). A 60 px capsule
|
||
(rich two-line: 76, radius 30) with the value at 22 px Medium and Steam's
|
||
caret; white .94 with dark text while its menu is open. It is also a
|
||
DialogButton, so section 1 gives it the states.
|
||
====================================================================== */
|
||
|
||
button%{DropDownControlButton}.DialogButton:not(%{SortingDropDownControlButton}):not([data-lgs-noprim] *) {
|
||
padding: 0 20px 0 24px;
|
||
font: var(--lgs-type-callout);
|
||
--lgs-c4a-side: 250;
|
||
& %{*GamepadDialogContent>DropDownControlButtonContents} {
|
||
gap: 14px;
|
||
align-items: center;
|
||
}
|
||
& %{*GamepadDialogContent>DropDownControlButtonContents} > svg {
|
||
width: 22px;
|
||
height: 22px;
|
||
color: var(--lgs-text-2);
|
||
}
|
||
& %{DropDownLabelTitle} {
|
||
font: var(--lgs-type-callout);
|
||
color: var(--lgs-text-1);
|
||
}
|
||
& :is(%{DropDownLabelDescription}, %{DropDownLabelUpperDescription}) {
|
||
font: var(--lgs-type-footnote);
|
||
color: var(--lgs-text-2);
|
||
}
|
||
}
|
||
/* rich (two-line) pop-ups: 76 px, radius 30; the title first, then Steam's
|
||
upper description and description joined on one line ("UTC −04:00 ·
|
||
New York", CTL §8.1) by `order` on Steam's own text nodes */
|
||
button%{DropDownControlButton}.DialogButton:has(%{DropDownLabelContainer}):not([data-lgs-noprim] *) {
|
||
min-height: 76px;
|
||
border-radius: 30px;
|
||
& %{DropDownLabelTextColumn} {
|
||
display: flex;
|
||
flex-flow: row wrap;
|
||
justify-content: flex-start;
|
||
align-items: baseline;
|
||
row-gap: 2px;
|
||
}
|
||
& %{DropDownLabelTitle} { order: 0; flex: 1 0 100%; }
|
||
& :is(%{DropDownLabelUpperDescription}, %{DropDownLabelDescription}) { margin-inline: 0; padding-inline: 0; text-indent: 0; }
|
||
& %{DropDownLabelUpperDescription} { order: 1; }
|
||
& %{DropDownLabelUpperDescription}:not(:empty)::after { content: "\00a0\00b7\00a0"; }
|
||
& %{DropDownLabelDescription} { order: 2; }
|
||
}
|
||
/* Game Recording's quality options: Steam dims both parts for its white focus */
|
||
button%{DropDownControlButton}.DialogButton %{BitrateOption} {
|
||
color: var(--lgs-text-2) !important;
|
||
& %{BitrateSetting>Emphasis} { color: var(--lgs-text-1) !important; }
|
||
}
|
||
/* open: the source of an open menu is white (CTL §8.1; tokens §3.3) */
|
||
button%{DropDownControlButton}.DialogButton[aria-expanded="true"]:not([data-lgs-noprim] *) {
|
||
background: var(--lgs-selected-fill) !important;
|
||
box-shadow: 0 2px 6px rgb(0 0 0 / .22) !important;
|
||
color: var(--lgs-text-on-selected) !important;
|
||
--lgs-ill: white;
|
||
& %{*GamepadDialogContent>DropDownControlButtonContents} > svg { color: var(--lgs-text-on-selected-2); }
|
||
& %{DropDownLabelTitle} { color: var(--lgs-text-on-selected); }
|
||
& :is(%{DropDownLabelDescription}, %{DropDownLabelUpperDescription}) { color: var(--lgs-text-on-selected-2); }
|
||
}
|
||
|
||
|
||
/* ======================================================================
|
||
7. Segmented controls: %{Group} (Shared_Radio_Group) (CTL §8.3).
|
||
A 64 px recessed track, padding 2; segments contiguous, 60 tall, ≥ 140
|
||
wide, one-line 22 px Semibold labels; the visible fill inset 2 px; the
|
||
selected segment a white .94 pill with a dark label. Focus is P4's
|
||
FocusRing plate (radios) plus the light layer; Steam's dividers go.
|
||
====================================================================== */
|
||
|
||
%{Group}:not(%{CenteredPill}):not([data-lgs-noprim] *) {
|
||
box-sizing: border-box;
|
||
min-height: var(--lgs-seg);
|
||
padding: 2px;
|
||
gap: 0;
|
||
border-radius: var(--lgs-r-capsule);
|
||
background: var(--lgs-fill-thick);
|
||
box-shadow: var(--lgs-recessed-shadow), inset 0 -2px 3px -1px rgb(255 255 255 / .10);
|
||
color: var(--lgs-text-1);
|
||
& > %{Group>Button} {
|
||
box-sizing: border-box;
|
||
min-height: 60px;
|
||
min-width: var(--lgs-seg-min-w);
|
||
margin: 0;
|
||
padding: 2px 20px;
|
||
background-clip: content-box;
|
||
border-radius: 30px;
|
||
font: 600 var(--lgs-fs-callout)/1.2 var(--lgs-font);
|
||
white-space: nowrap;
|
||
text-shadow: none;
|
||
text-transform: none;
|
||
color: var(--lgs-text-1);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
isolation: isolate;
|
||
--lgs-ill: raised;
|
||
--lgs-ill-z: -1;
|
||
--lgs-ill-inset: 2px;
|
||
--lgs-ill-r: 28px;
|
||
transition: background-color var(--lgs-d-fade) var(--lgs-ease-b0), color var(--lgs-d-swap) linear;
|
||
/* Steam's 1 px dividers */
|
||
&::before { background: transparent !important; }
|
||
}
|
||
/* Steam's hover fill: back to rest (the light layer carries hover) */
|
||
& > %{Group>Button}:not(%{Group>Active}):is(:hover, .gpfocus) {
|
||
background-color: transparent !important;
|
||
}
|
||
& > %{Group>Button}%{Group>Active} {
|
||
background: var(--lgs-selected-fill) !important;
|
||
background-clip: content-box !important;
|
||
color: var(--lgs-text-on-selected) !important;
|
||
--lgs-ill: white;
|
||
}
|
||
}
|
||
%{Group}%{CenteredPill}:not([data-lgs-noprim] *) > %{Group>Button}%{Group>Active} {
|
||
background: var(--lgs-selected-fill);
|
||
color: var(--lgs-text-on-selected);
|
||
}
|
||
/* T2 (wp.c4a): a decorative div.lgs-pill takes over the selected fill and
|
||
travels on `snappy`, clear glass for its first 180 ms (CTL §8.3). Strips
|
||
of other areas registered with rt.controls.pill(el) get the same pill */
|
||
[data-lgs-pill]:not([data-lgs-noprim] *) {
|
||
position: relative;
|
||
}
|
||
%{Group}[data-lgs-pill]:not([data-lgs-noprim] *) {
|
||
& > %{Group>Button} { position: relative; z-index: 1; }
|
||
& > %{Group>Button}%{Group>Active} {
|
||
background: transparent !important;
|
||
box-shadow: none !important;
|
||
}
|
||
}
|
||
& .lgs-pill {
|
||
position: absolute;
|
||
left: 0;
|
||
top: 0;
|
||
z-index: 0;
|
||
pointer-events: none;
|
||
border-radius: 28px;
|
||
background: var(--lgs-selected-fill);
|
||
box-shadow: 0 2px 6px rgb(0 0 0 / .22);
|
||
transition:
|
||
translate var(--lgs-d-snappy) var(--lgs-ease-b15),
|
||
width var(--lgs-d-snappy) var(--lgs-ease-b15),
|
||
scale var(--lgs-d-interactive) var(--lgs-ease-b15),
|
||
background-color var(--lgs-d-interactive) var(--lgs-ease-b0),
|
||
box-shadow var(--lgs-d-interactive) var(--lgs-ease-b0);
|
||
&.lgs-pill-still { transition: none; }
|
||
/* lifted while it travels: a bead of clear glass */
|
||
&.lgs-pill-lift {
|
||
scale: 1.06 1.12;
|
||
background: linear-gradient(180deg, rgb(255 255 255 / .42), rgb(255 255 255 / .18));
|
||
backdrop-filter: blur(1.5px) saturate(1.8);
|
||
box-shadow: 0 4px 12px rgb(0 0 0 / .28), inset 0 1.5px 1.5px -1px rgb(255 255 255 / .55);
|
||
}
|
||
}
|
||
/* Reduce Motion: the pill does not travel or lift; it cross-fades */
|
||
@media (prefers-reduced-motion: reduce) {
|
||
& .lgs-pill {
|
||
transition: none;
|
||
&.lgs-pill-lift { scale: none; backdrop-filter: none; background: var(--lgs-selected-fill); animation: lgs-fade-in var(--lgs-d-reduce, 180ms) linear; }
|
||
}
|
||
}
|
||
|
||
|
||
/* ======================================================================
|
||
8. Text fields (CTL §9). A 64 px recessed capsule (padding 0 12 0 24),
|
||
Body 24 Medium, upright placeholder .55, a blue caret. Focus is the one
|
||
ring in the system (--lgs-field-focus, VP P-17): on gamepad focus, and in
|
||
laser mode while the field has DOM focus (the caret's field), never on
|
||
hover. Steam's solid white focused input is overridden.
|
||
====================================================================== */
|
||
|
||
input%{*GamepadDialogContent>BasicTextInput}:not([data-lgs-noprim] *),
|
||
textarea.DialogTextInputBase:not([data-lgs-noprim] *) {
|
||
box-sizing: border-box;
|
||
min-height: var(--lgs-field);
|
||
padding: 0 12px 0 24px;
|
||
border: 0;
|
||
border-radius: calc(var(--lgs-field) / 2);
|
||
font: var(--lgs-type-body);
|
||
color: var(--lgs-text-1) !important;
|
||
caret-color: var(--lgs-blue);
|
||
background: var(--lgs-fill-thick) !important;
|
||
box-shadow: var(--lgs-recessed-shadow), inset 0 -2px 3px -1px rgb(255 255 255 / .10) !important;
|
||
transition: box-shadow var(--lgs-d-fade) var(--lgs-ease-b0), background-color var(--lgs-d-fade) var(--lgs-ease-b0);
|
||
}
|
||
textarea.DialogTextInputBase:not([data-lgs-noprim] *) {
|
||
padding: 18px 24px;
|
||
border-radius: 30px;
|
||
line-height: 1.3;
|
||
}
|
||
/* a bare textarea placed in a row (Steam's zoo, multi-line notes): the
|
||
multi-line field */
|
||
%{*GamepadDialogContent>FieldChildrenInner} > textarea:not([class*="DialogTextInputBase"]):not([data-lgs-noprim] *) {
|
||
box-sizing: border-box;
|
||
min-height: var(--lgs-field);
|
||
padding: 18px 24px;
|
||
border: 0;
|
||
border-radius: 30px;
|
||
font: var(--lgs-type-body);
|
||
line-height: 1.3;
|
||
color: var(--lgs-text-1);
|
||
caret-color: var(--lgs-blue);
|
||
background: var(--lgs-fill-thick);
|
||
box-shadow: var(--lgs-recessed-shadow), inset 0 -2px 3px -1px rgb(255 255 255 / .10);
|
||
resize: none;
|
||
outline: none;
|
||
&:focus { box-shadow: var(--lgs-recessed-shadow), var(--lgs-field-focus); }
|
||
}
|
||
/* a free-standing field (not in a row) keeps 8 px clear above and below,
|
||
so its 80 px hit box stays its own (P-08) */
|
||
.DialogInput_Wrapper:not(%{*GamepadDialogContent>Field} *):not([data-lgs-noprim] *) {
|
||
padding-block: 8px;
|
||
}
|
||
:is(input%{*GamepadDialogContent>BasicTextInput}, input.DialogTextInputBase, textarea.DialogTextInputBase)::placeholder {
|
||
color: rgb(255 255 255 / .55);
|
||
font-style: normal;
|
||
}
|
||
/* laser hover: a little light on the well */
|
||
&:not(.lgs-input-pad) :is(input%{*GamepadDialogContent>BasicTextInput}, textarea.DialogTextInputBase):hover:not(:focus):not([data-lgs-noprim] *) {
|
||
background: linear-gradient(rgb(255 255 255 / var(--lgs-hover-add)), rgb(255 255 255 / var(--lgs-hover-add))), var(--lgs-fill-thick) !important;
|
||
}
|
||
/* focus: the ring, and only .08 more light so typed text keeps its contrast */
|
||
&:not(.lgs-input-laser) :is(input%{*GamepadDialogContent>BasicTextInput}, textarea.DialogTextInputBase).gpfocus:not([data-lgs-noprim] *),
|
||
& :is(input%{*GamepadDialogContent>BasicTextInput}, textarea.DialogTextInputBase):focus:not([data-lgs-noprim] *) {
|
||
background: linear-gradient(rgb(255 255 255 / .08), rgb(255 255 255 / .08)), var(--lgs-fill-thick) !important;
|
||
box-shadow: var(--lgs-recessed-shadow), var(--lgs-field-focus) !important;
|
||
color: var(--lgs-text-1) !important;
|
||
}
|
||
input%{*GamepadDialogContent>BasicTextInput}:is(:disabled, :read-only, .disabled):not([data-lgs-noprim] *) {
|
||
color: rgb(255 255 255 / var(--lgs-dis-content)) !important;
|
||
}
|
||
&:not(.lgs-input-laser) %{*GamepadDialogContent_InnerWidth>GamepadDialogContent} ._DialogInputContainer.gpfocus,
|
||
& %{*GamepadDialogContent_InnerWidth>GamepadDialogContent} ._DialogInputContainer.Active {
|
||
background-color: var(--lgs-fill-thick) !important;
|
||
box-shadow: var(--lgs-recessed-shadow), var(--lgs-field-focus) !important;
|
||
color: var(--lgs-text-1) !important;
|
||
}
|
||
/* labels above a field: 20 px Semibold, title case */
|
||
.DialogLabel:not([data-lgs-noprim] *) {
|
||
font-size: var(--lgs-fs-subhead);
|
||
font-weight: 600;
|
||
line-height: 1.3;
|
||
text-transform: none;
|
||
letter-spacing: 0;
|
||
color: var(--lgs-text-2);
|
||
}
|
||
|
||
|
||
/* ======================================================================
|
||
9. Progress bars (ProgressBar: downloads, updates, zoo): the slider's
|
||
language, a recessed capsule with a white fill. Steam's indeterminate
|
||
sweep is left as is.
|
||
====================================================================== */
|
||
|
||
/* doubled class: beats Steam's focused-row variant without naming .gpfocus */
|
||
%{ProgressBarIndeterminate>ProgressBar}%{ProgressBarIndeterminate>ProgressBar} {
|
||
background: var(--lgs-fill-thick);
|
||
box-shadow: var(--lgs-recessed-shadow);
|
||
border-radius: var(--lgs-r-capsule);
|
||
/* the fill paints inline "background: var(--gpColor-Blue, #1a9fff)" */
|
||
--gpColor-Blue: rgb(255 255 255 / .92);
|
||
}
|
||
%{ProgressBarIndeterminate>ProgressBar} %{Indeterminate>Percent} {
|
||
border-radius: var(--lgs-r-capsule);
|
||
}
|
||
%{ProgressBarFieldStatus} %{ProgressBar>TextContainer} %{OperationText} {
|
||
color: var(--lgs-text-2);
|
||
}
|
||
|
||
|
||
/* ======================================================================
|
||
10. Labels of C4a's pop-ups inside C1c's menus, and dialog sub-headers.
|
||
The menu slab, rows, scrim and sheets are C1c's (theme/22-presentations.css;
|
||
Phase 1's menu and modal sections were removed here on REQ C1c->C4a,
|
||
PLAN §6). Kept: a rich pop-up's two-line label follows its menu row's
|
||
colour (dark on the white selected row), and Steam's in-page sub-headers.
|
||
====================================================================== */
|
||
|
||
%{*BasicContextMenuModal>contextMenuItem} %{DropDownLabelTitle} {
|
||
color: inherit;
|
||
}
|
||
%{*BasicContextMenuModal>contextMenuItem} :is(%{DropDownLabelDescription}, %{DropDownLabelUpperDescription}) {
|
||
color: inherit;
|
||
opacity: .74;
|
||
}
|
||
:is(.DialogSubHeader, .DialogControlsSectionHeader):not(%{*GamepadDialogContent>ModalPosition} *) {
|
||
color: var(--lgs-text-2);
|
||
border-color: transparent;
|
||
}
|
||
|
||
|
||
/* ======================================================================
|
||
11. Markup classes for our own elements (T2/T3 markup; the interface in
|
||
docs/phase2/wp/C4a.md Status). The same looks as Steam's primitives:
|
||
.lgs-btn + .lgs-btn-circle | .lgs-btn-capsule; sizes .lgs-btn-mini (38),
|
||
-sm (44), default 60, -lg (70), -xl (86); roles .lgs-btn-primary,
|
||
-play, -danger (red label), -danger-fill (red confirm), -plain
|
||
(borderless in ornaments and menus); [aria-pressed="true"] = selected
|
||
.lgs-switch[aria-checked] (with a child .lgs-switch-knob)
|
||
.lgs-check[aria-checked] (svg check inside)
|
||
.lgs-seg > [aria-pressed]
|
||
.lgs-field, .lgs-platter > .lgs-row (+ .lgs-row-nav), .lgs-sep
|
||
Elements we create are buttons or carry role and tabindex themselves;
|
||
states come from P4's numbers like Steam's (:hover, .gpfocus, :active,
|
||
.lgs-pressed, :disabled / [aria-disabled]).
|
||
====================================================================== */
|
||
|
||
& .lgs-btn {
|
||
position: relative;
|
||
box-sizing: border-box;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 10px;
|
||
height: var(--lgs-btn);
|
||
min-width: var(--lgs-btn);
|
||
padding: 0 var(--lgs-btn-pad);
|
||
border: 0;
|
||
border-radius: var(--lgs-r-capsule);
|
||
font: var(--lgs-type-headline);
|
||
letter-spacing: var(--lgs-track-headline);
|
||
white-space: nowrap;
|
||
color: var(--lgs-text-1);
|
||
background: var(--lgs-raised-bg);
|
||
box-shadow: var(--lgs-raised-shadow);
|
||
cursor: pointer;
|
||
isolation: isolate;
|
||
--lgs-ill: raised;
|
||
--lgs-ill-z: -1;
|
||
--lgs-edge: control;
|
||
--lgs-c4a-side: 160;
|
||
scale: calc(1 + (min(var(--lgs-press-max), 1 + var(--lgs-press-grow) / var(--lgs-c4a-side)) - 1) * var(--lgs-press));
|
||
transition: scale var(--lgs-d-snappy) var(--lgs-ease-b15), background-color var(--lgs-d-fade) var(--lgs-ease-b0), color var(--lgs-d-fade) var(--lgs-ease-b0);
|
||
& svg { width: var(--lgs-symbol); height: var(--lgs-symbol); flex: none; }
|
||
&:is(:active, .lgs-pressed) {
|
||
transition: scale var(--lgs-d-interactive) var(--lgs-ease-b15), background-color var(--lgs-d-fade) var(--lgs-ease-b0), color var(--lgs-d-fade) var(--lgs-ease-b0);
|
||
}
|
||
&.lgs-btn-circle { width: var(--lgs-btn); padding: 0; border-radius: 50%; --lgs-c4a-side: 60; }
|
||
&.lgs-btn-mini { height: var(--lgs-btn-mini); min-width: var(--lgs-btn-mini); --lgs-c4a-side: 38; & svg { width: 18px; height: 18px; } }
|
||
&.lgs-btn-mini.lgs-btn-circle { width: var(--lgs-btn-mini); }
|
||
&.lgs-btn-sm { height: var(--lgs-btn-sm); min-width: var(--lgs-btn-sm); --lgs-c4a-side: 44; & svg { width: 20px; height: 20px; } }
|
||
&.lgs-btn-sm.lgs-btn-circle { width: var(--lgs-btn-sm); }
|
||
/* mini and small circles stand alone: an 80 x 80 hit on ::before (E-MINI),
|
||
so they carry no arc */
|
||
&:is(.lgs-btn-mini, .lgs-btn-sm).lgs-btn-circle { --lgs-edge: none; }
|
||
&.lgs-btn-mini.lgs-btn-circle::before { content: ""; position: absolute; inset: calc((var(--lgs-btn-mini) - var(--lgs-hit)) / 2); border-radius: 50%; }
|
||
&.lgs-btn-sm.lgs-btn-circle::before { content: ""; position: absolute; inset: calc((var(--lgs-btn-sm) - var(--lgs-hit)) / 2); border-radius: 50%; }
|
||
&.lgs-btn-lg { height: var(--lgs-btn-lg); min-width: var(--lgs-btn-lg); padding: 0 28px; font-size: 26px; --lgs-c4a-side: 180; & svg { width: 30px; height: 30px; } }
|
||
&.lgs-btn-lg.lgs-btn-circle { width: var(--lgs-btn-lg); padding: 0; --lgs-c4a-side: 70; }
|
||
&.lgs-btn-xl { height: var(--lgs-btn-xl); min-width: var(--lgs-btn-xl); padding: 0 34px; font-size: 28px; --lgs-c4a-side: 200; & svg { width: 36px; height: 36px; } }
|
||
&.lgs-btn-xl.lgs-btn-circle { width: var(--lgs-btn-xl); padding: 0; --lgs-c4a-side: 86; }
|
||
&.lgs-btn-primary { background: linear-gradient(180deg, rgb(255 255 255 / .16), rgb(255 255 255 / 0) 55%), var(--lgs-tint-primary); color: var(--lgs-text-on-tint); --lgs-ill: white; }
|
||
&.lgs-btn-play { background: linear-gradient(180deg, rgb(255 255 255 / .16), rgb(255 255 255 / 0) 55%), var(--lgs-tint-play); color: var(--lgs-text-on-color); --lgs-ill: white; }
|
||
&.lgs-btn-danger-fill { background: linear-gradient(180deg, rgb(255 255 255 / .16), rgb(255 255 255 / 0) 55%), var(--lgs-fill-danger); color: var(--lgs-text-on-color); --lgs-ill: white; }
|
||
&:is(.lgs-btn-primary, .lgs-btn-play, .lgs-btn-danger-fill) { box-shadow: inset 0 1.5px 1.5px -1px rgb(255 255 255 / .35), 0 3px 8px rgb(0 0 0 / .22); }
|
||
&.lgs-btn-danger { color: var(--lgs-text-danger); font-weight: 600; }
|
||
&.lgs-btn-plain { background: transparent; box-shadow: none; --lgs-edge: none; }
|
||
&[aria-pressed="true"] { background: var(--lgs-selected-fill); color: var(--lgs-text-on-selected); box-shadow: 0 2px 6px rgb(0 0 0 / .22); --lgs-ill: white; }
|
||
&:is(:disabled, [aria-disabled="true"]) { background: rgb(255 255 255 / .04); box-shadow: none; color: rgb(255 255 255 / var(--lgs-dis-content)); cursor: default; }
|
||
}
|
||
&:not(.lgs-input-laser) .lgs-btn.lgs-btn-danger.gpfocus {
|
||
background: var(--lgs-fill-danger);
|
||
color: var(--lgs-text-on-color);
|
||
--lgs-ill: white;
|
||
}
|
||
|
||
& .lgs-switch {
|
||
position: relative;
|
||
box-sizing: border-box;
|
||
flex: none;
|
||
width: var(--lgs-switch-w);
|
||
height: var(--lgs-switch-h);
|
||
border: 0;
|
||
padding: 0;
|
||
border-radius: calc(var(--lgs-switch-h) / 2);
|
||
background: rgb(255 255 255 / .16);
|
||
box-shadow: inset 0 1px 3px rgb(0 0 0 / .22);
|
||
cursor: pointer;
|
||
--lgs-ill: raised;
|
||
transition: background-color var(--lgs-d-interactive) linear var(--lgs-d-interactive);
|
||
/* the 88 x 80 hit (E-SWITCH) */
|
||
&::before { content: ""; position: absolute; inset: -20px -11px; border-radius: 30px; }
|
||
& > .lgs-switch-knob {
|
||
position: absolute;
|
||
top: 3px;
|
||
inset-inline-start: 3px;
|
||
width: calc(var(--lgs-switch-h) - 6px);
|
||
height: calc(var(--lgs-switch-h) - 6px);
|
||
border-radius: 50%;
|
||
background: #fff;
|
||
box-shadow: 0 2px 5px rgb(0 0 0 / .30);
|
||
z-index: 1;
|
||
transition: translate var(--lgs-d-snappy) var(--lgs-ease-b15), box-shadow var(--lgs-d-fade) var(--lgs-ease-b0);
|
||
}
|
||
&[aria-checked="true"] {
|
||
background: linear-gradient(180deg, rgb(255 255 255 / .14), rgb(255 255 255 / 0) 60%), var(--lgs-toggle-on);
|
||
--lgs-ill: white;
|
||
& > .lgs-switch-knob { translate: calc(var(--lgs-switch-w) - var(--lgs-switch-h)) 0; }
|
||
&:dir(rtl) > .lgs-switch-knob { translate: calc(var(--lgs-switch-h) - var(--lgs-switch-w)) 0; }
|
||
}
|
||
&:is(:active, .lgs-knob-lift) > .lgs-switch-knob { animation: lgs-knob-lift var(--lgs-d-snappy) linear; }
|
||
&:is(:disabled, [aria-disabled="true"]) { background: rgb(255 255 255 / .07); & > .lgs-switch-knob { background: rgb(255 255 255 / .42); box-shadow: none; } }
|
||
}
|
||
&:not(.lgs-input-laser) .lgs-switch.gpfocus > .lgs-switch-knob {
|
||
box-shadow: 0 2px 5px rgb(0 0 0 / .30), 0 0 14px 3px rgb(255 255 255 / .42);
|
||
}
|
||
|
||
& .lgs-check {
|
||
position: relative;
|
||
box-sizing: border-box;
|
||
flex: none;
|
||
display: inline-grid;
|
||
place-items: center;
|
||
width: var(--lgs-check);
|
||
height: var(--lgs-check);
|
||
margin: calc((var(--lgs-hit) - var(--lgs-check)) / 2);
|
||
padding: 0;
|
||
border: 0;
|
||
border-radius: 50%;
|
||
background: rgb(0 0 0 / .22);
|
||
box-shadow: inset 0 0 0 2.5px rgb(255 255 255 / .34), inset 0 2px 4px rgb(0 0 0 / .30);
|
||
cursor: pointer;
|
||
isolation: isolate;
|
||
--lgs-ill: raised;
|
||
--lgs-ill-z: -1;
|
||
--lgs-hover-spot: .07;
|
||
&::before { content: ""; position: absolute; inset: calc((var(--lgs-check) - var(--lgs-hit)) / 2); border-radius: 50%; }
|
||
& svg { width: 24px; height: 24px; color: #fff; opacity: 0; }
|
||
&[aria-checked="true"] {
|
||
background: linear-gradient(180deg, rgb(255 255 255 / .16), rgb(255 255 255 / 0) 60%), var(--lgs-check-on);
|
||
box-shadow: inset 0 1.5px 1.5px -1px rgb(255 255 255 / .35), 0 1px 2px rgb(0 0 0 / .18);
|
||
--lgs-ill: white;
|
||
--lgs-white-glow-spread: 12px;
|
||
& svg { opacity: 1; }
|
||
}
|
||
}
|
||
|
||
& .lgs-seg {
|
||
box-sizing: border-box;
|
||
display: inline-flex;
|
||
min-height: var(--lgs-seg);
|
||
padding: 2px;
|
||
border-radius: var(--lgs-r-capsule);
|
||
background: var(--lgs-fill-thick);
|
||
box-shadow: var(--lgs-recessed-shadow), inset 0 -2px 3px -1px rgb(255 255 255 / .10);
|
||
& > [aria-pressed] {
|
||
position: relative;
|
||
box-sizing: border-box;
|
||
flex: 1 0 auto;
|
||
min-width: var(--lgs-seg-min-w);
|
||
min-height: 60px;
|
||
padding: 2px 20px;
|
||
border: 0;
|
||
border-radius: 30px;
|
||
background: transparent;
|
||
background-clip: content-box;
|
||
font: 600 var(--lgs-fs-callout)/1.2 var(--lgs-font);
|
||
white-space: nowrap;
|
||
color: var(--lgs-text-1);
|
||
cursor: pointer;
|
||
isolation: isolate;
|
||
--lgs-ill: raised;
|
||
--lgs-ill-z: -1;
|
||
--lgs-ill-inset: 2px;
|
||
--lgs-ill-r: 28px;
|
||
transition: color var(--lgs-d-swap) linear;
|
||
}
|
||
& > [aria-pressed="true"] {
|
||
background: var(--lgs-selected-fill);
|
||
background-clip: content-box;
|
||
color: var(--lgs-text-on-selected);
|
||
--lgs-ill: white;
|
||
}
|
||
}
|
||
|
||
& .lgs-field {
|
||
box-sizing: border-box;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 14px;
|
||
min-height: var(--lgs-field);
|
||
padding: 0 12px 0 24px;
|
||
border: 0;
|
||
border-radius: calc(var(--lgs-field) / 2);
|
||
font: var(--lgs-type-body);
|
||
color: var(--lgs-text-1);
|
||
caret-color: var(--lgs-blue);
|
||
background: var(--lgs-fill-thick);
|
||
box-shadow: var(--lgs-recessed-shadow), inset 0 -2px 3px -1px rgb(255 255 255 / .10);
|
||
transition: box-shadow var(--lgs-d-fade) var(--lgs-ease-b0);
|
||
&::placeholder { color: rgb(255 255 255 / .55); font-style: normal; }
|
||
&:focus, &:focus-within { box-shadow: var(--lgs-recessed-shadow), var(--lgs-field-focus); }
|
||
}
|
||
|
||
& .lgs-platter {
|
||
border-radius: var(--lgs-r-platter);
|
||
background: var(--lgs-fill-regular);
|
||
}
|
||
& .lgs-row {
|
||
position: relative;
|
||
box-sizing: border-box;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 18px;
|
||
min-height: var(--lgs-row-platter);
|
||
padding: 0 var(--lgs-sep-inset);
|
||
font: var(--lgs-type-body);
|
||
color: var(--lgs-text-1);
|
||
isolation: isolate;
|
||
--lgs-ill: row;
|
||
--lgs-ill-z: -1;
|
||
&.lgs-row-nav { min-height: var(--lgs-row); --lgs-ill: nav; }
|
||
&[aria-current="true"], &[aria-selected="true"].lgs-row-nav { background: var(--lgs-fill-nav); box-shadow: var(--lgs-sel-arc); font-weight: var(--lgs-nav-weight); border-radius: var(--lgs-r-row); }
|
||
}
|
||
& .lgs-sep {
|
||
height: 2px;
|
||
margin-inline: var(--lgs-sep-inset);
|
||
border-radius: 1px;
|
||
background: var(--lgs-separator);
|
||
}
|
||
|
||
|
||
/* ======================================================================
|
||
12. High Contrast (CTL §4.6; prefers-contrast: more). Opaque fills;
|
||
P4's hooks draw the one allowed 2 px stroke for focus.
|
||
====================================================================== */
|
||
|
||
@media (prefers-contrast: more) {
|
||
button.DialogButton%{*GamepadDialogContent>Button}:not([data-lgs-noprim] *),
|
||
button.DialogButton%{*GamepadDialogContent>Button}:not([data-lgs-noprim] *):is(.gpfocus, :hover, :active, :focus, .Primary, .Destructive) {
|
||
background: rgb(255 255 255 / .22) !important;
|
||
}
|
||
%{*GamepadDialogContent>Field}%{*GamepadDialogContent>Background}:not(%{*GamepadDialogContent>Classic}):not([data-lgs-noprim] *),
|
||
%{*GamepadDialogContent>Field}%{*GamepadDialogContent>Background}:not(%{*GamepadDialogContent>Classic})%{*GamepadDialogContent>HighlightOnFocus}:is(.gpfocus, .gpfocuswithin):not([data-lgs-noprim] *) {
|
||
background: rgb(11 13 16 / .94) !important;
|
||
}
|
||
:is(input%{*GamepadDialogContent>BasicTextInput}, textarea.DialogTextInputBase, %{*SliderControlPanelGroup>EditableValue}):not([data-lgs-noprim] *),
|
||
%{Group}:not(%{CenteredPill}):not([data-lgs-noprim] *) {
|
||
background: rgb(0 0 0 / .55) !important;
|
||
}
|
||
%{*SliderControlPanelGroup>SliderTrack}:not([data-lgs-noprim] *) {
|
||
background: rgb(0 0 0 / .55);
|
||
box-shadow: inset 0 0 0 2px rgb(255 255 255 / calc(.70 * var(--lgs-focus)));
|
||
}
|
||
%{*GamepadDialogContent>Toggle}:not([data-lgs-noprim] *) > %{*GamepadDialogContent>ToggleRail} {
|
||
background: rgb(255 255 255 / .30);
|
||
}
|
||
}
|