authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-07-23 13:09:55+02:00
committergravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-07-23 13:09:55+02:00
loge51538b812392d522947494ae32dacf3f3859f5e
treedb8c5fbd1d0df94349c43b98a7016af27e4d29d9
parent1c9a6de26eb41f77dbf2f6039427f50f2e9f8b39

Restore light-mode surfaces and refine dialog styling

- Restore light-mode glass, dialog, dropdown, and composer colors - Refine provider wizard, changed-file cards, sidebar controls, and buttons - Update wizard step tests for the new list structure

18 files changed, 212 insertions(+), 225 deletions(-)

apps/web/src/components/ChatView.tsx+1-1
......@@ -5592,7 +5592,7 @@ function ChatViewContent(props: ChatViewProps) {
55925592 : undefined
55935593 }
55945594 >
5595 <div className="chat-composer-glass-host mx-auto w-full max-w-3xl overflow-hidden rounded-[22px]">
5595 <div className="chat-composer-glass-host mx-auto w-full max-w-3xl rounded-[22px]">
55965596 <div ref={attachDraftHeroComposerAnchorRef} className="relative z-10 isolate">
55975597 <ChatComposer
55985598 composerRef={composerRef}
apps/web/src/components/GitActionsControl.tsx+9-20
......@@ -544,10 +544,7 @@ function PublishRepositoryDialog(props: PublishRepositoryDialogProps) {
544544
545545 return (
546546 <Dialog open={props.open} onOpenChange={handleOpenChange}>
547 <DialogPopup
548 backdropClassName="bg-black/40 backdrop-blur-none"
549 className="workflow-dialog-surface max-w-xl overflow-hidden before:hidden"
550 >
547 <DialogPopup className="max-w-xl overflow-hidden">
551548 <div className="flex min-h-0 flex-col overflow-hidden border-foreground/10 bg-transparent">
552549 <DialogHeader className="border-b border-border/70 bg-foreground/[0.025] dark:border-transparent dark:bg-transparent">
553550 <DialogTitle>Publish repository</DialogTitle>
......@@ -1828,16 +1825,13 @@ export default function GitActionsControl({
18281825 }
18291826 }}
18301827 >
1831 <DialogPopup
1832 backdropClassName="bg-black/40 backdrop-blur-none"
1833 className="command-palette-dialog-surface workflow-dialog-surface before:hidden"
1834 >
1828 <DialogPopup>
18351829 <DialogHeader>
18361830 <DialogTitle>{COMMIT_DIALOG_TITLE}</DialogTitle>
18371831 <DialogDescription>{COMMIT_DIALOG_DESCRIPTION}</DialogDescription>
18381832 </DialogHeader>
18391833 <DialogPanel className="space-y-4">
1840 <div className="space-y-3 rounded-lg border border-input bg-muted/40 p-3 text-xs dark:border-transparent dark:bg-white/[0.035]">
1834 <div className="space-y-3 rounded-xl bg-zinc-25 p-3 text-sm ring-1 ring-black/5 dark:bg-white/[0.035] dark:ring-white/5">
18411835 <div className="grid grid-cols-[auto_1fr] items-center gap-x-2 gap-y-1">
18421836 <span className="text-muted-foreground">Branch</span>
18431837 <span className="flex items-center justify-between gap-2">
......@@ -1845,9 +1839,7 @@ export default function GitActionsControl({
18451839 {gitStatusForActions?.refName ?? "(detached HEAD)"}
18461840 </span>
18471841 {isDefaultRef && (
1848 <span className="text-right text-warning text-xs">
1849 Warning: default refName
1850 </span>
1842 <span className="text-right text-warning">Warning: default refName</span>
18511843 )}
18521844 </span>
18531845 </div>
......@@ -1886,14 +1878,14 @@ export default function GitActionsControl({
18861878 <p className="font-medium">none</p>
18871879 ) : (
18881880 <div className="space-y-2">
1889 <ScrollArea className="h-44 rounded-md border border-input bg-background dark:border-transparent dark:bg-white/[0.025]">
1881 <ScrollArea className="h-44 rounded-lg bg-card ring-1 ring-black/5 dark:bg-white/[0.025] dark:ring-white/5">
18901882 <div className="space-y-1 p-1">
18911883 {allFiles.map((file) => {
18921884 const isExcluded = excludedFiles.has(file.path);
18931885 return (
18941886 <div
18951887 key={file.path}
1896 className="flex w-full items-center gap-2 rounded-md px-2 py-1 font-mono text-xs transition-colors hover:bg-accent/50"
1888 className="flex w-full items-center gap-2 rounded-md px-2 py-1 font-mono hover:bg-accent/50"
18971889 >
18981890 {isEditingFiles && (
18991891 <Checkbox
......@@ -1952,7 +1944,7 @@ export default function GitActionsControl({
19521944 </div>
19531945 </div>
19541946 <div className="space-y-1">
1955 <p className="text-xs font-medium">Commit message (optional)</p>
1947 <p className="text-sm font-medium">Commit message (optional)</p>
19561948 <Textarea
19571949 value={dialogCommitMessage}
19581950 onChange={(event) => setDialogCommitMessage(event.target.value)}
......@@ -1961,7 +1953,7 @@ export default function GitActionsControl({
19611953 />
19621954 </div>
19631955 </DialogPanel>
1964 <DialogFooter className="dark:border-transparent dark:bg-transparent">
1956 <DialogFooter variant="bare">
19651957 <Button
19661958 variant="outline"
19671959 size="sm"
......@@ -2004,10 +1996,7 @@ export default function GitActionsControl({
20041996 }
20051997 }}
20061998 >
2007 <DialogPopup
2008 backdropClassName="bg-black/40 backdrop-blur-none"
2009 className="workflow-dialog-surface max-w-xl before:hidden"
2010 >
1999 <DialogPopup className="max-w-xl">
20112000 <DialogHeader>
20122001 <DialogTitle>
20132002 {pendingDefaultBranchActionCopy?.title ?? "Run action on default refName?"}
apps/web/src/components/ProjectScriptsControl.tsx+1-1
......@@ -461,7 +461,7 @@ export default function ProjectScriptsControl({
461461 }}
462462 open={dialogOpen}
463463 >
464 <DialogPopup className="before:hidden">
464 <DialogPopup>
465465 <DialogHeader>
466466 <DialogTitle>{isEditing ? "Edit Action" : "Add Action"}</DialogTitle>
467467 <DialogDescription>
apps/web/src/components/SidebarV2.tsx+7-7
......@@ -677,13 +677,13 @@ const SidebarV2Row = memo(function SidebarV2Row(props: {
677677 <span className="text-red-600 dark:text-red-400">−{diff.deletions}</span>
678678 </span>
679679 ) : null}
680 <span className="ml-auto inline-flex shrink-0 items-center gap-1">
680 <span
681 aria-hidden
682 className="pointer-events-none ml-auto inline-flex shrink-0 items-center gap-1"
683 >
681684 {isRemote ? (
682 <span
683 aria-label={props.environmentLabel ?? "Remote environment"}
684 className="inline-flex shrink-0 items-center text-sidebar-muted-foreground/70"
685 >
686 <ServerIcon aria-hidden className="size-4" />
685 <span className="inline-flex shrink-0 items-center text-sidebar-muted-foreground/70">
686 <ServerIcon aria-hidden className="size-3.5" />
687687 </span>
688688 ) : null}
689689 {driverKind ? (
......@@ -691,7 +691,7 @@ const SidebarV2Row = memo(function SidebarV2Row(props: {
691691 <ProviderInstanceIcon
692692 driverKind={driverKind}
693693 displayName={thread.session?.providerName ?? modelInstanceId}
694 iconClassName="size-4"
694 iconClassName="size-3.5"
695695 />
696696 </span>
697697 ) : null}
apps/web/src/components/chat/ChangedFilesTree.tsx+2-2
......@@ -41,8 +41,8 @@ export const ChangedFilesCard = memo(function ChangedFilesCard(props: {
4141 const summaryStat = useMemo(() => summarizeTurnDiffStats(files), [files]);
4242
4343 return (
44 <div className="mt-4 rounded-2xl bg-background p-2 pt-4 shadow-xs/5 not-dark:bg-clip-padding dark:bg-input/32">
45 <div className="sticky top-0 z-10 mb-3 flex items-center justify-between gap-2 bg-background px-2 before:absolute before:inset-x-0 before:-top-4 before:h-4 before:bg-background before:content-[''] dark:bg-[color-mix(in_srgb,var(--foreground)_2.5%,var(--background))] dark:before:bg-[color-mix(in_srgb,var(--foreground)_2.5%,var(--background))]">
44 <div className="mt-4 rounded-2xl border border-border/70 bg-secondary p-2 pt-4 dark:border-transparent dark:bg-input/32">
45 <div className="sticky top-0 z-10 mb-3 flex items-center justify-between gap-2 bg-secondary px-2 before:absolute before:inset-x-0 before:-top-4 before:h-4 before:bg-secondary before:content-[''] dark:bg-[color-mix(in_srgb,var(--foreground)_2.5%,var(--background))] dark:before:bg-[color-mix(in_srgb,var(--foreground)_2.5%,var(--background))]">
4646 <p className="flex items-center gap-1 whitespace-nowrap font-medium text-foreground text-xs leading-4">
4747 <span>
4848 {files.length} changed file{files.length === 1 ? "" : "s"}
apps/web/src/components/chat/ComposerCommandMenu.tsx+1-4
......@@ -139,10 +139,7 @@ export const ComposerCommandMenu = memo(function ComposerCommandMenu(props: {
139139 );
140140 }}
141141 >
142 <div
143 ref={listRef}
144 className="relative w-full overflow-hidden rounded-[20px] border border-border/80 bg-popover/96 shadow-lg/8 backdrop-blur-xs"
145 >
142 <div ref={listRef} className="dropdown-glass relative w-full overflow-hidden rounded-[20px]">
146143 {props.items.length > 0 ? (
147144 <CommandList className="max-h-72">
148145 {groups.map((group, groupIndex) => (
apps/web/src/components/chat/MessagesTimeline.tsx+2-2
......@@ -1285,8 +1285,8 @@ function AssistantChangedFilesSectionInner({
12851285 const summaryStat = summarizeTurnDiffStats(checkpointFiles);
12861286
12871287 return (
1288 <div className="mt-4 rounded-2xl bg-background p-2 pt-4 shadow-xs/5 not-dark:bg-clip-padding dark:bg-input/32">
1289 <div className="sticky top-2 z-10 mb-3 flex items-center justify-between gap-2 bg-background px-2 before:absolute before:inset-x-0 before:-top-4 before:h-4 before:bg-background before:content-[''] dark:bg-[color-mix(in_srgb,var(--foreground)_2.5%,var(--background))] dark:before:bg-[color-mix(in_srgb,var(--foreground)_2.5%,var(--background))]">
1288 <div className="mt-4 rounded-2xl border border-border/70 bg-secondary p-2 pt-4 dark:border-transparent dark:bg-input/32">
1289 <div className="sticky top-2 z-10 mb-3 flex items-center justify-between gap-2 bg-secondary px-2 before:absolute before:inset-x-0 before:-top-4 before:h-4 before:bg-secondary before:content-[''] dark:bg-[color-mix(in_srgb,var(--foreground)_2.5%,var(--background))] dark:before:bg-[color-mix(in_srgb,var(--foreground)_2.5%,var(--background))]">
12901290 <p className="flex items-center gap-1 whitespace-nowrap font-medium text-foreground text-xs leading-4">
12911291 <span>
12921292 {checkpointFiles.length} changed file{checkpointFiles.length === 1 ? "" : "s"}
apps/web/src/components/clerk/T3ConnectSidebarSignIn.tsx+2-2
......@@ -55,10 +55,10 @@ function ConfiguredT3ConnectSidebarSignIn() {
5555 <SidebarMenuItem>
5656 <SidebarMenuButton
5757 size="sm"
58 className="gap-2 px-2 py-2 text-xs text-muted-foreground hover:bg-accent hover:text-foreground"
58 className="h-8 items-center gap-2 rounded-md px-2 py-1.5 text-sm font-medium text-sidebar-muted-foreground/80 hover:bg-sidebar-row-hover hover:text-sidebar-foreground"
5959 onClick={openAuthPrompt}
6060 >
61 <LogInIcon className="size-4" />
61 <LogInIcon className="size-4 shrink-0" />
6262 <span>Sign in to T3 Connect</span>
6363 </SidebarMenuButton>
6464 </SidebarMenuItem>
apps/web/src/components/settings/AddProviderInstanceDialog.tsx+17-20
......@@ -1,6 +1,7 @@
11"use client";
22
33import { Radio as RadioPrimitive } from "@base-ui/react/radio";
4import { CheckIcon } from "lucide-react";
45import { useMemo, useState } from "react";
56import {
67 ProviderInstanceId,
......@@ -223,7 +224,7 @@ export function AddProviderInstanceDialog({ open, onOpenChange }: AddProviderIns
223224 <Dialog open={open} onOpenChange={onOpenChange}>
224225 <DialogPopup className="max-w-xl overflow-hidden">
225226 <div className="flex min-h-0 flex-col overflow-hidden">
226 <DialogHeader className="border-b border-border/70">
227 <DialogHeader>
227228 <DialogTitle>Add provider instance</DialogTitle>
228229 <DialogDescription>
229230 Configure an additional provider instance — for example, a second Codex install
......@@ -239,41 +240,37 @@ export function AddProviderInstanceDialog({ open, onOpenChange }: AddProviderIns
239240
240241 <div
241242 data-slot="dialog-panel"
242 className="space-y-4 border-b border-border/70 bg-foreground/[0.025] px-6 py-5"
243 className="space-y-4 bg-zinc-25/80 px-6 py-5 ring-1 ring-black/5 dark:bg-white/2 dark:ring-white/5"
243244 >
244245 <AnimatedHeight>
245246 <div className={cn("grid gap-2", wizardStep !== 0 && "hidden")}>
246 <span
247 id="add-instance-driver-label"
248 className="text-xs font-medium text-foreground"
249 >
247 <div id="add-instance-driver-label" className="text-sm font-medium text-foreground">
250248 Driver
251 </span>
249 </div>
252250 <RadioGroup
253251 value={driver}
254252 onValueChange={(value) => setDriver(ProviderDriverKind.make(value))}
255253 aria-labelledby="add-instance-driver-label"
256 className="grid grid-cols-2 gap-2.5"
254 className="grid grid-cols-1 gap-2 sm:grid-cols-2"
257255 >
258256 {DRIVER_OPTIONS.map((option) => {
259257 const IconComponent = option.icon;
260 const isSelected = option.value === driver;
261258 return (
262259 <RadioPrimitive.Root
263260 key={option.value}
264261 value={option.value}
265 className={cn(
266 "relative flex cursor-pointer items-center gap-3 rounded-lg border px-3 py-3 text-left outline-none transition-[background-color,border-color,box-shadow]",
267 "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background",
268 isSelected
269 ? "border-primary bg-background shadow-sm ring-2 ring-primary/35"
270 : "border-border bg-background hover:border-foreground/20 hover:bg-muted/50",
271 )}
262 className="relative flex cursor-pointer items-center gap-3 rounded-lg bg-card px-3 py-3 text-left text-muted-foreground outline-none ring-1 ring-black/5 hover:bg-zinc-50 focus-visible:ring-2 focus-visible:ring-ring data-checked:bg-primary/8 data-checked:text-foreground data-checked:ring-2 data-checked:ring-primary data-checked:hover:bg-primary/8 dark:bg-white/3 dark:ring-white/5 dark:hover:bg-white/5 dark:data-checked:bg-primary/15 dark:data-checked:ring-primary dark:data-checked:hover:bg-primary/15"
272263 >
273 <IconComponent className="size-5 shrink-0" aria-hidden />
264 <IconComponent className="size-4 shrink-0" aria-hidden />
274265 <span className="min-w-0 flex-1 truncate text-sm font-medium text-foreground">
275266 {option.label}
276267 </span>
268 <RadioPrimitive.Indicator
269 className="grid size-5 shrink-0 place-items-center rounded-full bg-primary text-primary-foreground"
270 aria-hidden
271 >
272 <CheckIcon className="size-3.5 shrink-0" />
273 </RadioPrimitive.Indicator>
277274 {option.badgeLabel ? (
278275 <Badge variant="warning" size="sm">
279276 {option.badgeLabel}
......@@ -290,11 +287,11 @@ export function AddProviderInstanceDialog({ open, onOpenChange }: AddProviderIns
290287 value={option.value}
291288 disabled
292289 className={cn(
293 "relative flex cursor-not-allowed items-center gap-3 rounded-lg border border-border bg-background px-3 py-3 text-left opacity-55 outline-none",
290 "relative flex cursor-not-allowed items-center gap-3 rounded-lg bg-card/60 px-3 py-3 text-left opacity-55 outline-none ring-1 ring-black/5 dark:bg-white/2 dark:ring-white/5",
294291 )}
295292 >
296293 <IconComponent
297 className="size-5 shrink-0 text-muted-foreground"
294 className="size-4 shrink-0 text-muted-foreground"
298295 aria-hidden
299296 />
300297 <span className="min-w-0 flex-1 truncate text-sm font-medium text-foreground">
......@@ -409,7 +406,7 @@ export function AddProviderInstanceDialog({ open, onOpenChange }: AddProviderIns
409406 </AnimatedHeight>
410407 </div>
411408
412 <DialogFooter className="border-t bg-transparent">
409 <DialogFooter variant="bare">
413410 <Button
414411 variant="outline"
415412 size="sm"
apps/web/src/components/settings/AddProviderInstanceWizardSteps.test.tsx+7-3
......@@ -9,6 +9,10 @@ interface StepButtonProps {
99 readonly onClick: () => void;
1010}
1111
12interface StepListItemProps {
13 readonly children: ReactElement<StepButtonProps>;
14}
15
1216function renderStepButtons(
1317 currentStep: number,
1418 instanceIdError: string | null,
......@@ -21,9 +25,9 @@ function renderStepButtons(
2125 onNavigation,
2226 });
2327
24 return Children.toArray(header.props.children).filter(
25 (child): child is ReactElement<StepButtonProps> => isValidElement(child),
26 );
28 return Children.toArray(header.props.children)
29 .filter((child): child is ReactElement<StepListItemProps> => isValidElement(child))
30 .map((item) => item.props.children);
2731}
2832
2933describe("AddProviderInstanceWizardSteps", () => {
apps/web/src/components/settings/AddProviderInstanceWizardSteps.tsx+43-40
......@@ -21,50 +21,53 @@ export function AddProviderInstanceWizardSteps({
2121 onNavigation,
2222}: AddProviderInstanceWizardStepsProps) {
2323 return (
24 <div className="grid grid-cols-3 gap-2">
24 <ol
25 className="grid grid-cols-3 gap-1 rounded-xl bg-zinc-25 p-1 ring-1 ring-black/5 dark:bg-white/4 dark:ring-white/5"
26 role="list"
27 >
2528 {ADD_PROVIDER_WIZARD_STEPS.map((step, index) => (
26 <button
27 key={step}
28 type="button"
29 className={cn(
30 "grid min-w-0 grid-cols-[1rem_minmax(0,1fr)] gap-x-2 rounded-lg border px-3 py-2 text-left",
31 index === currentStep
32 ? "border-primary bg-primary/10 ring-1 ring-primary/25"
33 : index < currentStep
34 ? "border-border bg-background"
35 : "border-border bg-muted/40",
36 )}
37 aria-current={index === currentStep ? "step" : undefined}
38 onClick={() =>
39 onNavigation(
40 resolveWizardNavigation(currentStep, index, ADD_PROVIDER_WIZARD_STEPS.length, {
41 instanceIdError,
42 }),
43 )
44 }
45 >
46 <span
29 <li key={step} className="min-w-0">
30 <button
31 type="button"
4732 className={cn(
48 "row-span-2 mt-0.5 grid size-4 place-items-center rounded-full border",
49 index < currentStep
50 ? "border-primary bg-primary text-primary-foreground"
51 : index === currentStep
52 ? "border-primary bg-background"
53 : "border-muted-foreground/35 bg-background",
33 "flex w-full min-w-0 cursor-pointer items-center gap-2 rounded-lg px-2.5 py-2 text-left outline-none hover:bg-card focus-visible:ring-2 focus-visible:ring-ring max-sm:justify-center max-sm:px-2",
34 index === currentStep &&
35 "bg-card text-foreground shadow-xs ring-1 ring-black/5 hover:bg-card dark:shadow-none dark:ring-white/5",
5436 )}
55 aria-hidden
37 aria-current={index === currentStep ? "step" : undefined}
38 aria-label={`${step}, step ${index + 1}${index < currentStep && summaries[index] ? `, ${summaries[index]}` : ""}`}
39 onClick={() =>
40 onNavigation(
41 resolveWizardNavigation(currentStep, index, ADD_PROVIDER_WIZARD_STEPS.length, {
42 instanceIdError,
43 }),
44 )
45 }
5646 >
57 {index < currentStep ? <CheckIcon className="size-3" /> : null}
58 </span>
59 <span className="text-[10px] font-medium uppercase text-muted-foreground">
60 Step {index + 1}
61 </span>
62 <span className="truncate text-xs font-semibold text-foreground">
63 {step}
64 {index < currentStep && summaries[index] ? `: ${summaries[index]}` : ""}
65 </span>
66 </button>
47 <span
48 className={cn(
49 "grid size-5 shrink-0 place-items-center rounded-full text-sm font-medium ring-1",
50 index < currentStep
51 ? "bg-primary text-primary-foreground ring-primary"
52 : index === currentStep
53 ? "bg-primary/10 text-primary ring-primary/30"
54 : "bg-card text-muted-foreground ring-black/10 dark:bg-white/5 dark:ring-white/10",
55 )}
56 aria-hidden
57 >
58 {index < currentStep ? <CheckIcon className="size-4 shrink-0" /> : index + 1}
59 </span>
60 <span
61 className={cn(
62 "min-w-0 truncate text-sm font-medium max-sm:hidden",
63 index === currentStep ? "text-foreground" : "text-muted-foreground",
64 )}
65 >
66 {step}
67 </span>
68 </button>
69 </li>
6770 ))}
68 </div>
71 </ol>
6972 );
7073}
apps/web/src/components/ui/alert-dialog.tsx+3-3
......@@ -19,7 +19,7 @@ function AlertDialogBackdrop({ className, ...props }: AlertDialogPrimitive.Backd
1919 <AlertDialogPrimitive.Backdrop
2020 forceRender
2121 className={cn(
22 "fixed inset-0 z-50 bg-black/20 backdrop-blur-[2px] transition-all duration-200 data-ending-style:opacity-0 data-starting-style:opacity-0 dark:bg-black/55",
22 "dialog-backdrop fixed inset-0 z-50 transition-all duration-200 data-ending-style:opacity-0 data-starting-style:opacity-0",
2323 className,
2424 )}
2525 data-slot="alert-dialog-backdrop"
......@@ -56,9 +56,9 @@ function AlertDialogPopup({
5656 >
5757 <AlertDialogPrimitive.Popup
5858 className={cn(
59 "dialog-glass -translate-y-[calc(1.25rem*var(--nested-dialogs))] relative row-start-2 flex max-h-full min-h-0 w-full min-w-0 max-w-lg scale-[calc(1-0.1*var(--nested-dialogs))] flex-col rounded-2xl border border-border/70 text-popover-foreground opacity-[calc(1-0.1*var(--nested-dialogs))] transition-[scale,opacity,translate] duration-200 ease-in-out will-change-transform before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-2xl)-1px)] before:shadow-[0_1px_--theme(--color-black/4%)] data-nested:data-ending-style:translate-y-8 data-nested:data-starting-style:translate-y-8 data-nested-dialog-open:origin-top data-ending-style:scale-98 data-starting-style:scale-98 data-ending-style:opacity-0 data-starting-style:opacity-0 dark:before:shadow-[0_-1px_--theme(--color-white/6%)]",
59 "dialog-glass -translate-y-[calc(1.25rem*var(--nested-dialogs))] relative row-start-2 flex max-h-full min-h-0 w-full min-w-0 max-w-lg scale-[calc(1-0.1*var(--nested-dialogs))] flex-col rounded-2xl border text-popover-foreground opacity-[calc(1-0.1*var(--nested-dialogs))] outline-none transition-[scale,opacity,translate] duration-200 ease-in-out will-change-transform data-nested:data-ending-style:translate-y-8 data-nested:data-starting-style:translate-y-8 data-nested-dialog-open:origin-top data-ending-style:scale-98 data-starting-style:scale-98 data-ending-style:opacity-0 data-starting-style:opacity-0",
6060 bottomStickOnMobile &&
61 "max-sm:max-w-none max-sm:rounded-none max-sm:border-x-0 max-sm:border-t max-sm:border-b-0 max-sm:opacity-[calc(1-min(var(--nested-dialogs),1))] max-sm:data-ending-style:translate-y-4 max-sm:data-starting-style:translate-y-4 max-sm:before:hidden max-sm:before:rounded-none",
61 "max-sm:max-w-none max-sm:rounded-none max-sm:border-x-0 max-sm:border-t max-sm:border-b-0 max-sm:opacity-[calc(1-min(var(--nested-dialogs),1))] max-sm:data-ending-style:translate-y-4 max-sm:data-starting-style:translate-y-4",
6262 className,
6363 )}
6464 data-slot="alert-dialog-popup"
apps/web/src/components/ui/button.tsx+1-1
......@@ -40,7 +40,7 @@ const buttonVariants = cva(
4040 "border-transparent text-foreground data-pressed:bg-accent [:hover,[data-pressed]]:bg-accent [&_svg:not([class*='text-'])]:text-muted-foreground",
4141 link: "border-transparent underline-offset-4 [:hover,[data-pressed]]:underline",
4242 outline:
43 "border-transparent bg-popover not-dark:bg-clip-padding text-foreground shadow-none dark:bg-input/32 [:hover,[data-pressed]]:bg-accent/50 dark:[:hover,[data-pressed]]:bg-input/64 [&_svg:not([class*='text-'])]:text-muted-foreground",
43 "border-input bg-popover not-dark:bg-clip-padding text-foreground shadow-xs/5 not-disabled:not-active:not-data-pressed:before:shadow-[0_1px_--theme(--color-black/4%)] dark:bg-input/32 dark:not-disabled:before:shadow-[0_-1px_--theme(--color-white/2%)] dark:not-disabled:not-active:not-data-pressed:before:shadow-[0_-1px_--theme(--color-white/6%)] [:disabled,:active,[data-pressed]]:shadow-none [:hover,[data-pressed]]:bg-accent/50 dark:[:hover,[data-pressed]]:bg-input/64 [&_svg:not([class*='text-'])]:text-muted-foreground",
4444 secondary:
4545 "border-transparent bg-secondary text-secondary-foreground [:active,[data-pressed]]:bg-secondary/80 [:hover,[data-pressed]]:bg-secondary/90",
4646 },
apps/web/src/components/ui/command.tsx+2-2
......@@ -30,7 +30,7 @@ function CommandDialogBackdrop({ className, ...props }: CommandDialogPrimitive.B
3030 return (
3131 <CommandDialogPrimitive.Backdrop
3232 className={cn(
33 "fixed inset-0 z-50 bg-black/20 backdrop-blur-[2px] transition-opacity duration-200 data-ending-style:opacity-0 data-starting-style:opacity-0 dark:bg-black/55",
33 "dialog-backdrop fixed inset-0 z-50 transition-all duration-200 data-ending-style:opacity-0 data-starting-style:opacity-0",
3434 className,
3535 )}
3636 data-slot="command-dialog-backdrop"
......@@ -66,7 +66,7 @@ function CommandDialogPopup({
6666 <CommandDialogViewport>
6767 <CommandDialogPrimitive.Popup
6868 className={cn(
69 "chat-composer-glass command-palette-glass pointer-events-auto -translate-y-[calc(1.25rem*var(--nested-dialogs))] relative row-start-2 flex max-h-105 min-h-0 w-full min-w-0 max-w-xl scale-[calc(1-0.1*var(--nested-dialogs))] flex-col rounded-2xl bg-[color-mix(in_srgb,var(--background)_var(--glass-opacity),transparent)] text-foreground opacity-[calc(1-0.1*var(--nested-dialogs))] outline-none transition-[scale,opacity,translate] duration-200 ease-in-out will-change-transform data-nested:data-ending-style:translate-y-8 data-nested:data-starting-style:translate-y-8 data-nested-dialog-open:origin-top data-ending-style:scale-98 data-starting-style:scale-98 data-ending-style:opacity-0 data-starting-style:opacity-0 **:data-[slot=scroll-area-viewport]:data-has-overflow-y:pe-1",
69 "dialog-glass pointer-events-auto -translate-y-[calc(1.25rem*var(--nested-dialogs))] relative row-start-2 flex max-h-105 min-h-0 w-full min-w-0 max-w-xl scale-[calc(1-0.1*var(--nested-dialogs))] flex-col rounded-2xl border text-foreground opacity-[calc(1-0.1*var(--nested-dialogs))] outline-none transition-[scale,opacity,translate] duration-200 ease-in-out will-change-transform data-nested:data-ending-style:translate-y-8 data-nested:data-starting-style:translate-y-8 data-nested-dialog-open:origin-top data-ending-style:scale-98 data-starting-style:scale-98 data-ending-style:opacity-0 data-starting-style:opacity-0 **:data-[slot=scroll-area-viewport]:data-has-overflow-y:pe-1",
7070 className,
7171 )}
7272 data-slot="command-dialog-popup"
apps/web/src/components/ui/dialog.tsx+4-5
......@@ -25,7 +25,7 @@ function DialogBackdrop({ className, ...props }: DialogPrimitive.Backdrop.Props)
2525 <DialogPrimitive.Backdrop
2626 forceRender
2727 className={cn(
28 "fixed inset-0 z-50 bg-black/20 backdrop-blur-[2px] transition-all duration-200 data-ending-style:opacity-0 data-starting-style:opacity-0 dark:bg-black/55",
28 "dialog-backdrop fixed inset-0 z-50 transition-all duration-200 data-ending-style:opacity-0 data-starting-style:opacity-0",
2929 className,
3030 )}
3131 data-slot="dialog-backdrop"
......@@ -67,9 +67,9 @@ function DialogPopup({
6767 >
6868 <DialogPrimitive.Popup
6969 className={cn(
70 "dialog-glass -translate-y-[calc(1.25rem*var(--nested-dialogs))] relative row-start-2 flex max-h-full min-h-0 w-full min-w-0 max-w-lg scale-[calc(1-0.1*var(--nested-dialogs))] flex-col rounded-2xl border border-border/70 text-popover-foreground opacity-[calc(1-0.1*var(--nested-dialogs))] transition-[scale,opacity,translate] duration-200 ease-in-out will-change-transform before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-2xl)-1px)] before:shadow-[0_1px_--theme(--color-black/4%)] data-nested:data-ending-style:translate-y-8 data-nested:data-starting-style:translate-y-8 data-nested-dialog-open:origin-top data-ending-style:scale-98 data-starting-style:scale-98 data-ending-style:opacity-0 data-starting-style:opacity-0 dark:before:shadow-[0_-1px_--theme(--color-white/6%)]",
70 "dialog-glass -translate-y-[calc(1.25rem*var(--nested-dialogs))] relative row-start-2 flex max-h-full min-h-0 w-full min-w-0 max-w-lg scale-[calc(1-0.1*var(--nested-dialogs))] flex-col rounded-2xl border text-popover-foreground opacity-[calc(1-0.1*var(--nested-dialogs))] outline-none transition-[scale,opacity,translate] duration-200 ease-in-out will-change-transform data-nested:data-ending-style:translate-y-8 data-nested:data-starting-style:translate-y-8 data-nested-dialog-open:origin-top data-ending-style:scale-98 data-starting-style:scale-98 data-ending-style:opacity-0 data-starting-style:opacity-0",
7171 bottomStickOnMobile &&
72 "max-sm:max-w-none max-sm:rounded-none max-sm:border-x-0 max-sm:border-t max-sm:border-b-0 max-sm:opacity-[calc(1-min(var(--nested-dialogs),1))] max-sm:data-ending-style:translate-y-4 max-sm:data-starting-style:translate-y-4 max-sm:before:hidden max-sm:before:rounded-none",
72 "max-sm:max-w-none max-sm:rounded-none max-sm:border-x-0 max-sm:border-t max-sm:border-b-0 max-sm:opacity-[calc(1-min(var(--nested-dialogs),1))] max-sm:data-ending-style:translate-y-4 max-sm:data-starting-style:translate-y-4",
7373 className,
7474 )}
7575 data-slot="dialog-popup"
......@@ -116,8 +116,7 @@ function DialogFooter({
116116 className={cn(
117117 "flex flex-col-reverse gap-2 px-6 sm:flex-row sm:justify-end sm:rounded-b-[calc(var(--radius-2xl)-1px)]",
118118 variant === "default" && "border-t bg-muted/72 py-4",
119 variant === "bare" &&
120 "in-[[data-slot=dialog-popup]:has([data-slot=dialog-panel])]:pt-3 pt-4 pb-6",
119 variant === "bare" && "py-4",
121120 className,
122121 )}
123122 data-slot="dialog-footer"
apps/web/src/index.css+107-109
......@@ -77,7 +77,9 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
7777
7878:root {
7979 --app-scrollbar-width: 6px;
80 --glass-blur: 12px;
8081 --glass-opacity: 80%;
82 --glass-saturation: 1.14;
8183 --desktop-window-right-resize-inset: 0px;
8284 --workspace-topbar-height: 52px;
8385 --workspace-controls-top: 0px;
......@@ -88,6 +90,11 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
8890 --workspace-titlebar-control-gap: 0.75rem;
8991}
9092
93.dark {
94 --glass-blur: 16px;
95 --glass-saturation: 1.08;
96}
97
9198[data-slot="sidebar-wrapper"] {
9299 --workspace-titlebar-content-left: calc(
93100 var(--workspace-controls-left) + var(--workspace-titlebar-control-size) +
......@@ -108,6 +115,7 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
108115}
109116
110117@theme inline {
118 --color-zinc-25: oklch(99.2% 0 0);
111119 --animate-skeleton: skeleton 2s -1s infinite linear;
112120 /* Duty-cycled indicator animations: long holds with stepped ramps, so the
113121 compositor updates discrete frames instead of every vsync. */
......@@ -365,25 +373,39 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
365373
366374 .chat-composer-glass {
367375 background: color-mix(in srgb, var(--background) var(--glass-opacity), transparent);
368 -webkit-backdrop-filter: blur(16px);
369 backdrop-filter: blur(16px);
376 -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
377 backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
370378 }
371379
372380 .chat-composer-glass-host {
373 --chat-composer-glass-surface: color-mix(in srgb, var(--background) 96%, var(--color-black));
381 --chat-composer-glass-surface: var(--card);
382
383 position: relative;
384 isolation: isolate;
385 box-shadow:
386 0 0 0 1px rgb(0 0 0 / 8%),
387 0 12px 28px -18px rgb(0 0 0 / 40%);
388 }
374389
390 .chat-composer-glass-host::before {
391 position: absolute;
392 z-index: -1;
393 inset: 0;
394 border-radius: inherit;
375395 background: color-mix(
376396 in srgb,
377397 var(--chat-composer-glass-surface) var(--glass-opacity),
378398 transparent
379399 );
380 box-shadow: 0 12px 28px -18px rgb(0 0 0 / 40%);
381 -webkit-backdrop-filter: blur(16px);
382 backdrop-filter: blur(16px);
400 -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
401 backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
402 content: "";
383403 }
384404
385405 .dark .chat-composer-glass-host {
386 --chat-composer-glass-surface: color-mix(in srgb, var(--background) 96%, var(--color-white));
406 --chat-composer-glass-surface: color-mix(in srgb, var(--background) 84%, var(--color-white));
407
408 box-shadow: 0 0 0 1px rgb(255 255 255 / 10%);
387409 }
388410
389411 .alert-glass {
......@@ -395,8 +417,8 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
395417 color-mix(in srgb, var(--alert-glass-tint) 4%, transparent)
396418 ),
397419 color-mix(in srgb, var(--background) var(--glass-opacity), transparent) !important;
398 -webkit-backdrop-filter: blur(16px) saturate(1.1);
399 backdrop-filter: blur(16px) saturate(1.1);
420 -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
421 backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
400422 }
401423
402424 .alert-glass[data-variant="error"] {
......@@ -416,12 +438,16 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
416438 }
417439
418440 .dropdown-glass,
419 .dialog-glass,
420 .workflow-dialog-surface,
421 .command-palette-dialog-surface {
441 .dialog-glass {
422442 background: color-mix(in srgb, var(--background) var(--glass-opacity), transparent);
423 -webkit-backdrop-filter: blur(16px);
424 backdrop-filter: blur(16px);
443 -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
444 backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
445 }
446
447 .dialog-backdrop {
448 background: color-mix(in srgb, var(--background) 60%, transparent);
449 -webkit-backdrop-filter: blur(4px);
450 backdrop-filter: blur(4px);
425451 }
426452
427453 .dropdown-glass {
......@@ -429,30 +455,12 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
429455 box-shadow: 0 16px 40px -18px rgb(0 0 0 / 55%);
430456 }
431457
432 .command-palette-glass {
433 box-shadow: 0 24px 64px -24px rgb(0 0 0 / 65%);
434 }
435
436 .command-menu-surface {
437 background: color-mix(in srgb, var(--background) var(--glass-opacity), transparent);
438 -webkit-backdrop-filter: blur(16px);
439 backdrop-filter: blur(16px);
440 box-shadow: 0 24px 64px -24px rgb(0 0 0 / 65%);
441 }
442
443 .workflow-dialog-surface {
458 .dialog-glass {
444459 border-color: color-mix(in srgb, var(--foreground) 10%, transparent);
445460 box-shadow: 0 24px 64px -24px rgb(0 0 0 / 65%);
446461 }
447462
448 .command-palette-dialog-surface {
449 border-color: color-mix(in srgb, var(--foreground) 10%, transparent) !important;
450 background: color-mix(in srgb, var(--background) var(--glass-opacity), transparent) !important;
451 box-shadow: 0 24px 64px -24px rgb(0 0 0 / 65%) !important;
452 }
453
454 .dark .dropdown-glass,
455 .dark .dialog-glass {
463 .dark .dropdown-glass {
456464 box-shadow: 0 18px 44px -18px rgb(0 0 0 / 80%);
457465 }
458466
......@@ -460,33 +468,15 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
460468 background: color-mix(in srgb, var(--background) var(--glass-opacity), transparent);
461469 }
462470
463 .dark .command-menu-surface,
464 .dark .command-palette-glass,
465 .dark .workflow-dialog-surface {
466 box-shadow: none;
467 }
468
469 .dark .command-palette-dialog-surface {
470 box-shadow: none !important;
471 }
472
473 .dark
474 .command-palette-dialog-surface
475 :is([data-slot="input-control"], [data-slot="textarea-control"]) {
476 background: var(--secondary) !important;
477 }
478
479 .dark
480 .command-palette-dialog-surface
481 :is([data-slot="input-control"], [data-slot="textarea-control"]):not(:has(:focus-visible)) {
482 border-color: transparent !important;
483 box-shadow: none !important;
471 .dark .dialog-glass {
472 border-color: color-mix(in srgb, var(--color-white) 14%, transparent);
473 box-shadow:
474 inset 0 1px rgb(255 255 255 / 4%),
475 0 24px 72px -20px rgb(0 0 0 / 90%);
484476 }
485477
486 .dark
487 .command-palette-dialog-surface
488 :is([data-slot="input-control"], [data-slot="textarea-control"])::before {
489 box-shadow: none !important;
478 .dark .dialog-backdrop {
479 background: color-mix(in srgb, var(--background) 64%, transparent);
490480 }
491481
492482 .glass-opacity-slider {
......@@ -622,15 +612,12 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
622612 background: var(--background) !important;
623613 }
624614
625 .chat-composer-glass-host {
615 .chat-composer-glass-host::before {
626616 background: var(--chat-composer-glass-surface);
627617 }
628618
629619 .dialog-glass,
630 .dropdown-glass,
631 .command-menu-surface,
632 .command-palette-dialog-surface,
633 .workflow-dialog-surface {
620 .dropdown-glass {
634621 background: var(--popover) !important;
635622 }
636623 }
......@@ -673,25 +660,25 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
673660:root {
674661 color-scheme: light;
675662 --radius: 0.625rem;
676 --background: var(--color-white);
663 --background: var(--color-zinc-25);
677664 --app-chrome-background: var(--background);
678 --surface-raised: var(--secondary);
679 --foreground: var(--color-neutral-800);
665 --surface-raised: color-mix(in srgb, var(--card) 20%, transparent);
666 --foreground: var(--color-zinc-800);
680667 --card: var(--color-white);
681 --card-foreground: var(--color-neutral-800);
668 --card-foreground: var(--color-zinc-800);
682669 --popover: var(--color-white);
683 --popover-foreground: var(--color-neutral-800);
670 --popover-foreground: var(--color-zinc-800);
684671 --primary: oklch(0.488 0.217 264);
685672 --primary-foreground: var(--color-white);
686 --secondary: --alpha(var(--color-black) / 4%);
687 --secondary-foreground: var(--color-neutral-800);
688 --muted: --alpha(var(--color-black) / 4%);
689 --muted-foreground: color-mix(in srgb, var(--color-neutral-500) 90%, var(--color-black));
690 --accent: --alpha(var(--color-black) / 4%);
691 --accent-foreground: var(--color-neutral-800);
673 --secondary: var(--color-zinc-50);
674 --secondary-foreground: var(--color-zinc-800);
675 --muted: var(--color-zinc-50);
676 --muted-foreground: var(--color-zinc-500);
677 --accent: var(--color-zinc-100);
678 --accent-foreground: var(--color-zinc-900);
692679 --destructive: var(--color-red-500);
693 --border: --alpha(var(--color-black) / 8%);
694 --input: --alpha(var(--color-black) / 10%);
680 --border: var(--color-zinc-200);
681 --input: var(--color-zinc-300);
695682 --ring: oklch(0.488 0.217 264);
696683 --destructive-foreground: var(--color-red-700);
697684 --info: var(--color-blue-500);
......@@ -700,16 +687,17 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
700687 --success-foreground: var(--color-emerald-700);
701688 --warning: var(--color-amber-500);
702689 --warning-foreground: var(--color-amber-700);
703 /* Fallbacks for standalone sidebar primitives. App sidebars override these
704 roles on their own root so the surface hierarchy stays out of page content. */
705 --sidebar: var(--card);
690 /* Keep every sidebar primitive on the same light surface hierarchy, including
691 portaled mobile sheets and settings navigation outside the app sidebar. */
692 --sidebar: var(--color-zinc-50);
706693 --sidebar-foreground: var(--foreground);
707694 --sidebar-muted-foreground: var(--muted-foreground);
708 --sidebar-control-surface: var(--accent);
709 --sidebar-row-hover: var(--accent);
710 --sidebar-row-active: var(--accent);
711 --sidebar-row-selected: var(--muted);
695 --sidebar-control-surface: var(--color-zinc-100);
696 --sidebar-row-hover: var(--color-zinc-25);
697 --sidebar-row-active: var(--color-white);
698 --sidebar-row-selected: var(--color-white);
712699 --sidebar-border: var(--border);
700 --sidebar-stage-fade: var(--sidebar);
713701
714702 @variant dark {
715703 color-scheme: dark;
......@@ -742,34 +730,44 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
742730 --success-foreground: var(--color-emerald-400);
743731 --warning: var(--color-amber-500);
744732 --warning-foreground: var(--color-amber-400);
745 }
746}
747
748/* Give both navigation implementations the same cool graphite surface. The
749 version attribute remains useful for layout-specific styling, but color is
750 shared so switching the beta does not switch visual systems. */
733 --sidebar: var(--card);
734 --sidebar-foreground: var(--foreground);
735 --sidebar-muted-foreground: var(--muted-foreground);
736 --sidebar-control-surface: var(--muted);
737 --sidebar-row-hover: var(--accent);
738 --sidebar-row-active: var(--accent);
739 --sidebar-row-selected: var(--muted);
740 --sidebar-border: var(--border);
741 --sidebar-stage-fade: var(--card);
742 }
743}
744
745/* Keep both navigation implementations on the same quiet zinc hierarchy:
746 zinc-50 navigation, zinc-25 hover, and white selected/raised surfaces.
747 The version attribute remains useful for layout-specific styling without
748 changing the color system when the beta is toggled. */
751749[data-sidebar-version="v1"],
752750[data-sidebar-version="v2"] {
753 --background: oklch(0.965 0.009 265);
754 --foreground: oklch(0.27 0.025 265);
755 --card: oklch(0.945 0.014 265);
756 --card-foreground: var(--foreground);
757 --accent: oklch(0.875 0.008 265);
758 --accent-foreground: oklch(0.24 0.012 265);
759 --muted: oklch(0.9 0.018 265);
760 --muted-foreground: oklch(0.49 0.03 265);
761 --border: oklch(0.72 0.025 265 / 28%);
762 --input: oklch(0.62 0.03 265 / 28%);
763 --sidebar: var(--card);
764 --sidebar-foreground: var(--foreground);
765 --sidebar-muted-foreground: var(--muted-foreground);
766 --sidebar-control-surface: var(--muted);
767 --sidebar-row-hover: color-mix(in srgb, var(--foreground) 6%, transparent);
768 --sidebar-row-active: color-mix(in srgb, var(--foreground) 11%, transparent);
769 --sidebar-row-selected: color-mix(in srgb, var(--foreground) 7%, transparent);
770 --sidebar-border: var(--border);
751 --background: var(--color-zinc-25);
752 --foreground: var(--color-zinc-800);
753 --card: var(--color-white);
754 --card-foreground: var(--color-zinc-800);
755 --accent: var(--color-zinc-100);
756 --accent-foreground: var(--color-zinc-900);
757 --muted: var(--color-zinc-50);
758 --muted-foreground: var(--color-zinc-500);
759 --border: var(--color-zinc-200);
760 --input: var(--color-zinc-300);
761 --sidebar: var(--color-zinc-50);
762 --sidebar-foreground: var(--color-zinc-800);
763 --sidebar-muted-foreground: var(--color-zinc-500);
764 --sidebar-control-surface: var(--color-zinc-100);
765 --sidebar-row-hover: var(--color-zinc-25);
766 --sidebar-row-active: var(--color-white);
767 --sidebar-row-selected: var(--color-white);
768 --sidebar-border: var(--color-zinc-200);
771769 --sidebar-stage-fade: var(--sidebar);
772 background-color: var(--card);
770 background-color: var(--sidebar);
773771}
774772
775773.dark [data-sidebar-version="v1"],
packages/contracts/src/settings.test.ts+2-2
......@@ -38,12 +38,12 @@ describe("ClientSettings glass opacity", () => {
3838 expect(decodeClientSettings({}).glassOpacity).toBe(80);
3939 });
4040
41 it.each([49, 101, 72.5])("rejects an invalid glass opacity: %s", (value) => {
41 it.each([39, 101, 72.5])("rejects an invalid glass opacity: %s", (value) => {
4242 expect(() => decodeClientSettings({ glassOpacity: value })).toThrow();
4343 expect(() => decodeClientSettingsPatch({ glassOpacity: value })).toThrow();
4444 });
4545
46 it.each([50, 75, 100])("accepts a glass opacity within the supported range: %s", (value) => {
46 it.each([40, 75, 100])("accepts a glass opacity within the supported range: %s", (value) => {
4747 expect(decodeClientSettings({ glassOpacity: value }).glassOpacity).toBe(value);
4848 expect(decodeClientSettingsPatch({ glassOpacity: value }).glassOpacity).toBe(value);
4949 });
packages/contracts/src/settings.ts+1-1
......@@ -48,7 +48,7 @@ export const SidebarAutoSettleAfterDays = Schema.Number.check(
4848);
4949export type SidebarAutoSettleAfterDays = typeof SidebarAutoSettleAfterDays.Type;
5050export const DEFAULT_SIDEBAR_AUTO_SETTLE_AFTER_DAYS: SidebarAutoSettleAfterDays = 3;
51export const MIN_GLASS_OPACITY = 50;
51export const MIN_GLASS_OPACITY = 40;
5252export const MAX_GLASS_OPACITY = 100;
5353export const GlassOpacity = Schema.Int.check(
5454 Schema.isBetween({