/* Glass Shell, area "settings" (package C6a): every /settings page on surface main. Concept: docs/phase2/concepts/settings.md (SET) §3, §4; PLAN §1 decides conflicts. T1 (this file, always on with the theme): - the 400 px sidebar: 72 px rows at an 80 px pitch, 40 px icon circles, 24 px Medium labels, the navigation-selected pill (PLAN §1.4: white .18 + specular arc + Semibold), hover = the light spot only and focus = P4's nav hook (--lgs-ill: nav), 16 px group spacers; - the detail pane: content from y 116 (toolbar 108 + 8), an 816 px column (32 px margins in the 880 px pane), the compact hero (Title 1, centred; its colour circle with Steam's own glyph needs T2), C1a's scroll guard (--lgs-guard-top / --lgs-guard-bottom) on both scrollers; - page widgets the primitives do not cover (Notifications column headers, Storage, Game Recording modes, small colour fixes), all on P4's phase 2 tokens. T2 hooks (device/rt/60-settings.js, flag wp.c6a; inert without it): - [data-lgs-page=""] on each sidebar item and on the dialog root (the current page): the icon-circle colour (--lgs-set-tint) and the hero circle; - --lgs-set-glyph on the dialog root: Steam's own sidebar glyph of the current page as a data: URI (white), drawn in the hero circle; - data-lgs-title on the dialog root: Steam's "#MainTabsSettings", drawn by C1a's Large Title; - data-lgs-destructive on Steam's destructive buttons (SET §4.7; depth admission rule 4). Controls (rows, platters, switches, sliders, capsules, buttons, section headers) are C4a's (theme/10-primitives.css) and are never restyled here. Scope: Steam's PagedSettingsDialog is shared with game Properties (%{AppProperties}, C5a) and Notes (%{NotesPagedSettings}, C7); both are excluded. Wrapped as html.lgs-on { ... } by the bundler. */ /* ====================================================================== 1. Skeleton: sidebar column 400 px (black .14, no line), detail pane transparent (the window glass shows through). ====================================================================== */ %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog}:not(%{AppProperties}, %{NotesPagedSettings}) { background: none; & > %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingDialog_ContentColumn} { background: none; } & > %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageListColumn} { flex: 0 0 400px; width: 400px; min-width: 400px; max-width: 400px; background: var(--lgs-fill-regular); } /* the list starts at y 108 under the toolbar row (C1a: --lgs-hdr-pad), fades under it and over the last 72 px; focus stays inside C1a's guard band */ & %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageList} { padding: calc(var(--lgs-hdr-pad, 68px) + 40px) 0 24px; scroll-padding-top: var(--lgs-guard-top, 124px); scroll-padding-bottom: 96px; -webkit-mask-image: linear-gradient(180deg, transparent 94px, #000 108px, #000 calc(100% - 72px), transparent 100%); mask-image: linear-gradient(180deg, transparent 94px, #000 108px, #000 calc(100% - 72px), transparent 100%); /* rows scrolled under the toolbar row are cut at y 94 (the Back and search hit boxes end there), so they never take a click meant for the toolbar */ clip-path: inset(94px 0 0 0); } /* group separators become 16 px spacers (+ the row's 8 px margin = 24) */ & %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageList} > %{PagedSettingsDialog>Separator} { flex: 0 0 auto; height: 16px; margin: 0; background: none !important; } /* ==================================================================== 2. Sidebar rows (SET §3.3, PLAN §1.3 free-standing rows, §1.4 states). The row is the pill: 368 x 72 at x 16, radius 36, 8 px apart. Light: P4's nav hook on the row's ::after, under the label. ==================================================================== */ & %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageListItem} { position: relative; isolation: isolate; display: flex; align-items: center; box-sizing: border-box; flex: 0 0 auto; height: var(--lgs-row); min-height: var(--lgs-row); margin: 0 16px var(--lgs-row-gap); padding: 0 16px; border: 0 none !important; border-radius: 36px; background: none !important; box-shadow: none; color: var(--lgs-text-1) !important; text-shadow: none; --lgs-ill: nav; --lgs-ill-z: -1; --lgs-ill-r: 36px; } /* hit extender into the 8 px gaps (G-SIZE: >= 95 % of the 80 px box; neighbours only touch) */ & %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageListItem}::before { content: ""; position: absolute; inset: calc(var(--lgs-row-gap) / -2) 0; border-radius: inherit; background: none; } /* navigation selected (the current page; in gamepad mode also the focus, whose extra light comes from the hook) */ & %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageListItem}%{PagedSettingsDialog_PageList_ShowTitle>Active} { background: var(--lgs-fill-nav) !important; box-shadow: none; } /* its specular arc: a lobe centred at 34 % of the width fading both ways (VP P-42: never a full-width top line), painted on the hit extender (its top edge is 4 px above the pill). The lobe (x 12 %..56 %, i.e. 44..206 of 368) stays on the pill's straight top edge (36..332) and inside its top 4 px, so it never shows above the rounded corners (review R2 m1) */ & %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageListItem}%{PagedSettingsDialog_PageList_ShowTitle>Active}::before { background: radial-gradient(22% 2px at 34% calc(var(--lgs-row-gap) / 2 + 2px), rgb(255 255 255 / .45), rgb(255 255 255 / 0)) no-repeat; } & %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageListItem}%{PagedSettingsDialog_PageList_ShowTitle>DisabledItem} { color: var(--lgs-text-disabled) !important; } /* icon + label row; Steam's 1.1 scale on the active row is withdrawn (VP P-05: rows never scale) */ & %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageListItem} > %{ScaledChildren} { display: flex; align-items: center; gap: 16px; width: 100%; min-width: 0; transform: none !important; transition: none !important; } /* 40 px colour circle (T1: grey; T2: the page's colour), white glyph 22 px */ & %{PagedSettingsDialog_PageList_ShowTitle>PageListItem_Icon} { flex: 0 0 40px; width: 40px; height: 40px; margin: 0; display: grid; place-items: center; border-radius: 50%; background: linear-gradient(180deg, rgb(255 255 255 / .24), rgb(255 255 255 / 0) 60%), var(--lgs-set-tint, var(--lgs-gray)); color: #fff; opacity: 1; } & %{PagedSettingsDialog_PageList_ShowTitle>PageListItem_Icon} svg { width: 22px; height: 22px; color: #fff; } & %{PagedSettingsDialog_PageList_ShowTitle>PageListItem_Title} { flex: 1 1 auto; min-width: 0; font: var(--lgs-type-body); letter-spacing: 0; color: inherit; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } & %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageListItem}%{PagedSettingsDialog_PageList_ShowTitle>Active} %{PagedSettingsDialog_PageList_ShowTitle>PageListItem_Title} { font-weight: var(--lgs-nav-weight); } /* ==================================================================== 3. Detail pane (SET §3.5): content from y 116, an 816 px column centred in the 880 px pane, C1a's guard band on the scroller. ==================================================================== */ & %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageContent} { padding: calc(var(--lgs-hdr-pad, 68px) + 48px) 0 0; scroll-padding-top: var(--lgs-guard-top, 124px); scroll-padding-bottom: calc(720px - var(--lgs-guard-bottom, 612px)); -webkit-mask-image: linear-gradient(180deg, transparent 84px, #000 116px, #000 calc(100% - 140px), transparent calc(100% - 92px)); mask-image: linear-gradient(180deg, transparent 84px, #000 116px, #000 calc(100% - 140px), transparent calc(100% - 92px)); } & %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageContent} > .DialogContent_InnerWidth { /* the column box fills the pane and carries the margins (32 px each side, Steam's 112 px end padding), so it keeps its area on short pages (G-AUD SHRUNK) and a long page ends at y 608 */ box-sizing: border-box; width: 100%; max-width: none; margin-inline: 0; padding: 0 32px 112px; } /* pages end at y 628 (C1a: the ornament line); the hit region ends there too */ & %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageContent} { clip-path: inset(0 0 92px 0); } /* compact hero (SET §3.5): Title 1, centred, one line; 60 + 16 px. The 60 px circle needs T2's page key, glyph and the title's measured width (data-lgs-hero, --lgs-set-hero-tw): the circle and the title are centred as one group. It stays flat on the window plane (no native pop) */ & %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageContent} > .DialogContent_InnerWidth > .DialogHeader { position: relative; justify-content: center; align-items: center; height: 60px; margin: 0 0 16px; font: var(--lgs-type-title1); letter-spacing: var(--lgs-track-title); color: var(--lgs-text-1); text-shadow: none; white-space: nowrap; } &[data-lgs-hero] %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageContent} > .DialogContent_InnerWidth > .DialogHeader { padding-left: 76px; } &[data-lgs-hero] %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageContent} > .DialogContent_InnerWidth > .DialogHeader::before { content: ""; position: absolute; top: 0; left: calc(50% - 38px - var(--lgs-set-hero-tw, 0px) / 2); width: 60px; height: 60px; border-radius: 50%; background: var(--lgs-set-glyph, none) center / 32px 32px no-repeat, linear-gradient(180deg, rgb(255 255 255 / .24), rgb(255 255 255 / 0) 60%), var(--lgs-set-tint, var(--lgs-gray)); /* flat on the window plane (the +10 mm native pop was removed: it cut the window's base mosaic into pieces that did not line up off axis), so no depth shadow */ box-shadow: none; pointer-events: none; } /* Storage (SET §4.8: no hero, its title is the page's own): Steam sizes the virtualised app list to the space left, and every row Steam renders at stock must still render (G-AUD GONE), so the page keeps stock's list height: title only (Title 2), 8 px less on top, full pane width, and the list runs to y 720 under the glass edge (no 628 cut on this page); its own scroller gets 64 px of end padding so the last row still scrolls up into the glass (§6) */ &:has(%{ContentManagement}%{InPagedSettings}) %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageContent} { padding: calc(var(--lgs-hdr-pad, 68px) + 40px) 0 0; clip-path: none; -webkit-mask-image: linear-gradient(180deg, transparent 84px, #000 108px, #000 calc(100% - 112px), transparent calc(100% - 64px)); mask-image: linear-gradient(180deg, transparent 84px, #000 108px, #000 calc(100% - 112px), transparent calc(100% - 64px)); } &:has(%{ContentManagement}%{InPagedSettings}) %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageContent} > .DialogContent_InnerWidth { padding: 0 16px; } &:has(%{ContentManagement}%{InPagedSettings}) %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageContent} > .DialogContent_InnerWidth > .DialogBody { margin-top: 0; } &:has(%{ContentManagement}%{InPagedSettings}) %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageContent} > .DialogContent_InnerWidth > .DialogHeader { padding-left: 0; height: 36px; margin: 0 0 4px; font: var(--lgs-type-title2); } &:has(%{ContentManagement}%{InPagedSettings}) %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageContent} > .DialogContent_InnerWidth > .DialogHeader::before { content: none; } /* in-text links: white with a soft underline */ & %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageContent} a { color: var(--lgs-text-1); text-decoration-line: underline; text-decoration-color: var(--lgs-text-3); text-underline-offset: 3px; } & %{SettingsDialogBodyText} { color: var(--lgs-text-1); } & %{SettingsDialogDescriptionText} { color: var(--lgs-text-2); } /* ==================================================================== 4. Page widgets ==================================================================== */ /* --- Notifications: the "Show Toast" / "Play Sound" headers sit centred over their switch columns (C4a's 66 px switches with 14 px side margins: 94 px cells, the second ends at the row's 26 px inset), 18 px Semibold title case (REQ C4a->C6a) */ & %{NotificationSectionHeader} %{Toggles} { display: flex; align-items: center; gap: 52px; padding-inline-end: 26px; font: var(--lgs-type-caption); font-weight: 600; text-transform: none; letter-spacing: 0; color: var(--lgs-text-2); } & %{NotificationSectionHeader} %{Toggles} > div { flex: 0 0 94px; width: 94px; text-align: center; white-space: nowrap; text-transform: none; letter-spacing: 0; } /* --- Game Recording: recording-mode cards = rows in a platter, a leading radio circle */ & %{RecordingModeOption} { position: relative; isolation: isolate; background: var(--lgs-fill-regular) !important; border-radius: var(--lgs-r-row); border-color: transparent !important; box-shadow: none !important; color: var(--lgs-text-1); --lgs-ill: row; --lgs-ill-z: -1; --lgs-ill-inset: 0px; } & %{RecordingModeOption} %{WarningBox>Header} { color: var(--lgs-text-1); } & %{RecordingModeOption} %{FieldSeparator>Body} { color: var(--lgs-text-2); } & %{RecordingModeOption} %{Pip} { background-color: var(--lgs-fill-thick); border-color: transparent; box-shadow: var(--lgs-recessed-shadow); } & %{RecordingModeOption} %{Pip}%{ActivePip} { background: radial-gradient(circle, #fff 0 3.5px, var(--lgs-check-on) 4px); border-color: transparent; box-shadow: none; } & %{BitrateSetting>Muted} { color: var(--lgs-text-2); } /* --- Downloads: "game update timing" pseudo-row */ & %{FakeContainer} { background-color: var(--lgs-fill-regular); border-radius: var(--lgs-r-row); color: var(--lgs-text-1); } /* --- Bluetooth: "Not connected" badge, scanning header */ & %{BluetoothDeviceQuickAccessField>NotConnectedLabel}, & %{NotConnectedLabel>Header} { color: var(--lgs-text-2); } /* --- Home: hidden games and instructions */ & %{HiddenGameLabel}, & %{HiddenGameLabel} %{GameCount} { color: var(--lgs-text-1); } & :is(%{AppSelectorButton>Description}, %{Instructions}) { color: var(--lgs-text-2); } /* --- Friends & Chat: the "Append nicknames" preview friend */ & %{FakeFriend} %{playerName} { color: var(--lgs-text-1); } & %{FakeFriend} %{richPresenceLabel} { color: var(--lgs-text-2); } & %{FakeFriend} %{avatar} { border-radius: var(--lgs-r-small); } } /* ====================================================================== 5. Page colours (T2 keys, SET §3.3: visionOS / iOS Settings colours, keyed by route, never by text). On the sidebar items and on the dialog root (the current page: the hero circle). ====================================================================== */ [data-lgs-page="system"], [data-lgs-page="storage"], [data-lgs-page="keyboard"], [data-lgs-page="developer"] { --lgs-set-tint: var(--lgs-gray); } [data-lgs-page="internet"], [data-lgs-page="bluetooth"], [data-lgs-page="display"], [data-lgs-page="accessibility"], [data-lgs-page="security"], [data-lgs-page="cloud"], [data-lgs-page="store"] { --lgs-set-tint: var(--lgs-blue); } [data-lgs-page="power"], [data-lgs-page="friends"] { --lgs-set-tint: var(--lgs-green); } [data-lgs-page="audio"], [data-lgs-page="notifications"], [data-lgs-page="gamerecording"] { --lgs-set-tint: var(--lgs-red); } [data-lgs-page="controller"], [data-lgs-page="family"], [data-lgs-page="library"] { --lgs-set-tint: var(--lgs-orange); } [data-lgs-page="downloads"] { --lgs-set-tint: var(--lgs-teal); } [data-lgs-page="ingame"], [data-lgs-page="home"] { --lgs-set-tint: var(--lgs-indigo); } [data-lgs-page="compatibility"], [data-lgs-page="remoteplay"], [data-lgs-page="lgsvr"] { --lgs-set-tint: var(--lgs-purple); } /* ====================================================================== 6. Storage (/settings/storage): drive tabs as a segmented strip, the usage bar, the app list as one platter. Anchored on .BasicUI: Steam's storage rules reach (0,5,0). Virtualised geometry is untouched. ====================================================================== */ .BasicUI %{ContentManagement}%{InPagedSettings} { & %{InstallFolder} { position: relative; isolation: isolate; background: var(--lgs-fill-thin) !important; box-shadow: none !important; border-color: transparent !important; color: var(--lgs-text-1); --lgs-ill: raised; --lgs-ill-z: -1; } & %{InstallFolder} %{DriveName}, & %{InstallFolder} > svg { color: var(--lgs-text-1) !important; } & %{InstallFolder} %{DriveSize} { color: var(--lgs-text-1) !important; } & %{InstallFolder}%{IsSelected} { background: var(--lgs-selected-fill) !important; box-shadow: none !important; --lgs-ill: white; } & %{InstallFolder}%{IsSelected} %{DriveName}, & %{InstallFolder}%{IsSelected} > svg { color: var(--lgs-text-on-selected) !important; } & %{InstallFolder}%{IsSelected} %{DriveSize} { color: var(--lgs-text-on-selected) !important; } /* type (P-38, P-84): no text under 18 px, no uppercase or tracking */ & %{InstallFolder} %{DriveName} { font-size: var(--lgs-fs-subhead); font-weight: 600; line-height: 1.15; } & %{InstallFolder} %{DriveSize} { line-height: 1.15; } /* the app list's own scroller: the last 64 px of the window are under the glass edge */ & %{ContentManagement>AppList} { padding-bottom: 64px; scroll-padding-bottom: 64px; } & :is(%{InstallFolder} %{DriveSize}, %{LibraryHeader} %{DriveName}, %{DriveUsageText}, %{DriveUsageNumber}, %{AppUsageValue}, %{AppSize}) { font-size: var(--lgs-fs-footnote); font-weight: 500; text-transform: none; letter-spacing: 0; } & :is(%{AppHeader}, %{AppHeaderValue}) { font-size: var(--lgs-fs-subhead); font-weight: 500; } & %{ContentManagement>AppName} { font-size: var(--lgs-fs-subhead); font-weight: 600; } & %{SortingDropDownControlButton} { font-size: var(--lgs-fs-footnote); font-weight: 500; } & %{LibraryHeader} %{DriveName} { color: var(--lgs-text-2); } & %{DriveUsageIndicator} { background: var(--lgs-fill-thick); border-radius: var(--lgs-r-capsule); box-shadow: var(--lgs-recessed-shadow); } & %{DriveUsageGames} { background-color: var(--lgs-blue); } & %{DriveUsageWorkshop} { background-color: var(--lgs-green); } & %{DriveUsageShader} { background-color: var(--lgs-purple); } & :is(%{DriveUsageOther}, %{DriveUsageOtherDot}) { background-color: var(--lgs-yellow); } & %{DriveUsageFreeSpace} { background-color: transparent; } & %{DriveUsageText} { color: var(--lgs-text-1); } & %{DriveUsageNumber}, & %{OtherInfo} svg { color: var(--lgs-text-2); } & %{AppHeader} { color: var(--lgs-text-1); } & %{AppHeaderValue} { color: var(--lgs-text-2); } & %{ContentManagement>Rule} { height: 2px; background-color: var(--lgs-separator); } /* the app list is one recessed platter */ & %{LibraryInventory} { background-color: var(--lgs-fill-regular); border-radius: var(--lgs-r-platter); box-shadow: none; } & %{AppBody} { position: relative; isolation: isolate; border-radius: var(--lgs-r-row); background: none !important; box-shadow: none !important; --lgs-ill: row; --lgs-ill-z: -1; } & %{ContentManagement>AppName}, & %{AppSize} { color: var(--lgs-text-1); } & %{AppUsageValue}, & %{SpecialSectionText}, & %{AppInfoItem} svg { color: var(--lgs-text-2); } & %{AppBodyPortrait} :is(%{LibraryItemBox}, %{PortraitImage>Container}, %{PortraitImage>Image}) { border-radius: var(--lgs-r-small); } } /* in-text links: the underline brightens on laser hover (laser mode) or gamepad focus (pad mode) only, never on a stale :focus (review R2 m7; 04-states' input-mode scopes) */ &:not(.lgs-input-pad) %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog}:not(%{AppProperties}, %{NotesPagedSettings}) %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageContent} a:hover, &:not(.lgs-input-laser) %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog}:not(%{AppProperties}, %{NotesPagedSettings}) %{PagedSettingsDialog_PageList_ShowTitle>PagedSettingsDialog_PageContent} a.gpfocus { text-decoration-color: var(--lgs-text-1); } /* ====================================================================== 7. Dialogs opened from settings pages (modal layer; the alert itself is C1c's): the Game Recording bitrate table sits in a recessed well. ====================================================================== */ %{BitRateTable} { background: var(--lgs-fill-thick); box-shadow: var(--lgs-recessed-shadow); border-radius: var(--lgs-r-row); color: var(--lgs-text-1); } %{AutoExplainer} { color: var(--lgs-text-2); }