Files

863 lines
36 KiB
CSS

/* Glass Shell, area "bar" (C3a, Phase 2): the dashboard bar (surface bar)
and the bar popups other than "+" (C2b, 32-launcher.css) and Quick Access
(C3b, 31-cc.css; its Phase 1 rules stay in §4 below until the two-step
move of PLAN §6). The frame menu is C1a's (20-shell.css §4): every
DashboardMenu rule here is scoped to %{Variant_TabMenu}.
PLAN §1.3, §1.4, §1.6, §1.12; CC §3; mockup control-center-bar.html.
Sizes are bar / popup px (pp, m .83). Wrapped as html.lgs-on { ... }.
The bar is three glass pieces on Steam's own nodes (T5 covers the same
three shapes, theme/layers/30-bar.json):
Home circle = %{BarSurface}%{Bookend} (Steam tab)
apps capsule = the main %{BarSurface}'s Tabs section (app tabs + "+")
system capsule= %{Tray} (Playspace, Room View, Streaming, pill, avatar)
The main %{BarSurface} itself is transparent. Each is its own SteamVR
quad over the room, so CSS-only glass is the liquid-over-room tint plus
E3 edges (P4 hooks); no outer shadow (the quad clips it).
States (PLAN §1.4), keyed on P3's input mode like 04-states.css: laser
hover + .08 and a .12 spot at the pointer; gamepad focus + .32, a static
.16 spot in the upper third and the disc's arc; no scale, no ring, no
outline. White (on, open popup source, pill while open) and art discs:
the outer glow only. Selected frame: .18 disc + top arc + a white dot.
Steam's press transform (Highlight::before scale .9, ClickPop) is kept. */
/* ====================================================================== */
/* 0. Local values */
/* ====================================================================== */
& {
/* focus glow on white / art discs, scaled to the bar (tokens.md §1.6) */
--lgs-c3a-glow: 0 0 calc(var(--lgs-white-glow-blur) * var(--lgs-m-bar)) calc(var(--lgs-white-glow-spread) * var(--lgs-m-bar)) rgb(255 255 255 / var(--lgs-white-glow-a));
--lgs-c3a-arc: inset 0 1.5px 1.5px -1px rgb(255 255 255 / var(--lgs-focus-arc));
--lgs-c3a-u-focus: linear-gradient(rgb(255 255 255 / var(--lgs-focus-add)), rgb(255 255 255 / var(--lgs-focus-add)));
--lgs-c3a-spot-focus: radial-gradient(circle at 50% 30%, rgb(255 255 255 / var(--lgs-focus-spot)) 0, rgb(255 255 255 / 0) 75%);
--lgs-c3a-u-hover: linear-gradient(rgb(255 255 255 / var(--lgs-hover-add)), rgb(255 255 255 / var(--lgs-hover-add)));
--lgs-c3a-u-sel: linear-gradient(rgb(255 255 255 / .18), rgb(255 255 255 / .18));
--lgs-c3a-u-press: linear-gradient(rgb(255 255 255 / calc(var(--lgs-hover-add) + var(--lgs-press-add))), rgb(255 255 255 / calc(var(--lgs-hover-add) + var(--lgs-press-add))));
--lgs-c3a-t: background-color var(--lgs-motion-fade, 441ms ease), box-shadow var(--lgs-motion-fade, 441ms ease), color var(--lgs-motion-fade, 441ms ease);
}
/* ====================================================================== */
/* 1. The bar: three glass pieces */
/* ====================================================================== */
%{PopupBody>DashboardBar} {
color: var(--lgs-text-1);
/* the bar keeps Steam's width; its pieces sit together in the middle */
justify-content: center;
}
/* the main segment is only a holder now */
%{BarSurface}:not(%{Bookend}) {
background: transparent;
box-shadow: none;
border-radius: 0;
gap: 12px;
}
/* Steam's flex spacer (min 70) between the apps and the system capsule */
%{BarSurface} %{EmptySpace} {
flex: 0 0 12px;
min-width: 12px;
}
/* the glass: Home circle, apps capsule, system capsule */
%{BarSurface}%{Bookend},
%{BarSurface}:not(%{Bookend}) > %{BarSurfaceSection}%{LowBatteryGauge>Tabs},
%{BarSurfaceSection}%{Tray} {
position: relative;
background: var(--lgs-mat-liquid-room-bg);
box-shadow: var(--lgs-mat-liquid-shade);
border-radius: var(--lgs-r-capsule);
--lgs-edge: liquid;
}
%{BarSurface}:not(%{Bookend}) > %{BarSurfaceSection}%{LowBatteryGauge>Tabs} {
padding-inline: 4px;
}
%{BarSurfaceSection}%{Tray} {
padding-inline: 4px 0;
}
/* ---------------------------------------------------------------------- */
/* 1.1 Tabs (the Steam tab = Home circle; app / overlay / window tabs) */
/* The disc is BarTab::before (free), 56 pp at inset 12. Steam's ::after */
/* indicator keeps its transform: recoloured into a small white dot. */
/* ---------------------------------------------------------------------- */
%{BarTab} {
isolation: isolate;
color: var(--lgs-text-1);
background: transparent;
}
%{BarTab}:is(:hover, %{MenuVisible}),
%{BarTab}%{OldColors}:is(:hover, :active, %{LowBatteryGauge>Selected}) {
background: transparent;
color: var(--lgs-text-1);
--badge-border-color: transparent;
}
%{BarTab}::before {
content: "";
position: absolute;
inset: 12px;
z-index: -1;
border-radius: 50%;
background: transparent;
box-shadow: none;
pointer-events: none;
transition: var(--lgs-c3a-t);
}
/* selected frame: navigation selection, never white */
%{BarTab}%{LowBatteryGauge>Selected}::before {
background: var(--lgs-c3a-u-sel);
box-shadow: var(--lgs-sel-arc);
}
/* laser hover (also the tab whose menu is open) */
&:not(.lgs-input-pad) %{BarTab}:is(:hover, %{MenuVisible})::before {
background: radial-gradient(circle at var(--hx, 50%) var(--hy, 30%), rgb(255 255 255 / var(--lgs-hover-spot)) 0, rgb(255 255 255 / 0) 75%), var(--lgs-c3a-u-hover);
}
&:not(.lgs-input-pad) %{BarTab}%{LowBatteryGauge>Selected}:is(:hover, %{MenuVisible})::before {
background: radial-gradient(circle at var(--hx, 50%) var(--hy, 30%), rgb(255 255 255 / var(--lgs-hover-spot)) 0, rgb(255 255 255 / 0) 75%), var(--lgs-c3a-u-sel), var(--lgs-c3a-u-hover);
}
/* gamepad focus: light from within, no scale, no ring */
&:not(.lgs-input-laser) %{BarTab}.gpfocus::before {
background: var(--lgs-c3a-spot-focus), var(--lgs-c3a-u-focus);
box-shadow: var(--lgs-c3a-arc);
animation: lgs-focus-in var(--lgs-motion-hover-in, 294ms ease) backwards;
transition: none;
}
&:not(.lgs-input-laser) %{BarTab}.gpfocus%{LowBatteryGauge>Selected}::before {
background: var(--lgs-c3a-spot-focus), var(--lgs-c3a-u-sel), var(--lgs-c3a-u-focus);
}
/* app art (overlay thumbnails, window icons) is content: a round crop,
no fill on focus, only the outer glow (D-5) */
%{BarTab} %{OverlayIcon} {
border-radius: 50%;
overflow: hidden;
}
%{BarTab} %{OverlayIcon} > img {
border-radius: 50%;
object-fit: cover;
}
&:not(.lgs-input-laser) %{BarTab}.gpfocus:has(%{OverlayIcon})::before {
background: transparent;
box-shadow: var(--lgs-c3a-glow);
}
/* Steam's selected indicator: a white 6 pp dot (its transform, flex and
transition stay Steam's) */
%{BarTab}::after {
background: rgb(255 255 255 / .92);
width: 6px;
border-radius: 3px;
/* Steam slides it from under the edge (translateY 6 -> 3 px); the
independent translate lifts the whole travel 8 pp so the selected dot
sits fully under the disc, and only the selected tab shows it */
translate: 0 -8px;
opacity: 0;
}
%{BarTab}%{LowBatteryGauge>Selected}::after {
opacity: 1;
}
/* ---------------------------------------------------------------------- */
/* 1.2 Discs: "+" and the system buttons (Playspace, Room View, Streaming, */
/* conditional header items). Steam's Highlight::before is the disc. */
/* ---------------------------------------------------------------------- */
/* 56 pp discs at a 64 pp pitch: Highlight is 2 em */
%{Tray} .VRDashboardBarSmallButton {
font-size: 28px;
padding: 0 4px;
}
/* "+" keeps Steam's transform: scale(.7); the independent scale brings the
48 px disc to 56 rendered (48 x 1.667 x .7), layout unchanged */
%{AddWindowButton} {
min-width: 64px;
height: 72px;
align-self: center;
justify-content: center;
}
%{AddWindowButton} %{PopupBody>Highlight} {
scale: 1.6667;
}
.VRDashboardBarSmallButton %{PopupBody>Highlight} {
color: var(--lgs-text-1);
transition: color var(--lgs-motion-fade, 441ms ease);
}
.VRDashboardBarSmallButton %{PopupBody>Highlight}::before,
%{Tray} .VRDashboardBarSmallButton:not(%{PanelSection>Active}) %{PopupBody>Highlight}::before {
background: transparent;
box-shadow: none;
opacity: 1;
transition: var(--lgs-c3a-t), transform .15s ease-out;
}
/* laser hover */
&:not(.lgs-input-pad) .VRDashboardBarSmallButton%{PopupBody>Clickable}:not(%{PanelSection>Active}):hover %{PopupBody>Highlight}::before {
background: radial-gradient(circle at var(--hx, 50%) var(--hy, 30%), rgb(255 255 255 / var(--lgs-hover-spot)) 0, rgb(255 255 255 / 0) 75%), var(--lgs-c3a-u-hover);
opacity: 1;
}
/* press: a glow (Steam's own scale-in stays) */
.VRDashboardBarSmallButton%{PopupBody>Clickable}:not(%{PanelSection>Active}):active %{PopupBody>Highlight}::before {
background: radial-gradient(circle at 50% 50%, rgb(255 255 255 / var(--lgs-press-spot)) 0, rgb(255 255 255 / 0) 100%), var(--lgs-c3a-u-press);
}
/* gamepad focus */
&:not(.lgs-input-laser) .VRDashboardBarSmallButton%{PopupBody>Clickable}.gpfocus:not(%{PanelSection>Active}) %{PopupBody>Highlight}::before {
background: var(--lgs-c3a-spot-focus), var(--lgs-c3a-u-focus);
box-shadow: var(--lgs-c3a-arc);
animation: lgs-focus-in var(--lgs-motion-hover-in, 294ms ease) backwards;
}
.VRDashboardBarSmallButton%{PopupBody>Clickable}.gpfocus %{PopupBody>Highlight} {
box-shadow: none;
outline: none;
}
/* on: Room View on, or its popup is open = white disc, dark glyph (on fade) */
.VRDashboardBarSmallButton%{PanelSection>Active} %{PopupBody>Highlight},
.VRDashboardBarSmallButton%{PopupBody>Clickable}%{PanelSection>Active}:is(:hover, .gpfocus, :active) %{PopupBody>Highlight} {
color: var(--lgs-text-on-selected);
}
.VRDashboardBarSmallButton%{PanelSection>Active} %{PopupBody>Highlight}::before,
.VRDashboardBarSmallButton%{PopupBody>Clickable}%{PanelSection>Active}:is(:hover, :active) %{PopupBody>Highlight}::before {
background: var(--lgs-selected-fill);
box-shadow: none;
opacity: 1;
}
/* white cannot get lighter: focus (and half on hover) is the outer glow */
&:not(.lgs-input-laser) .VRDashboardBarSmallButton%{PopupBody>Clickable}.gpfocus%{PanelSection>Active} %{PopupBody>Highlight}::before {
box-shadow: var(--lgs-c3a-glow);
}
&:not(.lgs-input-pad) .VRDashboardBarSmallButton%{PopupBody>Clickable}%{PanelSection>Active}:hover %{PopupBody>Highlight}::before {
box-shadow: 0 0 calc(var(--lgs-white-glow-blur) * var(--lgs-m-bar)) calc(var(--lgs-white-glow-spread) * var(--lgs-m-bar)) rgb(255 255 255 / calc(var(--lgs-white-glow-a) * .5));
}
/* disabled items: content at 40 %, no hover */
.VRDashboardBarSmallButton:is([aria-disabled="true"], .Disabled) %{PopupBody>Highlight} {
color: rgb(255 255 255 / var(--lgs-dis-content));
}
/* ---------------------------------------------------------------------- */
/* 1.3 The status pill (Quick Access) and the avatar */
/* Steam's own hover/open pill (Inner::before) is the raised capsule: */
/* 56 tall, white .10 at rest; clock 26 Semibold tabular and the glyphs */
/* on one line. */
/* ---------------------------------------------------------------------- */
%{QuickAccessButton} {
color: var(--lgs-text-1);
padding-inline: 4px;
}
%{QuickAccessButton} %{PopupBody>Inner} {
flex-direction: row;
align-items: center;
gap: 12px;
padding: 0 16px 0 18px;
}
%{QuickAccessButton} %{PopupBody>Time} {
color: inherit;
font-family: var(--lgs-font);
font-size: 26px;
font-weight: 600;
font-variant-numeric: tabular-nums;
letter-spacing: 0;
line-height: 1;
text-shadow: none;
}
%{QuickAccessButton} %{PopupBody>Icons} {
align-items: center;
gap: 8px;
}
%{QuickAccessButton} %{PopupBody>Inner}::before {
inset: -5px 0;
border-radius: var(--lgs-r-capsule);
background: var(--lgs-raised-bg);
box-shadow: var(--lgs-raised-shadow);
opacity: 1;
transition: var(--lgs-c3a-t);
}
&:not(.lgs-input-pad) %{QuickAccessButton}:not(%{MenuVisible}):hover %{PopupBody>Inner}::before {
background: radial-gradient(circle at var(--hx, 50%) var(--hy, 30%), rgb(255 255 255 / var(--lgs-hover-spot)) 0, rgb(255 255 255 / 0) 75%), var(--lgs-c3a-u-hover), var(--lgs-raised-bg);
opacity: 1;
}
&:not(.lgs-input-laser) %{QuickAccessButton}.gpfocus:not(%{MenuVisible}) %{PopupBody>Inner}::before {
background: var(--lgs-c3a-spot-focus), var(--lgs-c3a-u-focus), var(--lgs-raised-bg);
box-shadow: var(--lgs-c3a-arc), var(--lgs-raised-shadow);
opacity: 1;
animation: lgs-focus-in var(--lgs-motion-hover-in, 294ms ease) backwards;
}
/* Control Center / Quick Access open: the pill is white, dark content */
%{QuickAccessButton}%{MenuVisible} {
color: var(--lgs-text-on-selected);
}
%{QuickAccessButton}%{MenuVisible} %{PopupBody>Inner}::before {
background: var(--lgs-selected-fill);
box-shadow: none;
opacity: 1;
}
&:not(.lgs-input-laser) %{QuickAccessButton}.gpfocus%{MenuVisible} %{PopupBody>Inner}::before {
box-shadow: var(--lgs-c3a-glow);
}
/* audit hint: the white pill is Steam's pseudo-element, which the lab's
contrast walk (ancestor backgrounds only) cannot see. The clock carries
the same white clipped to its own glyphs, fully covered by the dark
glyphs: no visible change, and the audit measures the real backdrop. */
%{QuickAccessButton}%{MenuVisible} %{PopupBody>Time} {
background-color: var(--lgs-selected-fill);
-webkit-background-clip: text;
background-clip: text;
}
%{QuickAccessButton}.gpfocus {
outline: none;
}
/* T2 (device/rt/30-bar.js, flag wp.c3a): the unread count after Steam's
bell, a deep-red capsule with a white Bold number (5.5:1). Without the
runtime the bell alone says "unread", as stock. */
/* the glyphs are not targets of their own (focusable: false; a click
bubbles to the pill, inventory bar.md §1.2) */
%{QuickAccessButton} %{NotificationsIcon}[data-lgs-unread] {
display: inline-flex;
align-items: center;
gap: 4px;
}
%{QuickAccessButton} %{NotificationsIcon}[data-lgs-unread]::after {
content: attr(data-lgs-unread);
box-sizing: border-box;
min-width: 26px;
height: 26px;
padding: 0 7px;
border-radius: 13px;
background: rgb(204 32 40);
color: #fff;
font-family: var(--lgs-font);
font-size: 17px;
font-weight: 700;
line-height: 26px;
font-variant-numeric: tabular-nums;
text-align: center;
pointer-events: none;
}
/* avatar: content, a 46 pp disc; Steam's persona strip beside it becomes a
small capsule; focus = outer glow, never a ring */
%{AvatarButton} %{PopupBody>Avatar} {
border-radius: 24px;
transition: box-shadow var(--lgs-motion-fade, 441ms ease);
}
%{AvatarButton} %{PopupBody>Avatar} img {
border-radius: 50%;
box-shadow: none;
}
%{AvatarButton} %{PopupBody>Avatar} .avatarStatus {
border-radius: 2px;
}
&:not(.lgs-input-pad) %{AvatarButton}:hover %{PopupBody>Avatar} {
box-shadow: 0 0 calc(var(--lgs-white-glow-blur) * var(--lgs-m-bar)) calc(var(--lgs-white-glow-spread) * var(--lgs-m-bar) / 2) rgb(255 255 255 / calc(var(--lgs-white-glow-a) * .5));
}
&:not(.lgs-input-laser) %{AvatarButton}.gpfocus %{PopupBody>Avatar},
%{AvatarButton}%{MenuVisible} %{PopupBody>Avatar} {
box-shadow: var(--lgs-c3a-glow);
}
/* ====================================================================== */
/* 2. Bar popups (surface barpopup): Playspace, Streaming */
/* Panel glass (PLAN §1.6), one column (the 300 pp host), 64 pp rows 5 pp */
/* apart. The "+" list (C2b) carries its own glass on its list: excluded. */
/* ====================================================================== */
%{DashboardBarPopupContents}:not(:has(%{DashboardBarPopupListHeader})) {
position: relative;
background: var(--lgs-mat-panel-bg);
/* E4 only: Streaming stacks two cards, and E5's raised bottom shadow
leaves the last rows lighter than the glass above, which reads as a
closed bottom rim (G-OUTLINE edge profile) */
box-shadow: inset 0 0 10px -1.5px rgb(0 0 0 / .16);
border-color: transparent;
border-radius: 27px;
color: var(--lgs-text-2);
--lgs-edge: panel;
/* narrow cards up to 1024 pp tall: the key light sits a little further
left so no edge reads as a closed line (WN 8.2 ratio <= .35) */
--lgs-light: 320deg;
--lgs-maxside: 300;
transform-origin: 50% 100%;
animation: lgs-mat-large-in var(--lgs-motion-mat-in, 250ms linear) backwards;
}
%{DashboardBarPopupContents}:has(%{DashboardBarPopupListHeader}) {
background: transparent;
box-shadow: none;
border-color: transparent;
}
/* ---------------------------------------------------------------------- */
/* 2.1 The list card (Playspace; the "+" list is C2b's) */
/* Rows: Steam's ::before is the active dot, ::after the separator; the */
/* row's light is drawn on ::after (Steam hides the separator on lit rows) */
/* ---------------------------------------------------------------------- */
%{DashboardBarPopupList}:not(:has(> %{DashboardBarPopupListHeader})) %{DashboardBarPopupListItem} {
min-height: 64px;
box-sizing: border-box;
margin-block: 0 5px;
background: transparent;
border-radius: var(--lgs-r-capsule);
color: var(--lgs-text-1);
isolation: isolate;
}
%{DashboardBarPopupList}:not(:has(> %{DashboardBarPopupListHeader})) %{DashboardBarPopupListItem} %{*GamepadDialogContent>FieldLabel} {
color: var(--lgs-text-1);
font-family: var(--lgs-font);
font-size: 20px;
font-weight: 500;
letter-spacing: 0;
text-shadow: none;
}
%{DashboardBarPopupList}:not(:has(> %{DashboardBarPopupListHeader})) %{DashboardBarPopupListItem} %{*GamepadDialogContent>FieldIcon} {
color: var(--lgs-text-1);
}
/* rows sit on one glass: no separators (a 5 pp gap instead) */
%{DashboardBarPopupList}:not(:has(> %{DashboardBarPopupListHeader})) %{DashboardBarPopupListItem}%{*GamepadDialogContent>WithBottomSeparatorStandard}::after {
background: transparent;
}
/* Steam's row fill (rgb(61,68,80) + a focus keyframe) never paints */
%{DashboardBarPopupList}:not(:has(> %{DashboardBarPopupListHeader})) %{DashboardBarPopupListItem}:is(.gpfocus, .gpfocuswithin, :hover, :active) {
background: transparent !important;
color: var(--lgs-text-1) !important;
animation-name: none !important;
outline: none;
}
%{DashboardBarPopupList}:not(:has(> %{DashboardBarPopupListHeader})) %{DashboardBarPopupListItem}:where(.gpfocus, .gpfocuswithin, :hover)::after {
content: "";
display: block !important;
position: absolute;
inset: 0 2px;
height: auto;
margin: 0;
z-index: -1;
border-radius: var(--lgs-r-capsule);
background: transparent;
pointer-events: none;
}
&:not(.lgs-input-pad) %{DashboardBarPopupList}:not(:has(> %{DashboardBarPopupListHeader})) %{DashboardBarPopupListItem}:not(%{*GamepadDialogContent>Disabled}):hover::after {
background: radial-gradient(circle at var(--hx, 50%) var(--hy, 30%), rgb(255 255 255 / var(--lgs-hover-spot)) 0, rgb(255 255 255 / 0) 75%), var(--lgs-c3a-u-hover);
}
&:not(.lgs-input-laser) %{DashboardBarPopupList}:not(:has(> %{DashboardBarPopupListHeader})) %{DashboardBarPopupListItem}:is(.gpfocus, .gpfocuswithin)::after {
background: radial-gradient(60% 120% at 26% 0, rgb(255 255 255 / var(--lgs-focus-spot)) 0, rgb(255 255 255 / 0) 75%), var(--lgs-c3a-u-focus);
box-shadow: var(--lgs-c3a-arc);
animation: lgs-focus-in var(--lgs-motion-hover-in, 294ms ease) backwards;
}
%{DashboardBarPopupList}:not(:has(> %{DashboardBarPopupListHeader})) %{DashboardBarPopupListItem}:not(%{*GamepadDialogContent>Disabled}):active::after {
background: var(--lgs-c3a-u-press);
}
/* active (toggled) row: Steam's dot (its ::before) in white */
%{DashboardBarPopupList}:not(:has(> %{DashboardBarPopupListHeader})) %{DashboardBarPopupListItem}::before {
background: rgb(255 255 255 / .92);
}
%{DashboardBarPopupList}:not(:has(> %{DashboardBarPopupListHeader})) %{DashboardBarPopupListItem}%{*GamepadDialogContent>Disabled},
%{DashboardBarPopupList}:not(:has(> %{DashboardBarPopupListHeader})) %{DashboardBarPopupListItem}%{*GamepadDialogContent>Disabled} %{*GamepadDialogContent>FieldLabel} {
color: rgb(255 255 255 / var(--lgs-dis-content));
}
/* the last row has no gap under it */
%{DashboardBarPopupList}:not(:has(> %{DashboardBarPopupListHeader})) %{DashboardBarPopupListItem}:last-child {
margin-bottom: 0;
}
/* scroll fades: Steam's opaque #0e141b bands become a fade into the glass */
%{DashboardBarPopupList}:not(:has(> %{DashboardBarPopupListHeader})) %{DashboardBarPopupListScrollRegion}::before,
%{DashboardBarPopupList}:not(:has(> %{DashboardBarPopupListHeader})) %{DashboardBarPopupListScrollRegion}::after {
box-shadow: none;
background: transparent;
}
%{DashboardBarPopupListScrollRegion}%{FadeTop} {
-webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 36px);
}
%{DashboardBarPopupListScrollRegion}%{FadeBottom} {
-webkit-mask-image: linear-gradient(to top, transparent 0, #000 36px);
}
%{DashboardBarPopupListScrollRegion}%{FadeTop}%{FadeBottom} {
-webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 36px, #000 calc(100% - 36px), transparent 100%);
}
/* ---------------------------------------------------------------------- */
/* 2.2 Streaming Status / VR Spectating (QAM panel in a popup card) */
/* ---------------------------------------------------------------------- */
%{QuickAccessPopupPanel}%{BottomFade}::after {
background: transparent;
box-shadow: none;
}
%{QuickAccessPopupPanel}%{BottomFade} {
-webkit-mask-image: linear-gradient(to top, transparent 0, #000 48px);
}
%{ActiveHostTitle>Streaming} %{ActiveHostTitle} {
color: var(--lgs-text-2);
text-shadow: none;
}
/* the popup's one primary action: the tinted capsule (over C4a's raised
text button), 20 pp Semibold on one line in the 300 pp card */
%{ActiveHostTitle>Streaming} button%{AlwaysBluePrimaryButton}.DialogButton.Primary {
background: var(--lgs-tint-primary) !important;
color: var(--lgs-text-on-tint) !important;
border-radius: var(--lgs-r-capsule);
box-shadow: var(--lgs-raised-shadow);
min-height: 66px;
padding-inline: 16px;
font-size: 20px;
font-weight: 600;
line-height: 1.2;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
&:not(.lgs-input-pad) %{ActiveHostTitle>Streaming} button%{AlwaysBluePrimaryButton}.DialogButton.Primary:hover {
background: var(--lgs-c3a-u-hover), var(--lgs-tint-primary) !important;
}
%{ActiveHostTitle>Streaming} button%{AlwaysBluePrimaryButton}.DialogButton.Primary.gpfocus:not(.Disabled) {
background: var(--lgs-tint-primary) !important;
box-shadow: var(--lgs-raised-shadow), var(--lgs-c3a-glow) !important;
color: var(--lgs-text-on-tint) !important;
outline: none;
}
%{ActiveHostTitle>Streaming} button%{AlwaysBluePrimaryButton}.DialogButton.Primary:enabled:active {
background: var(--lgs-c3a-u-press), var(--lgs-tint-primary) !important;
}
%{AvailableHostsHeader} {
color: var(--lgs-text-2);
font-size: 18px;
font-weight: 600;
line-height: 1.25;
}
/* host card: a grouped fill on the glass; no ring (P-42) */
%{AvailableHost} {
border-radius: var(--lgs-r-card);
outline: 0 solid transparent;
border: 0;
}
%{AvailableHostContents} {
outline: 0 solid transparent;
border: 0;
background: var(--lgs-fill-thin);
border-radius: var(--lgs-r-card);
transition: background-color var(--lgs-motion-fade, 441ms ease);
}
%{AvailableHostContents}:focus-within {
background: var(--lgs-c3a-spot-focus), var(--lgs-c3a-u-focus) !important;
color: var(--lgs-text-1) !important;
}
%{HostIcon} {
color: var(--lgs-text-2);
}
%{HostName} {
color: var(--lgs-text-1);
font-size: 20px;
font-weight: 600;
line-height: 1.2;
}
/* status: neutral text (white .86: .70 misses 4.5:1 over a bright room on
this card), the meaning stays in the coloured dot */
%{HostStatus} {
color: rgb(255 255 255 / .86);
font-size: 16px;
font-weight: 500;
line-height: 1.25;
}
%{HostStatus}%{Streaming>Ready} {
--status-color: var(--lgs-green);
}
%{SharingViewStatus} {
color: rgb(255 255 255 / .86);
font-size: 16px;
font-weight: 500;
line-height: 1.25;
}
/* the "none found" card is Steam's dimmed placeholder (opacity .3 on the
opaque card); on glass that sinks below stock legibility, so it takes
the disabled level and keeps its labels full white */
%{AvailableHost}%{NoneFound} {
opacity: var(--lgs-disabled-opacity);
}
%{AvailableHost}%{NoneFound} :is(%{HostName}, %{SharingViewStatus}, %{HostStatus}) {
color: var(--lgs-text-1);
}
/* the host card's divider above Advanced: spacing only (a full-width
line across the card's lower edge reads as a rim, G-OUTLINE) */
%{AdvancedSection} hr {
border: 0;
height: 2px;
background: transparent;
}
/* the status dot: Steam's thin ring goes (P-43), the fill stays */
%{HostStatus}::before {
border: 0;
}
/* Advanced disclosure: a borderless text button; light grows with a
spread shadow so its box (and the layout) stays as is */
%{AdvancedToggle} {
color: var(--lgs-text-1);
font-size: 16px;
font-weight: 600;
/* a 50 pp tall target (P-80) */
min-height: 50px;
padding-inline: 14px;
display: inline-flex;
align-items: center;
border-radius: var(--lgs-r-capsule);
transition: var(--lgs-c3a-t);
}
&:not(.lgs-input-pad) %{AdvancedToggle}:hover {
color: var(--lgs-text-1);
background: rgb(255 255 255 / var(--lgs-hover-add));
box-shadow: 0 0 0 4px rgb(255 255 255 / var(--lgs-hover-add));
}
&:not(.lgs-input-laser) %{AdvancedToggle}.gpfocus {
color: var(--lgs-text-1);
background: rgb(255 255 255 / var(--lgs-focus-add));
box-shadow: 0 0 0 4px rgb(255 255 255 / var(--lgs-focus-add)), var(--lgs-c3a-arc);
outline: none;
}
/* ====================================================================== */
/* 3. Tab menus (DashboardMenu %{Variant_TabMenu}, surface barpopup) */
/* Panel glass, one column, Steam's order and first focus; 64 pp rows, */
/* 22 pp glyphs, 20 pp Medium labels. The light is P4's hook on the item */
/* (::after); the current route is the navigation selection (.18 + arc) */
/* on ItemOuter::before. Steam's focus zoom on the item is kept. */
/* ====================================================================== */
%{DashboardMenu}%{Variant_TabMenu} {
--menu-background: transparent;
--menu-item-height: 64px;
--menu-icon-size: 22px;
--menu-font-size: 20px;
background: var(--lgs-mat-panel-bg);
box-shadow: var(--lgs-mat-panel-shade);
border-radius: 27px;
--lgs-edge: panel;
/* a tall narrow slab: the key light sits further left so the top edge
shows the arc's fall-off (WN 8.2 ratio <= .35), as C2b's "+" card */
--lgs-light: 305deg;
--lgs-maxside: 300;
animation: lgs-mat-large-in var(--lgs-motion-mat-in, 250ms linear) backwards;
}
/* Steam fades the menu's background-color over .5 s; the glass is
constant, so only Steam's width/transform transitions are kept */
%{DashboardMenu}%{Variant_TabMenu}:not(%{DashboardMenu>Collapsed}) {
transition-property: width, transform;
}
%{DashboardMenu}%{Variant_TabMenu} %{DashboardMenu>ItemOuter} {
background: transparent;
border-color: transparent !important;
}
/* rows sit on one glass: Steam's dividers go (a lit row needs none) */
%{DashboardMenu}%{Variant_TabMenu} %{DashboardMenu>ItemOuter}::after {
background: transparent;
}
%{DashboardMenu}%{Variant_TabMenu} %{SectionGap} {
background: linear-gradient(var(--lgs-separator), var(--lgs-separator)) center / calc(100% - 52px) 2px no-repeat;
}
%{DashboardMenu}%{Variant_TabMenu} %{PopupBody>Separator} {
background: linear-gradient(90deg, transparent, var(--lgs-separator), transparent);
}
/* the item never paints a fill of its own (Steam: hover 20 % white,
focus keyframes); its light is P4's hook */
%{DashboardMenu}%{Variant_TabMenu} %{DashboardMenu>Item} {
background: transparent !important;
outline: none;
isolation: isolate;
--lgs-ill: raised;
--lgs-ill-inset: 2px 6px;
--lgs-ill-r: var(--lgs-r-capsule);
--lgs-ill-z: -1;
}
/* the current route: navigation selected */
%{DashboardMenu}%{Variant_TabMenu} %{DashboardMenu>ItemOuter}::before {
content: "";
position: absolute;
inset: 2px 6px;
border-radius: var(--lgs-r-capsule);
background: transparent;
pointer-events: none;
}
%{DashboardMenu}%{Variant_TabMenu} %{DashboardMenu>ItemOuter}:has(> %{DashboardMenu>Item}%{DashboardMenu>Active})::before {
background: var(--lgs-fill-nav);
box-shadow: var(--lgs-sel-arc);
}
%{DashboardMenu}%{Variant_TabMenu} %{DashboardMenu>Item}%{DashboardMenu>Active} :is(%{DashboardMenu>ItemIcon}, %{DashboardMenu>ItemLabel}) {
color: var(--lgs-text-1) !important;
font-weight: var(--lgs-nav-weight);
}
/* labels and glyphs: white on glass */
%{DashboardMenu}%{Variant_TabMenu} %{DashboardMenu>Item}:not(%{DashboardMenu>Blocked}) :is(%{DashboardMenu>ItemIcon}, %{DashboardMenu>ItemLabel}) {
color: var(--lgs-text-1) !important;
}
%{DashboardMenu}%{Variant_TabMenu} %{DashboardMenu>ItemLabel} {
font-family: var(--lgs-font);
font-weight: 500;
letter-spacing: 0;
text-shadow: none;
}
%{DashboardMenu}%{Variant_TabMenu} %{DashboardMenu>Blocked} :is(%{DashboardMenu>ItemIcon}, %{DashboardMenu>ItemLabel}) {
color: rgb(255 255 255 / var(--lgs-dis-content)) !important;
}
/* route-active marker: Steam's dot, white */
%{DashboardMenu}%{Variant_TabMenu} %{DashboardMenu>ActiveDot} {
background: rgb(255 255 255 / .92);
}
/* ====================================================================== */
/* 4. Quick Access Menu (CC-C) — Phase 1 rules kept until C3b takes them */
/* (PLAN §6 two-step move); C3b's 31-cc.css adds its Phase 2 deltas. */
/* The card is panel glass with E3 edges; focus is light, never a ring. */
/* ====================================================================== */
& {
--lgs-bar-row-ring: var(--lgs-c3a-arc);
}
%{QuickAccessMenu} {
position: relative;
background: var(--lgs-mat-panel-bg);
box-shadow: var(--lgs-mat-panel-shade);
border-color: transparent;
border-radius: var(--lgs-r-panel);
--lgs-edge: panel;
}
%{PanelSection>Container}%{Expanded>VR} %{QuickAccessMenu} {
border-color: transparent;
border-radius: var(--lgs-r-panel);
}
/* title: Steam paints it opaque with a shadow halo as the top fade */
%{QuickAccessMenu} %{PopupBody>Title} {
background: transparent;
box-shadow: none;
color: var(--lgs-text-1);
text-shadow: none;
}
/* bottom fade band (opaque) -> the list itself fades into the glass */
%{PanelSection>Container}%{Expanded>VR} %{PopupBody>ContentTransition}::after {
background: transparent;
box-shadow: none;
}
%{QuickAccessMenu} %{TabGroupPanel} {
-webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 14px, #000 calc(100% - 52px), transparent 100%);
}
/* tab bar at the bottom: a hairline above, segments as inset pills */
%{QuickAccessMenu} %{ViewPlaceholder>Tabs}::after {
background: var(--lgs-separator);
}
%{QuickAccessMenu} %{PopupBody>Tab} {
background: transparent !important;
color: var(--lgs-text-2) !important;
outline: none;
transition: color var(--lgs-motion-fade, 441ms ease);
}
%{QuickAccessMenu} %{PopupBody>Tab}::before {
content: "";
position: absolute;
inset: 6px 7px;
z-index: -1;
border-radius: var(--lgs-r-capsule);
background: transparent;
pointer-events: none;
transition: var(--lgs-c3a-t);
}
&:not(.lgs-input-pad) %{QuickAccessMenu} %{PopupBody>Tab}:hover {
color: var(--lgs-text-1) !important;
}
&:not(.lgs-input-pad) %{QuickAccessMenu} %{PopupBody>Tab}:hover::before {
background: rgb(255 255 255 / var(--lgs-hover-add));
}
%{QuickAccessMenu} %{PopupBody>Tab}%{ViewPlaceholder>Selected} {
color: var(--lgs-text-on-selected) !important;
}
%{QuickAccessMenu} %{PopupBody>Tab}%{ViewPlaceholder>Selected}::before {
background: var(--lgs-selected-fill);
}
%{QuickAccessMenu} %{PopupBody>Tab}.gpfocus:not(%{ViewPlaceholder>Selected}) {
color: var(--lgs-text-1) !important;
}
%{QuickAccessMenu} %{PopupBody>Tab}.gpfocus:not(%{ViewPlaceholder>Selected})::before {
background: rgb(255 255 255 / var(--lgs-focus-add));
box-shadow: var(--lgs-c3a-arc);
}
/* voice tab keeps Steam's green as a whole fill */
%{QuickAccessMenu} %{PopupBody>Tab}%{VoiceTab}::before {
background: var(--lgs-green);
}
/* section headers: secondary label, title case */
:is(%{QuickAccessMenu}, %{DashboardBarPopupContents}) %{*PanelSection>PanelSectionTitle} {
color: var(--lgs-text-2);
text-transform: none;
letter-spacing: 0;
text-shadow: none;
}
/* notifications tab: hairline dividers, secondary empty state */
%{QuickAccessMenu} %{*PanelSection>QuickAccessNotifications} > div::before {
border-bottom-color: var(--lgs-separator);
}
%{QuickAccessMenu} %{*PanelSection>EmptyNotifications} {
color: var(--lgs-text-2);
}
%{QuickAccessMenu} %{*PanelSection>BatteryPercentageLabel} {
color: var(--lgs-text-1);
}
/* ---------------------------------------------------------------------- */
/* 4.1 Classic field rows inside bar popups (Quick Access, Streaming) */
/* Rest transparent; hover/focus = an inset pill on ::before (free on */
/* these rows), Steam's own separator ::after recoloured. */
/* ---------------------------------------------------------------------- */
:is(%{QuickAccessMenu}, %{DashboardBarPopupContents}) %{*GamepadDialogContent>Field}%{*GamepadDialogContent>Classic} :is(%{*GamepadDialogContent>FieldLabel}, %{*GamepadDialogContent>FieldIcon}) {
color: var(--lgs-text-1);
}
:is(%{QuickAccessMenu}, %{DashboardBarPopupContents}) %{*GamepadDialogContent>Field}%{*GamepadDialogContent>Classic} :is(%{*GamepadDialogContent>FieldDescription}, %{*GamepadDialogContent>LabelFieldValue}) {
color: var(--lgs-text-2);
}
:is(%{QuickAccessMenu}, %{DashboardBarPopupContents}) %{*GamepadDialogContent>Field}%{*GamepadDialogContent>Classic}:is(%{*GamepadDialogContent>WithBottomSeparatorStandard}, %{*GamepadDialogContent>WithBottomSeparatorThick})::after {
background: var(--lgs-separator);
}
/* no separator under a card's last row: it would sit on the glass edge */
%{DashboardBarPopupContents} %{*GamepadDialogContent>Field}%{*GamepadDialogContent>Classic}:last-child::after {
background: transparent;
}
:is(%{QuickAccessMenu}, %{DashboardBarPopupContents}) %{*GamepadDialogContent>Field}%{*GamepadDialogContent>Classic}:not(%{DashboardBarPopupListItem}):is(%{*GamepadDialogContent>HighlightOnFocus}:is(.gpfocus, .gpfocuswithin), %{*GamepadDialogContent>Clickable}:not(%{*GamepadDialogContent>Disabled}):hover) {
background: transparent !important;
color: var(--lgs-text-1) !important;
}
:is(%{QuickAccessMenu}, %{DashboardBarPopupContents}) %{*GamepadDialogContent>Field}%{*GamepadDialogContent>Classic}:not(%{DashboardBarPopupListItem}):where(%{*GamepadDialogContent>HighlightOnFocus}:is(.gpfocus, .gpfocuswithin), %{*GamepadDialogContent>Clickable}:not(%{*GamepadDialogContent>Disabled}):hover)::before {
content: "";
position: absolute;
inset: 1px 6px;
z-index: -1;
border-radius: var(--lgs-r-row);
background: rgb(255 255 255 / var(--lgs-hover-add));
pointer-events: none;
}
:is(%{QuickAccessMenu}, %{DashboardBarPopupContents}) %{*GamepadDialogContent>Field}%{*GamepadDialogContent>Classic}:not(%{DashboardBarPopupListItem})%{*GamepadDialogContent>HighlightOnFocus}:is(.gpfocus, .gpfocuswithin)::before {
background: rgb(255 255 255 / var(--lgs-focus-add));
box-shadow: var(--lgs-c3a-arc);
}
/* compact rows (the Wi-Fi network row) have no inline padding and are
indented by margin: the pill reaches back past their icon */
:is(%{QuickAccessMenu}, %{DashboardBarPopupContents}) %{*GamepadDialogContent>Field}%{*GamepadDialogContent>Classic}%{*GamepadDialogContent>CompactPadding}:not(%{DashboardBarPopupListItem})::before {
inset: 1px 6px 1px -10px;
}
/* a toggle/button inside the row carries its own focus: the row only warms */
:is(%{QuickAccessMenu}, %{DashboardBarPopupContents}) %{*GamepadDialogContent>Field}%{*GamepadDialogContent>Classic}%{*GamepadDialogContent>HighlightOnFocus}.gpfocuswithin:has(button.DialogButton.gpfocus)::before {
background: rgb(255 255 255 / var(--lgs-within-add));
box-shadow: none;
}
:is(%{QuickAccessMenu}, %{DashboardBarPopupContents}) %{*GamepadDialogContent>Field}%{*GamepadDialogContent>Classic}%{*GamepadDialogContent>Disabled} :is(%{*GamepadDialogContent>FieldLabel}, %{*GamepadDialogContent>FieldIcon}) {
color: rgb(255 255 255 / var(--lgs-dis-content));
}