BlueSky & more on desktop lazurite.stormlightlabs.org/
tauri rust typescript bluesky appview atproto solid
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor: proper light theme support

+97 -81
+7
src/App.css
··· 47 47 --input-bg-strong: rgba(0, 0, 0, 0.5); 48 48 --inset-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.04); 49 49 --overlay-shadow: 0 24px 40px rgba(0, 0, 0, 0.28); 50 + --overlay-scrim: rgba(4, 7, 12, 0.62); 50 51 --focus-ring: rgba(125, 175, 255, 0.45); 51 52 --font-stack: "Google Sans Variable", "Segoe UI", "Avenir Next", sans-serif; 52 53 } ··· 77 78 --input-bg-strong: rgba(244, 246, 250, 0.96); 78 79 --inset-shadow: inset 0 0 0 1px rgba(17, 24, 39, 0.1); 79 80 --overlay-shadow: 0 24px 40px rgba(15, 23, 42, 0.18); 81 + --overlay-scrim: rgba(9, 16, 28, 0.34); 80 82 --focus-ring: rgba(11, 99, 209, 0.45); 81 83 } 82 84 ··· 110 112 --input-bg-strong: rgba(0, 0, 0, 0.5); 111 113 --inset-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.04); 112 114 --overlay-shadow: 0 24px 40px rgba(0, 0, 0, 0.28); 115 + --overlay-scrim: rgba(4, 7, 12, 0.62); 113 116 --focus-ring: rgba(125, 175, 255, 0.45); 114 117 --font-stack: "Google Sans Variable", "Segoe UI", "Avenir Next", sans-serif; 115 118 } ··· 196 199 @utility ui-overlay-card { 197 200 background: var(--surface-container-highest); 198 201 box-shadow: var(--overlay-shadow); 202 + } 203 + 204 + @utility ui-scrim { 205 + background: var(--overlay-scrim); 199 206 } 200 207 201 208 .skeleton-block {
+3 -2
src/components/account/AccountSwitcher.tsx
··· 83 83 class="ui-control ui-control-hoverable relative w-full min-w-0 cursor-pointer text-on-surface" 84 84 classList={{ 85 85 "rounded-xl py-[0.95rem] pr-10 pl-4": !compact(), 86 - "grid h-14 w-14 place-items-center overflow-visible rounded-full p-0": compact(), 86 + "grid h-13 w-13 place-items-center overflow-visible rounded-full p-0 [background:transparent] [box-shadow:none]": 87 + compact(), 87 88 }} 88 89 type="button" 89 90 aria-haspopup="menu" ··· 95 96 class="absolute flex items-center justify-center text-on-surface-variant" 96 97 classList={{ 97 98 "right-[0.95rem] top-1/2 -translate-y-1/2": !compact(), 98 - "bottom-0 right-0 h-5 w-5 translate-x-[8%] translate-y-[8%] rounded-full bg-surface-container text-[0.7rem] leading-none shadow-[0_0_0_2px_var(--surface-container-lowest),inset_0_0_0_1px_var(--outline-subtle)]": 99 + "bottom-0 right-0 h-[1.35rem] w-[1.35rem] translate-x-[20%] translate-y-[20%] rounded-full bg-surface-container-high text-[0.78rem] leading-none shadow-[0_0_0_2px_var(--surface-container-lowest),inset_0_0_0_1px_var(--outline-subtle)]": 99 100 compact(), 100 101 }} 101 102 aria-hidden="true">
+7 -1
src/components/account/AccountSwitcherIdentity.tsx
··· 11 11 12 12 return ( 13 13 <div class="flex min-w-0 items-center gap-3" classList={{ "justify-center": !!props.compact }}> 14 - <AvatarBadge label={label()} src={avatar()} tone={tone()} /> 14 + <div 15 + classList={{ 16 + "flex h-12 w-12 items-center justify-center rounded-full border ui-outline-subtle bg-surface shadow-[0_1px_2px_rgba(15,23,42,0.08)]": 17 + !!props.compact, 18 + }}> 19 + <AvatarBadge label={label()} src={avatar()} tone={tone()} /> 20 + </div> 15 21 <Show when={!props.compact}> 16 22 <div class="grid min-w-0"> 17 23 <span class="truncate text-[0.92rem] font-semibold">{name()}</span>
+1 -1
src/components/feeds/FeedComposer.tsx
··· 32 32 export function ComposerLauncher(props: { activeAvatar?: string | null; activeHandle: string; onCompose: () => void }) { 33 33 return ( 34 34 <button 35 - class="mb-4 flex w-full min-w-0 items-center gap-3 rounded-3xl border-0 bg-white/3 px-4 py-4 text-left text-on-surface-variant shadow-[inset_0_0_0_1px_rgba(255,255,255,0.03)] transition duration-150 ease-out hover:bg-white/5 max-[760px]:gap-2 max-[760px]:px-3.5 max-[520px]:py-3.5" 35 + class="tone-muted mb-4 flex w-full min-w-0 items-center gap-3 rounded-3xl border-0 px-4 py-4 text-left text-on-surface-variant shadow-[var(--inset-shadow)] transition duration-150 ease-out hover:bg-surface-bright max-[760px]:gap-2 max-[760px]:px-3.5 max-[520px]:py-3.5" 36 36 type="button" 37 37 onClick={() => props.onCompose()}> 38 38 <ComposerIdentityAvatar
+4 -4
src/components/feeds/FeedPane.tsx
··· 11 11 return ( 12 12 <div class="flex shrink-0 flex-wrap items-center justify-end gap-2 max-[960px]:w-full max-[960px]:justify-between"> 13 13 <button 14 - class="inline-flex h-11 items-center gap-2 rounded-full border-0 bg-white/5 px-4 text-sm text-on-surface transition duration-150 ease-out hover:-translate-y-px hover:bg-white/8 max-[960px]:flex-1 max-[960px]:justify-center max-[520px]:px-3" 14 + class="ui-control ui-control-hoverable inline-flex h-11 items-center gap-2 rounded-full px-4 text-sm text-on-surface max-[960px]:flex-1 max-[960px]:justify-center max-[520px]:px-3" 15 15 type="button" 16 16 onClick={() => props.onCompose()}> 17 17 <Icon aria-hidden="true" kind="quill" /> 18 18 <span>New post</span> 19 19 </button> 20 20 <button 21 - class="inline-flex h-11 w-11 items-center justify-center rounded-full border-0 bg-white/5 text-on-surface transition duration-150 ease-out hover:-translate-y-px hover:bg-white/8" 21 + class="ui-control ui-control-hoverable inline-flex h-11 w-11 items-center justify-center rounded-full text-on-surface" 22 22 type="button" 23 23 aria-label="Refresh active feed" 24 24 title="Refresh active feed" ··· 88 88 89 89 function FeedPaneHeader(props: { controller: FeedWorkspaceController }) { 90 90 return ( 91 - <header class="sticky top-0 z-20 overflow-hidden rounded-t-4xl bg-[rgba(14,14,14,0.94)] px-6 pb-3 pt-5 backdrop-blur-[18px] shadow-[inset_0_-1px_0_rgba(255,255,255,0.04)] max-[960px]:px-5 max-[960px]:pb-4 max-[960px]:pt-4 max-[760px]:px-4 max-[520px]:px-3"> 91 + <header class="sticky top-0 z-20 overflow-hidden rounded-t-4xl bg-surface-container-high px-6 pb-3 pt-5 backdrop-blur-[18px] shadow-[inset_0_-1px_0_var(--outline-subtle)] max-[960px]:px-5 max-[960px]:pb-4 max-[960px]:pt-4 max-[760px]:px-4 max-[520px]:px-3"> 92 92 <FeedPaneTitle 93 93 activeFeed={props.controller.activeFeed()} 94 94 generators={props.controller.workspace.generators} ··· 108 108 const session = useAppSession(); 109 109 110 110 return ( 111 - <section class="grid min-h-0 min-w-0 overflow-hidden grid-rows-[auto_minmax(0,1fr)] rounded-4xl bg-[rgba(8,8,8,0.32)] shadow-[inset_0_0_0_1px_rgba(255,255,255,0.03)]"> 111 + <section class="grid min-h-0 min-w-0 overflow-hidden grid-rows-[auto_minmax(0,1fr)] rounded-4xl bg-surface-container shadow-(--inset-shadow)"> 112 112 <FeedPaneHeader controller={props.controller} /> 113 113 <FeedScroller 114 114 controller={props.controller}
+1 -1
src/components/feeds/FeedWorkspace.tsx
··· 116 116 Restore 117 117 </button> 118 118 <button 119 - class="rounded-full border-0 bg-transparent px-3 py-1.5 text-xs text-on-surface-variant transition hover:bg-white/5" 119 + class="rounded-full border-0 bg-transparent px-3 py-1.5 text-xs text-on-surface-variant transition hover:bg-surface-bright" 120 120 type="button" 121 121 onClick={() => props.onDiscard()}> 122 122 Discard
+6 -6
src/components/feeds/FeedWorkspaceSidebar.tsx
··· 51 51 ) { 52 52 return ( 53 53 <button 54 - class="flex w-full items-center gap-3 rounded-1xl border-0 bg-white/4 px-3 py-3 text-left text-on-surface transition duration-150 ease-out hover:-translate-y-px hover:bg-white/[0.07]" 54 + class="tone-muted flex w-full items-center gap-3 rounded-1xl border-0 px-3 py-3 text-left text-on-surface shadow-[var(--inset-shadow)] transition duration-150 ease-out hover:-translate-y-px hover:bg-surface-bright" 55 55 type="button" 56 56 onClick={() => props.onSelect(props.feed.id)}> 57 57 <FeedChipAvatar feed={props.feed} generator={props.generator} /> ··· 98 98 <span>Minimum likes for replies</span> 99 99 <p class="m-0 text-[0.72rem] leading-normal text-on-surface-variant/80">Only reply posts are affected.</p> 100 100 <input 101 - class="rounded-full border-0 bg-white/6 px-4 py-2 text-on-surface shadow-[inset_0_0_0_1px_rgba(255,255,255,0.05)] focus:outline focus:outline-primary/50" 101 + class="ui-input ui-input-strong rounded-full px-4 py-2 text-on-surface focus:outline focus:outline-primary/50" 102 102 min="0" 103 103 type="number" 104 104 placeholder='e.g. "10"' ··· 132 132 133 133 function SidebarCard(props: ParentProps & { subtitle: string; title: string }) { 134 134 return ( 135 - <section class="rounded-3xl bg-white/3 p-4 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.04)]"> 135 + <section class="tone-muted rounded-3xl p-4 shadow-[var(--inset-shadow)]"> 136 136 <p class="m-0 text-base font-semibold text-on-surface">{props.title}</p> 137 137 <p class="mt-1 text-xs uppercase tracking-[0.12em] text-on-surface-variant">{props.subtitle}</p> 138 138 <div class="mt-4">{props.children}</div> ··· 142 142 143 143 function ToggleRow(props: { checked: boolean; label: string; onChange: (checked: boolean) => void }) { 144 144 return ( 145 - <label class="flex items-center justify-between gap-3 rounded-2xl bg-white/4 px-3 py-3 text-sm text-on-surface"> 145 + <label class="tone-muted flex items-center justify-between gap-3 rounded-2xl px-3 py-3 text-sm text-on-surface shadow-[var(--inset-shadow)]"> 146 146 <span>{props.label}</span> 147 147 <input checked={props.checked} type="checkbox" onInput={(event) => props.onChange(event.currentTarget.checked)} /> 148 148 </label> ··· 151 151 152 152 function ShortcutLine(props: { keys: string; label: string }) { 153 153 return ( 154 - <div class="flex items-center justify-between gap-3 rounded-2xl bg-white/4 px-3 py-2.5"> 154 + <div class="tone-muted flex items-center justify-between gap-3 rounded-2xl px-3 py-2.5 shadow-[var(--inset-shadow)]"> 155 155 <span>{props.label}</span> 156 - <span class="rounded-full bg-black/30 px-2 py-1 text-[0.68rem] uppercase tracking-[0.08em] text-primary"> 156 + <span class="ui-input-strong rounded-full px-2 py-1 text-[0.68rem] uppercase tracking-[0.08em] text-primary"> 157 157 {props.keys} 158 158 </span> 159 159 </div>
+5 -5
src/components/feeds/PostCard.tsx
··· 80 80 <div 81 81 class="min-w-0 rounded-2xl p-2 outline-none transition duration-150 ease-out" 82 82 classList={{ 83 - "cursor-pointer hover:bg-white/2 focus-visible:bg-white/3 focus-visible:ring-1 focus-visible:ring-primary/30": 83 + "cursor-pointer hover:bg-surface-bright focus-visible:bg-surface-bright focus-visible:ring-1 focus-visible:ring-primary/30": 84 84 interactive(), 85 85 }} 86 86 aria-label={interactive() ? "Open thread" : undefined} ··· 120 120 return ( 121 121 <button 122 122 aria-label={props.ariaLabel ?? props.label} 123 - class="inline-flex min-w-0 items-center gap-1.5 rounded-full border-0 bg-transparent px-3 py-2 text-xs text-on-surface-variant transition duration-150 ease-out hover:-translate-y-px hover:bg-white/5 hover:text-primary disabled:cursor-wait disabled:opacity-70 max-[520px]:px-2.5" 123 + class="inline-flex min-w-0 items-center gap-1.5 rounded-full border-0 bg-transparent px-3 py-2 text-xs text-on-surface-variant transition duration-150 ease-out hover:-translate-y-px hover:bg-surface-bright hover:text-primary disabled:cursor-wait disabled:opacity-70 max-[520px]:px-2.5" 124 124 classList={{ "text-primary": !!props.active }} 125 125 type="button" 126 126 disabled={props.busy} ··· 226 226 ref={(element) => menu.menu.triggerRef(element)} 227 227 aria-expanded={menu.menu.open} 228 228 aria-haspopup="menu" 229 - class="inline-flex items-center justify-center rounded-full border-0 bg-transparent px-3 py-2 text-xs text-on-surface-variant transition duration-150 ease-out hover:-translate-y-px hover:bg-white/5 hover:text-primary max-[520px]:px-2.5" 229 + class="inline-flex items-center justify-center rounded-full border-0 bg-transparent px-3 py-2 text-xs text-on-surface-variant transition duration-150 ease-out hover:-translate-y-px hover:bg-surface-bright hover:text-primary max-[520px]:px-2.5" 230 230 type="button" 231 231 onClick={(event) => { 232 232 event.stopPropagation(); ··· 534 534 return ( 535 535 <article 536 536 ref={(element) => view.registerRef?.(element)} 537 - class="group min-w-0 overflow-hidden rounded-3xl bg-white/2.5 px-4 py-4 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.03)] transition duration-150 ease-out hover:bg-white/4 max-[760px]:px-3.5 max-[760px]:py-3.5 max-[520px]:rounded-3xl max-[520px]:px-3 max-[520px]:py-3" 537 + class="tone-muted group min-w-0 overflow-hidden rounded-3xl px-4 py-4 shadow-[var(--inset-shadow)] transition duration-150 ease-out hover:bg-surface-bright max-[760px]:px-3.5 max-[760px]:py-3.5 max-[520px]:rounded-3xl max-[520px]:px-3 max-[520px]:py-3" 538 538 classList={{ 539 539 "bg-[linear-gradient(135deg,rgba(125,175,255,0.11),rgba(0,115,222,0.06))] shadow-[inset_0_0_0_1px_rgba(125,175,255,0.22),0_0_0_1px_rgba(125,175,255,0.08)]": 540 540 !!view.focused, ··· 569 569 onClick={(event) => event.stopPropagation()}> 570 570 <ModeratedAvatar 571 571 avatar={view.post.author.avatar} 572 - class="relative h-11 w-11 shrink-0 overflow-hidden rounded-full bg-[linear-gradient(135deg,rgba(125,175,255,0.9),rgba(0,115,222,0.72))] shadow-[0_0_0_2px_rgba(14,14,14,1),0_0_0_3px_rgba(125,175,255,0.28)]" 572 + class="relative h-11 w-11 shrink-0 overflow-hidden rounded-full bg-[linear-gradient(135deg,rgba(125,175,255,0.9),rgba(0,115,222,0.72))] shadow-[0_0_0_2px_var(--surface-container),0_0_0_3px_rgba(125,175,255,0.28)]" 573 573 hidden={avatarDecision().filter || avatarDecision().blur !== "none"} 574 574 label={getAvatarLabel(view.post.author)} 575 575 fallbackClass="text-sm font-semibold text-on-primary-fixed" />
+12 -10
src/components/posts/PostEngagementPanel.tsx
··· 121 121 } 122 122 123 123 return ( 124 - <section class="grid min-h-0 grid-rows-[auto_auto_minmax(0,1fr)] overflow-hidden rounded-4xl bg-[rgba(8,8,8,0.32)] shadow-[inset_0_0_0_1px_rgba(255,255,255,0.03)]"> 125 - <header class="sticky top-0 z-20 flex items-center justify-between gap-3 bg-[rgba(14,14,14,0.94)] px-6 pb-4 pt-5 backdrop-blur-[18px] shadow-[inset_0_-1px_0_rgba(255,255,255,0.04)] max-[760px]:px-4 max-[520px]:px-3"> 124 + <section class="grid min-h-0 grid-rows-[auto_auto_minmax(0,1fr)] overflow-hidden rounded-4xl bg-surface-container shadow-[var(--inset-shadow)]"> 125 + <header class="sticky top-0 z-20 flex items-center justify-between gap-3 bg-surface-container-high px-6 pb-4 pt-5 backdrop-blur-[18px] shadow-[inset_0_-1px_0_var(--outline-subtle)] max-[760px]:px-4 max-[520px]:px-3"> 126 126 <div class="min-w-0"> 127 127 <p class="m-0 text-xl font-semibold tracking-tight text-on-surface">Post Engagement</p> 128 128 <p class="m-0 mt-1 text-xs uppercase tracking-[0.12em] text-on-surface-variant">{activeTabLabel()}</p> 129 129 </div> 130 130 <button 131 131 type="button" 132 - class="inline-flex h-10 items-center gap-2 rounded-full border-0 bg-white/5 px-4 text-sm text-on-surface transition duration-150 ease-out hover:-translate-y-px hover:bg-white/8" 132 + class="ui-control ui-control-hoverable inline-flex h-10 items-center gap-2 rounded-full px-4 text-sm text-on-surface" 133 133 onClick={() => void postNavigation.backFromPost()}> 134 134 <Icon aria-hidden="true" iconClass="i-ri-arrow-left-line" /> 135 135 Back ··· 143 143 type="button" 144 144 class="rounded-full border-0 px-4 py-2.5 text-sm font-medium transition duration-150 ease-out" 145 145 classList={{ 146 - "bg-white/8 text-primary shadow-[inset_0_0_0_1px_rgba(125,175,255,0.2)]": activeTab() === tab.key, 147 - "text-on-surface-variant hover:bg-white/5 hover:text-on-surface": activeTab() !== tab.key, 146 + "tone-muted text-primary shadow-[inset_0_0_0_1px_rgba(125,175,255,0.2)]": activeTab() === tab.key, 147 + "text-on-surface-variant hover:bg-surface-bright hover:text-on-surface": activeTab() !== tab.key, 148 148 }} 149 149 onClick={() => selectTab(tab.key)}> 150 150 {tab.label} ({activeCount(state.groups[tab.key])}) ··· 232 232 return ( 233 233 <button 234 234 type="button" 235 - class="flex w-full items-start gap-3 rounded-3xl border-0 bg-white/4 p-4 text-left shadow-[inset_0_0_0_1px_rgba(255,255,255,0.03)] transition duration-150 hover:bg-white/6 disabled:cursor-default disabled:hover:bg-white/4" 235 + class="tone-muted flex w-full items-start gap-3 rounded-3xl border-0 p-4 text-left shadow-[var(--inset-shadow)] transition duration-150 hover:bg-surface-bright disabled:cursor-default disabled:hover:bg-[var(--panel-muted)]" 236 236 disabled={!interactive()} 237 237 onClick={() => { 238 238 if (quoteInteractive()) { ··· 242 242 243 243 props.onOpenProfile(props.item); 244 244 }}> 245 - <div class="flex h-11 w-11 shrink-0 items-center justify-center overflow-hidden rounded-full bg-white/8 text-xs font-semibold text-on-surface-variant"> 245 + <div class="ui-input-strong flex h-11 w-11 shrink-0 items-center justify-center overflow-hidden rounded-full text-xs font-semibold text-on-surface-variant"> 246 246 <Show when={props.item.profile?.avatar} fallback={<span>{initials(actorLabel())}</span>}> 247 247 {(src) => <img alt={actorLabel()} class="h-full w-full object-cover" src={src()} />} 248 248 </Show> ··· 252 252 <p class="m-0 text-sm font-medium text-on-surface">{actorLabel()}</p> 253 253 <Show when={props.item.collection}> 254 254 {(collection) => ( 255 - <span class="rounded-full bg-white/7 px-2.5 py-1 text-xs text-on-surface-variant">{collection()}</span> 255 + <span class="tone-muted rounded-full px-2.5 py-1 text-xs text-on-surface-variant shadow-[var(--inset-shadow)]"> 256 + {collection()} 257 + </span> 256 258 )} 257 259 </Show> 258 260 </div> ··· 265 267 <div class="mt-2"> 266 268 <QuotedPostPreview 267 269 author={quoteAuthor()} 268 - class="rounded-2xl bg-black/28 p-3 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.04)]" 270 + class="ui-input-strong rounded-2xl p-3 shadow-[var(--inset-shadow)]" 269 271 text={quoteText() ?? ""} 270 272 title="Quoted post" 271 273 truncate /> ··· 321 323 <div class="grid gap-3"> 322 324 <For each={Array.from({ length: 4 })}> 323 325 {() => ( 324 - <div class="rounded-3xl bg-white/4 p-5 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.03)]"> 326 + <div class="tone-muted rounded-3xl p-5 shadow-[var(--inset-shadow)]"> 325 327 <div class="flex gap-3"> 326 328 <div class="skeleton-block h-11 w-11 rounded-full" /> 327 329 <div class="grid min-w-0 flex-1 gap-2">
+8 -8
src/components/posts/PostPanel.tsx
··· 126 126 } 127 127 128 128 return ( 129 - <section class="grid min-h-0 grid-rows-[auto_minmax(0,1fr)] overflow-hidden rounded-4xl bg-[rgba(8,8,8,0.32)] shadow-[inset_0_0_0_1px_rgba(255,255,255,0.03)]"> 130 - <header class="sticky top-0 z-20 flex items-center justify-between gap-3 bg-[rgba(14,14,14,0.94)] px-6 pb-4 pt-5 backdrop-blur-[18px] shadow-[inset_0_-1px_0_rgba(255,255,255,0.04)] max-[760px]:px-4 max-[520px]:px-3"> 129 + <section class="grid min-h-0 grid-rows-[auto_minmax(0,1fr)] overflow-hidden rounded-4xl bg-surface-container shadow-[var(--inset-shadow)]"> 130 + <header class="sticky top-0 z-20 flex items-center justify-between gap-3 bg-surface-container-high px-6 pb-4 pt-5 backdrop-blur-[18px] shadow-[inset_0_-1px_0_var(--outline-subtle)] max-[760px]:px-4 max-[520px]:px-3"> 131 131 <div class="min-w-0"> 132 132 <p class="m-0 text-xl font-semibold tracking-tight text-on-surface">Post</p> 133 133 <Show when={parentPostUri()}> ··· 142 142 </div> 143 143 <button 144 144 type="button" 145 - class="inline-flex h-10 items-center gap-2 rounded-full border-0 bg-white/5 px-4 text-sm text-on-surface transition duration-150 ease-out hover:-translate-y-px hover:bg-white/8" 145 + class="ui-control ui-control-hoverable inline-flex h-10 items-center gap-2 rounded-full px-4 text-sm text-on-surface" 146 146 onClick={() => void postNavigation.backFromPost()}> 147 147 <Icon aria-hidden="true" iconClass="i-ri-arrow-left-line" /> 148 148 Back ··· 206 206 <div class="grid gap-3"> 207 207 <For each={props.parentChain}> 208 208 {(parent) => ( 209 - <div class="rounded-3xl bg-white/3 p-3"> 209 + <div class="tone-muted rounded-3xl p-3 shadow-[var(--inset-shadow)]"> 210 210 <PostCard 211 211 bookmarkPending={!!props.bookmarkPendingByUri[parent.post.uri]} 212 212 likePending={!!props.likePendingByUri[parent.post.uri]} ··· 235 235 repostPending={!!props.repostPendingByUri[focused().post.uri]} /> 236 236 237 237 <Show when={focused().replies?.length}> 238 - <div class="grid gap-3 rounded-3xl bg-white/3 p-3"> 238 + <div class="tone-muted grid gap-3 rounded-3xl p-3 shadow-[var(--inset-shadow)]"> 239 239 <For each={focused().replies}> 240 240 {(reply) => ( 241 241 <ThreadReplies ··· 297 297 repostPending={!!props.repostPendingByUri[current().post.uri]} /> 298 298 299 299 <Show when={current().replies?.length}> 300 - <div class="ml-3 grid gap-3 border-l border-white/8 pl-3"> 300 + <div class="ml-3 grid gap-3 border-l pl-3 ui-outline-subtle"> 301 301 <For each={current().replies}> 302 302 {(reply) => ( 303 303 <ThreadReplies ··· 334 334 335 335 function SkeletonPostCard() { 336 336 return ( 337 - <div class="rounded-3xl bg-white/3 p-5 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.04)]"> 337 + <div class="tone-muted rounded-3xl p-5 shadow-[var(--inset-shadow)]"> 338 338 <div class="flex gap-3"> 339 339 <div class="skeleton-block h-11 w-11 rounded-full" /> 340 340 <div class="min-w-0 flex-1"> ··· 352 352 353 353 function StateCard(props: { label: string; meta: string }) { 354 354 return ( 355 - <div class="rounded-3xl bg-white/3 p-4 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.04)]"> 355 + <div class="tone-muted rounded-3xl p-4 shadow-[var(--inset-shadow)]"> 356 356 <p class="m-0 text-sm font-semibold text-on-surface">{props.label}</p> 357 357 <p class="mt-1 text-xs text-on-surface-variant">{props.meta}</p> 358 358 </div>
+10 -10
src/components/posts/ThreadDrawer.tsx
··· 141 141 <Show when={activeUri()}> 142 142 <div class="fixed inset-0 z-50"> 143 143 <Motion.button 144 - class="absolute inset-0 border-0 bg-surface-container-highest/70 backdrop-blur-xl" 144 + class="ui-scrim absolute inset-0 border-0 backdrop-blur-xl" 145 145 type="button" 146 146 aria-label="Close thread" 147 147 initial={{ opacity: 0 }} ··· 150 150 transition={{ duration: 0.2 }} 151 151 onClick={() => void threadOverlay.closeThread()} /> 152 152 <Motion.aside 153 - class="absolute inset-y-0 right-0 grid w-full max-w-136 grid-rows-[auto_minmax(0,1fr)] overflow-hidden bg-[rgba(12,12,12,0.92)] px-5 pb-6 pt-5 shadow-[-28px_0_50px_rgba(0,0,0,0.35)] backdrop-blur-[22px]" 153 + class="absolute inset-y-0 right-0 grid w-full max-w-136 grid-rows-[auto_minmax(0,1fr)] overflow-hidden bg-surface-container-highest px-5 pb-6 pt-5 shadow-[-28px_0_50px_rgba(0,0,0,0.24)] backdrop-blur-[22px]" 154 154 initial={{ opacity: 0, x: 30 }} 155 155 animate={{ opacity: 1, x: 0 }} 156 156 exit={{ opacity: 0, x: 36 }} ··· 204 204 205 205 <Show when={!props.loading && props.error}> 206 206 {(message) => ( 207 - <div class="rounded-3xl bg-[rgba(138,31,31,0.2)] p-4 text-sm text-error shadow-[inset_0_0_0_1px_rgba(255,128,128,0.2)]"> 207 + <div class="rounded-3xl bg-error-surface p-4 text-sm text-error shadow-[inset_0_0_0_1px_rgba(180,35,24,0.2)]"> 208 208 {message()} 209 209 </div> 210 210 )} ··· 241 241 }, 242 242 ) { 243 243 return ( 244 - <header class="sticky top-0 z-10 mb-4 flex items-center justify-between rounded-3xl bg-[rgba(14,14,14,0.9)] px-4 py-3 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.04)]"> 244 + <header class="sticky top-0 z-10 mb-4 flex items-center justify-between rounded-3xl bg-surface-container-high px-4 py-3 shadow-[var(--inset-shadow)]"> 245 245 <div> 246 246 <p class="m-0 text-base font-semibold text-on-surface">Thread</p> 247 247 <Show when={props.parentThreadHref}> ··· 259 259 {(uri) => ( 260 260 <button 261 261 aria-label="Open full post" 262 - class="inline-flex h-10 w-10 items-center justify-center rounded-xl border-0 bg-transparent text-on-surface-variant transition duration-150 ease-out hover:bg-white/5 hover:text-on-surface" 262 + class="inline-flex h-10 w-10 items-center justify-center rounded-xl border-0 bg-transparent text-on-surface-variant transition duration-150 ease-out hover:bg-surface-bright hover:text-on-surface" 263 263 type="button" 264 264 onClick={() => props.onMaximize(uri())}> 265 265 <Icon aria-hidden="true" iconClass="i-ri-external-link-line" /> ··· 267 267 )} 268 268 </Show> 269 269 <button 270 - class="inline-flex h-10 w-10 items-center justify-center rounded-xl border-0 bg-transparent text-on-surface-variant transition duration-150 ease-out hover:bg-white/5 hover:text-on-surface" 270 + class="inline-flex h-10 w-10 items-center justify-center rounded-xl border-0 bg-transparent text-on-surface-variant transition duration-150 ease-out hover:bg-surface-bright hover:text-on-surface" 271 271 type="button" 272 272 onClick={() => props.onClose()}> 273 273 <Icon aria-hidden="true" iconClass="i-ri-close-line" /> ··· 318 318 <div class="grid gap-4"> 319 319 <Show when={threadNode().parent}> 320 320 {(parent) => ( 321 - <div class="rounded-3xl bg-white/3 p-3"> 321 + <div class="tone-muted rounded-3xl p-3 shadow-[var(--inset-shadow)]"> 322 322 <ThreadNodeView 323 323 activeUri={props.activeUri} 324 324 bookmarkPendingByUri={props.bookmarkPendingByUri} ··· 348 348 repostPending={!!props.repostPendingByUri[threadNode().post.uri]} /> 349 349 350 350 <Show when={threadNode().replies?.length}> 351 - <div class="grid gap-4 rounded-3xl bg-white/3 p-3"> 351 + <div class="tone-muted grid gap-4 rounded-3xl p-3 shadow-[var(--inset-shadow)]"> 352 352 <For each={threadNode().replies}> 353 353 {(reply) => ( 354 354 <ThreadNodeView ··· 376 376 377 377 function StateCard(props: { label: string; meta: string }) { 378 378 return ( 379 - <div class="rounded-3xl bg-white/3 p-4 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.04)]"> 379 + <div class="tone-muted rounded-3xl p-4 shadow-[var(--inset-shadow)]"> 380 380 <p class="m-0 text-sm font-semibold text-on-surface">{props.label}</p> 381 381 <p class="mt-1 text-xs text-on-surface-variant">{props.meta}</p> 382 382 </div> ··· 385 385 386 386 function SkeletonThreadCard() { 387 387 return ( 388 - <div class="rounded-3xl bg-white/3 p-5 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.04)]"> 388 + <div class="tone-muted rounded-3xl p-5 shadow-[var(--inset-shadow)]"> 389 389 <div class="flex gap-3"> 390 390 <div class="skeleton-block h-11 w-11 rounded-full" /> 391 391 <div class="min-w-0 flex-1">
+7 -7
src/components/profile/ProfileActorList.tsx
··· 13 13 <p class="m-0 text-base font-semibold text-on-surface">{props.title}</p> 14 14 </div> 15 15 <button 16 - class="flex h-8 w-8 items-center justify-center rounded-full border-0 bg-white/6 text-on-surface-variant transition hover:bg-white/10 hover:text-on-surface" 16 + class="ui-control ui-control-hoverable flex h-8 w-8 items-center justify-center rounded-full" 17 17 type="button" 18 18 onClick={() => props.onClose()}> 19 19 <Icon iconClass="i-ri-close-line" class="text-base" /> ··· 26 26 return ( 27 27 <div class="flex justify-center py-4"> 28 28 <button 29 - class="inline-flex min-h-10 items-center gap-2 rounded-full border-0 bg-white/6 px-5 text-sm font-medium text-on-surface transition hover:-translate-y-px hover:bg-white/10 disabled:translate-y-0 disabled:opacity-70" 29 + class="ui-control ui-control-hoverable inline-flex min-h-10 items-center gap-2 rounded-full px-5 text-sm font-medium text-on-surface disabled:translate-y-0 disabled:opacity-70" 30 30 disabled={props.loadingMore} 31 31 type="button" 32 32 onClick={() => props.onLoadMore()}> ··· 99 99 const isFollowing = createMemo(() => !!props.actor.viewer?.following); 100 100 101 101 return ( 102 - <article class="rounded-3xl bg-white/4 p-4 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.03)]"> 102 + <article class="tone-muted rounded-3xl p-4 shadow-[var(--inset-shadow)]"> 103 103 <div class="flex items-start gap-3"> 104 104 <button 105 105 class="flex min-w-0 flex-1 items-start gap-3 border-0 bg-transparent p-0 text-left transition hover:opacity-90" ··· 159 159 when={props.isFollowing} 160 160 fallback={ 161 161 <button 162 - class="inline-flex min-h-9 shrink-0 items-center gap-2 rounded-full border border-white/16 bg-transparent px-4 text-sm font-medium text-on-surface transition hover:bg-white/6 disabled:opacity-50" 162 + class="inline-flex min-h-9 shrink-0 items-center gap-2 rounded-full border ui-outline-subtle bg-transparent px-4 text-sm font-medium text-on-surface transition hover:bg-surface-bright disabled:opacity-50" 163 163 disabled={props.loading} 164 164 type="button" 165 165 onClick={() => props.onFollow()}> ··· 189 189 <div class="grid gap-2 pt-1"> 190 190 <For each={Array.from({ length: 6 })}> 191 191 {() => ( 192 - <div class="rounded-3xl bg-white/4 p-4 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.03)]"> 192 + <div class="tone-muted rounded-3xl p-4 shadow-[var(--inset-shadow)]"> 193 193 <div class="flex items-start gap-3"> 194 194 <span class="skeleton-block h-11 w-11 shrink-0 rounded-full" /> 195 195 <div class="grid flex-1 gap-1.5"> ··· 229 229 overlayRef = element; 230 230 }} 231 231 aria-modal="true" 232 - class="absolute inset-0 z-50 flex items-end bg-[rgba(5,5,5,0.58)] p-3 backdrop-blur-xl" 232 + class="ui-scrim absolute inset-0 z-50 flex items-end p-3 backdrop-blur-xl" 233 233 initial={{ opacity: 0 }} 234 234 animate={{ opacity: 1 }} 235 235 exit={{ opacity: 0 }} ··· 244 244 } 245 245 }}> 246 246 <Motion.div 247 - class="flex max-h-[min(42rem,calc(100%-0.75rem))] w-full flex-col overflow-hidden rounded-4xl bg-[rgba(20,20,20,0.94)] shadow-[0_30px_80px_rgba(0,0,0,0.5),inset_0_0_0_1px_rgba(255,255,255,0.04)]" 247 + class="flex max-h-[min(42rem,calc(100%-0.75rem))] w-full flex-col overflow-hidden rounded-4xl bg-surface-container-highest shadow-[0_30px_80px_rgba(0,0,0,0.24),var(--inset-shadow)]" 248 248 initial={{ opacity: 0.96, y: 40 }} 249 249 animate={{ opacity: 1, y: 0 }} 250 250 exit={{ opacity: 0.96, y: 40 }}
+3 -3
src/components/profile/ProfileFeed.tsx
··· 44 44 return ( 45 45 <div class="flex justify-center py-2"> 46 46 <button 47 - class="inline-flex min-h-12 items-center gap-2 rounded-full border-0 bg-white/6 px-5 text-sm font-medium text-on-surface transition duration-150 ease-out hover:-translate-y-px hover:bg-white/10 disabled:translate-y-0 disabled:opacity-70" 47 + class="ui-control ui-control-hoverable inline-flex min-h-12 items-center gap-2 rounded-full px-5 text-sm font-medium text-on-surface disabled:translate-y-0 disabled:opacity-70" 48 48 type="button" 49 49 disabled={props.loadingMore} 50 50 onClick={() => props.onLoadMore()}> ··· 62 62 <div class="grid gap-3"> 63 63 <For each={Array.from({ length: 3 })}> 64 64 {() => ( 65 - <div class="rounded-3xl bg-white/3 p-5 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.03)]"> 65 + <div class="tone-muted rounded-3xl p-5 shadow-[var(--inset-shadow)]"> 66 66 <div class="flex items-start gap-3"> 67 67 <span class="skeleton-block h-11 w-11 rounded-full" /> 68 68 <div class="grid min-w-0 flex-1 gap-2"> ··· 80 80 81 81 export function ProfileFeedMessage(props: { body: string; title: string }) { 82 82 return ( 83 - <div class="grid place-items-center rounded-3xl bg-white/3 px-6 py-12 text-center shadow-[inset_0_0_0_1px_rgba(255,255,255,0.03)]"> 83 + <div class="tone-muted grid place-items-center rounded-3xl px-6 py-12 text-center shadow-[var(--inset-shadow)]"> 84 84 <div class="grid max-w-lg gap-2"> 85 85 <p class="m-0 text-lg font-semibold tracking-[-0.02em] text-on-surface">{props.title}</p> 86 86 <p class="m-0 text-sm leading-relaxed text-on-surface-variant">{props.body}</p>
+11 -11
src/components/profile/ProfileHero.tsx
··· 87 87 <div class="flex flex-wrap items-center justify-end gap-2"> 88 88 <For each={props.badges}> 89 89 {(badge) => ( 90 - <span class="inline-flex items-center rounded-full bg-white/6 px-3 py-2 text-xs font-medium text-on-surface"> 90 + <span class="tone-muted inline-flex items-center rounded-full px-3 py-2 text-xs font-medium text-on-surface shadow-[var(--inset-shadow)]"> 91 91 {badge} 92 92 </span> 93 93 )} 94 94 </For> 95 95 <Show when={props.badges.length === 0}> 96 - <span class="inline-flex items-center rounded-full bg-white/5 px-3 py-2 text-xs font-medium text-on-surface-variant"> 96 + <span class="tone-muted inline-flex items-center rounded-full px-3 py-2 text-xs font-medium text-on-surface-variant shadow-[var(--inset-shadow)]"> 97 97 {props.isSelf ? "Signed in" : "Public profile"} 98 98 </span> 99 99 </Show> ··· 136 136 <Show when={props.pinnedPostHref}> 137 137 {(href) => ( 138 138 <a 139 - class="inline-flex items-center gap-2 rounded-full bg-white/6 px-3 py-2 text-xs font-medium text-on-surface no-underline transition hover:-translate-y-px hover:bg-white/10" 139 + class="tone-muted inline-flex items-center gap-2 rounded-full px-3 py-2 text-xs font-medium text-on-surface no-underline shadow-[var(--inset-shadow)] transition hover:-translate-y-px hover:bg-surface-bright" 140 140 href={`#${href()}`}> 141 141 <Icon iconClass="i-ri-pushpin-2-line" class="text-base" /> 142 142 <span>Pinned post</span> ··· 153 153 when={props.isFollowing} 154 154 fallback={ 155 155 <button 156 - class="inline-flex min-h-9 items-center gap-2 rounded-full border border-white/20 bg-transparent px-5 text-sm font-medium text-on-surface transition duration-150 ease-out hover:bg-white/5 disabled:opacity-50" 156 + class="inline-flex min-h-9 items-center gap-2 rounded-full border ui-outline-strong bg-transparent px-5 text-sm font-medium text-on-surface transition duration-150 ease-out hover:bg-surface-bright disabled:opacity-50" 157 157 disabled={props.loading} 158 158 type="button" 159 159 onClick={props.onFollow}> ··· 181 181 function MessageButton(props: { onClick: () => void }) { 182 182 return ( 183 183 <button 184 - class="inline-flex min-h-9 items-center gap-2 rounded-full border border-white/12 bg-white/6 px-4 text-sm font-medium text-on-surface transition duration-150 ease-out hover:bg-white/10" 184 + class="tone-muted inline-flex min-h-9 items-center gap-2 rounded-full border ui-outline-subtle px-4 text-sm font-medium text-on-surface shadow-[var(--inset-shadow)] transition duration-150 ease-out hover:bg-surface-bright" 185 185 type="button" 186 186 onClick={() => props.onClick()}> 187 187 <Icon kind="messages" class="text-base" /> ··· 216 216 217 217 return ( 218 218 <header class="relative" ref={(element) => props.rootRef?.(element)}> 219 - <div class="relative h-64 overflow-hidden bg-surface-container-high shadow-[inset_0_-64px_80px_rgba(0,0,0,0.55)] max-[760px]:h-56"> 219 + <div class="relative h-64 overflow-hidden bg-surface-container-high shadow-[inset_0_-64px_80px_rgba(0,0,0,0.22)] max-[760px]:h-56"> 220 220 <Show 221 221 when={props.profile.banner} 222 222 fallback={ ··· 231 231 </div> 232 232 233 233 <div class="relative z-10 -mt-16 px-6 pb-6 max-[760px]:px-4 max-[520px]:px-3"> 234 - <div class="grid gap-5 rounded-4xl bg-[rgba(8,8,8,0.82)] px-5 pb-6 pt-5 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.035)] backdrop-blur-[18px] max-[760px]:px-4 max-[520px]:px-3.5"> 234 + <div class="grid gap-5 rounded-4xl bg-surface-container-highest px-5 pb-6 pt-5 shadow-[var(--inset-shadow)] backdrop-blur-[18px] max-[760px]:px-4 max-[520px]:px-3.5"> 235 235 <div class="flex flex-wrap items-start justify-between gap-5"> 236 236 <ProfileAvatar profile={props.profile} /> 237 237 ··· 278 278 return ( 279 279 <ModeratedAvatar 280 280 avatar={profile().avatar} 281 - class="relative h-32 w-32 shrink-0 overflow-hidden rounded-full bg-black/60 shadow-[0_0_0_4px_rgba(8,8,8,0.96),0_0_0_6px_rgba(125,175,255,0.22),0_24px_40px_rgba(0,0,0,0.36)] backdrop-blur-sm" 281 + class="relative h-32 w-32 shrink-0 overflow-hidden rounded-full bg-surface-container-high shadow-[0_0_0_4px_var(--surface),0_0_0_6px_rgba(125,175,255,0.24),0_24px_40px_rgba(0,0,0,0.22)]" 282 282 hidden={decision().filter || decision().blur !== "none"} 283 283 label={label()} 284 284 fallbackClass="text-[2rem] font-semibold text-on-surface" /> ··· 296 296 <div 297 297 class="sticky top-0 z-30 px-3 pb-3 pt-3 backdrop-blur-[18px] max-[520px]:px-2" 298 298 data-testid="profile-sticky-header"> 299 - <div class="flex items-center gap-3 rounded-3xl bg-[rgba(14,14,14,0.92)] px-4 py-3 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.04)]"> 299 + <div class="flex items-center gap-3 rounded-3xl bg-surface-container-high px-4 py-3 shadow-[var(--inset-shadow)]"> 300 300 <ModeratedAvatar 301 301 avatar={props.profile.avatar} 302 - class="relative h-12 w-12 shrink-0 overflow-hidden rounded-full bg-black/60 shadow-[0_0_0_2px_rgba(8,8,8,0.96),0_0_0_3px_rgba(125,175,255,0.2)]" 302 + class="relative h-12 w-12 shrink-0 overflow-hidden rounded-full bg-surface-container-high shadow-[0_0_0_2px_var(--surface),0_0_0_3px_rgba(125,175,255,0.22)]" 303 303 hidden={decision().filter || decision().blur !== "none"} 304 304 label={avatarLabel()} 305 305 fallbackClass="text-sm font-semibold text-on-surface" /> ··· 317 317 <div class="ml-auto hidden flex-wrap justify-end gap-2 min-[720px]:flex"> 318 318 <For each={visibleBadges()}> 319 319 {(badge) => ( 320 - <span class="inline-flex items-center rounded-full bg-white/6 px-3 py-1.5 text-xs font-medium text-on-surface"> 320 + <span class="tone-muted inline-flex items-center rounded-full px-3 py-1.5 text-xs font-medium text-on-surface shadow-[var(--inset-shadow)]"> 321 321 {badge} 322 322 </span> 323 323 )}
+9 -9
src/components/profile/ProfilePanel.tsx
··· 443 443 444 444 return ( 445 445 <section 446 - class="relative grid min-h-0 overflow-hidden bg-[rgba(8,8,8,0.32)]" 447 - classList={{ "rounded-4xl shadow-[inset_0_0_0_1px_rgba(255,255,255,0.03)]": !props.embedded }}> 446 + class="relative grid min-h-0 overflow-hidden bg-surface-container" 447 + classList={{ "rounded-4xl shadow-[var(--inset-shadow)]": !props.embedded }}> 448 448 <div 449 449 data-testid="profile-scroll-region" 450 450 class="min-h-0 overflow-y-auto overscroll-contain" ··· 540 540 function ProfileLoadingView() { 541 541 return ( 542 542 <div class="grid gap-4 p-6 max-[760px]:p-4 max-[520px]:p-3"> 543 - <div class="overflow-hidden rounded-4xl bg-white/3 p-6 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.03)]"> 543 + <div class="tone-muted overflow-hidden rounded-4xl p-6 shadow-[var(--inset-shadow)]"> 544 544 <ProfileSkeleton /> 545 545 </div> 546 546 <ProfileFeedSkeleton /> ··· 553 553 554 554 return ( 555 555 <div class="grid min-h-120 place-items-center p-6"> 556 - <div class="grid max-w-lg gap-4 rounded-4xl bg-white/3 p-6 text-left shadow-[inset_0_0_0_1px_rgba(255,255,255,0.03)]"> 556 + <div class="tone-muted grid max-w-lg gap-4 rounded-4xl p-6 text-left shadow-[var(--inset-shadow)]"> 557 557 <div class="flex items-center gap-3"> 558 - <span class="flex h-12 w-12 items-center justify-center rounded-full bg-white/6 text-on-surface-variant"> 558 + <span class="ui-input-strong flex h-12 w-12 items-center justify-center rounded-full text-on-surface-variant"> 559 559 <Icon kind="danger" aria-hidden="true" /> 560 560 </span> 561 561 <div class="min-w-0"> ··· 577 577 <ProfileFeedMessage body={error()} title="Profile couldn't be loaded" /> 578 578 <button 579 579 type="button" 580 - class="inline-flex items-center justify-center gap-2 rounded-full border-0 bg-surface-container-high px-4 py-2 text-sm font-medium text-on-surface transition duration-150 hover:-translate-y-px" 580 + class="ui-control ui-control-hoverable inline-flex items-center justify-center gap-2 rounded-full px-4 py-2 text-sm font-medium text-on-surface" 581 581 onClick={() => props.onRetry()}> 582 582 <Icon kind="refresh" aria-hidden="true" /> 583 583 Retry ··· 594 594 <div 595 595 class="sticky z-20 px-3 pb-3 pt-1 backdrop-blur-[18px] max-[520px]:px-2" 596 596 classList={{ "top-22": props.compactHeaderVisible, "top-0": !props.compactHeaderVisible }}> 597 - <div class="rounded-3xl bg-[rgba(14,14,14,0.92)] p-2 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.04)]"> 597 + <div class="rounded-3xl bg-surface-container-high p-2 shadow-[var(--inset-shadow)]"> 598 598 <div class="flex flex-wrap gap-2"> 599 599 <For each={PROFILE_TABS}> 600 600 {(tab) => ( 601 601 <button 602 602 class="rounded-full border-0 px-4 py-2.5 text-sm font-medium transition duration-150 ease-out" 603 603 classList={{ 604 - "bg-white/8 text-primary shadow-[inset_0_0_0_1px_rgba(125,175,255,0.2)]": props.activeTab === tab, 605 - "text-on-surface-variant hover:bg-white/5 hover:text-on-surface": props.activeTab !== tab, 604 + "tone-muted text-primary shadow-[inset_0_0_0_1px_rgba(125,175,255,0.2)]": props.activeTab === tab, 605 + "text-on-surface-variant hover:bg-surface-bright hover:text-on-surface": props.activeTab !== tab, 606 606 }} 607 607 type="button" 608 608 onClick={() => props.onSelect(tab)}>
+3 -3
src/components/shared/QuotedPostPreview.tsx
··· 33 33 const truncated = createMemo(() => props.truncate ?? false); 34 34 35 35 return ( 36 - <div class={props.class ?? "rounded-2xl bg-black/30 p-4 shadow-[inset_0_0_0_1px_rgba(255,255,255,0.05)]"}> 36 + <div class={props.class ?? "ui-input-strong rounded-2xl p-4 shadow-(--inset-shadow)"}> 37 37 <p class="m-0 text-xs uppercase tracking-[0.12em] text-on-surface-variant">{props.title}</p> 38 38 <Show 39 39 when={props.onOpenPost} ··· 43 43 fallback={<QuotedPreviewContent author={props.author} preview={preview()} truncated={truncated()} />}> 44 44 {(href) => ( 45 45 <a 46 - class="mt-2 block rounded-xl px-1 py-1 text-inherit no-underline transition duration-150 ease-out hover:bg-white/4" 46 + class="mt-2 block rounded-xl px-1 py-1 text-inherit no-underline transition duration-150 ease-out hover:bg-surface-bright" 47 47 href={href()} 48 48 rel={openInNewTab() ? "noreferrer" : undefined} 49 49 target={openInNewTab() ? "_blank" : undefined} ··· 54 54 </Show> 55 55 }> 56 56 <button 57 - class="mt-2 block w-full rounded-xl border-0 bg-transparent px-1 py-1 text-left text-inherit transition duration-150 ease-out hover:bg-white/4" 57 + class="mt-2 block w-full rounded-xl border-0 bg-transparent px-1 py-1 text-left text-inherit transition duration-150 ease-out hover:bg-surface-bright" 58 58 type="button" 59 59 onClick={(event) => { 60 60 event.stopPropagation();