chore: Tailwind CSS v4 migration (#4139)

Migrates the webapp from Tailwind CSS 3.4 to 4.x.
This commit is contained in:
Katia Bulatova
2026-07-08 15:11:40 +02:00
committed by GitHub
parent e0bf74bfae
commit 6e827f1da3
246 changed files with 2109 additions and 2478 deletions
+6
View File
@@ -0,0 +1,6 @@
---
area: webapp
type: improvement
---
Migrated the webapp to Tailwind CSS v4 with a CSS-first `@theme`. Semantic color tokens are now CSS variables overridable per theme (multi-theme support). Tailwind runs through `@tailwindcss/postcss`; plugins replaced or upgraded to v4-compatible versions.
+6
View File
@@ -0,0 +1,6 @@
---
area: webapp
type: improvement
---
Replaced raw charcoal-* Tailwind classes with semantic theme tokens (surfaces, borders, text) across the dashboard. Adds surface/border/text tokens to the themable layer so future themes only override CSS variables.
+8 -8
View File
@@ -173,7 +173,7 @@ function AskAIDialog({ initialQuery, isOpen, onOpenChange, closeAskAI }: AskAIDi
return (
<Dialog open={isOpen} onOpenChange={handleOpenChange}>
<DialogContent className="animated-gradient-glow flex max-h-[90vh] min-h-fit w-full flex-col justify-between gap-0 px-0 pb-0 pt-0 sm:max-w-prose">
<DialogHeader className="flex h-[2.75rem] items-start justify-center rounded-t-md bg-background-bright pl-3">
<DialogHeader className="flex h-11 items-start justify-center rounded-t-md bg-background-bright pl-3">
<div className="flex items-center gap-1">
<AISparkleIcon className="size-5" />
<DialogTitle className="text-sm font-medium text-text-bright">Ask AI</DialogTitle>
@@ -226,7 +226,7 @@ function ChatMessages({
];
return (
<div className="flex-1 overflow-y-auto p-4 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600">
<div className="flex-1 overflow-y-auto p-4 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control">
{conversation.length === 0 ? (
<motion.div
className="flex flex-col gap-2 pb-2"
@@ -249,7 +249,7 @@ function ChatMessages({
{exampleQuestions.map((question, index) => (
<motion.button
key={index}
className="group flex w-fit items-center gap-2 rounded-full border border-dashed border-charcoal-600 px-4 py-2 transition-colors hover:border-solid hover:border-indigo-500"
className="group flex w-fit items-center gap-2 rounded-full border border-dashed border-border-bright px-4 py-2 transition-colors hover:border-solid hover:border-indigo-500"
onClick={() => onExampleClick(question)}
variants={{
hidden: {
@@ -468,7 +468,7 @@ function ChatInterface({ initialQuery }: { initialQuery?: string }) {
error={error}
addFeedback={addFeedback}
/>
<form onSubmit={handleSubmit} className="flex-shrink-0 border-t border-grid-bright p-4">
<form onSubmit={handleSubmit} className="shrink-0 border-t border-grid-bright p-4">
<div className="flex gap-3">
<input
type="text"
@@ -511,7 +511,7 @@ function ChatInterface({ initialQuery }: { initialQuery?: string }) {
disabled={!message.trim()}
LeadingIcon={<ArrowUpIcon className="size-5 text-text-bright" />}
variant="primary/large"
className="size-10 min-w-10 rounded-full group-disabled/button:border-charcoal-550 group-disabled/button:bg-charcoal-600"
className="size-10 min-w-10 rounded-full group-disabled/button:border-border-brighter group-disabled/button:bg-surface-control"
/>
)}
</div>
@@ -531,11 +531,11 @@ function GradientSpinnerBackground({
}) {
return (
<div
className={`flex rounded-full bg-gradient-to-br from-indigo-500 via-purple-500 to-fuchsia-500 p-px ${className}`}
className={`flex rounded-full bg-linear-to-br from-indigo-500 via-purple-500 to-fuchsia-500 p-px ${className}`}
>
<div
className={`flex h-full w-full items-center justify-center rounded-full bg-charcoal-600 ${
hoverEffect ? "transition group-hover:bg-charcoal-550" : ""
className={`flex h-full w-full items-center justify-center rounded-full bg-surface-control ${
hoverEffect ? "transition group-hover:bg-surface-control-hover" : ""
}`}
>
{children}
@@ -7,7 +7,7 @@ export function BackgroundWrapper({ children }: { children: ReactNode }) {
return (
<div className="relative h-full w-full overflow-hidden bg-background-dimmed lg:bg-transparent">
<div
className="absolute left-0 top-0 hidden w-[260px] bg-contain bg-left-top bg-no-repeat lg:block"
className="absolute left-0 top-0 hidden w-[260px] bg-contain bg-top-left bg-no-repeat lg:block"
style={{
backgroundImage: `url(${blurredDashboardBackgroundMenuTop})`,
aspectRatio: "auto",
@@ -17,7 +17,7 @@ export function BackgroundWrapper({ children }: { children: ReactNode }) {
/>
<div
className="absolute bottom-0 left-0 hidden w-[260px] bg-contain bg-left-bottom bg-no-repeat lg:block"
className="absolute bottom-0 left-0 hidden w-[260px] bg-contain bg-bottom-left bg-no-repeat lg:block"
style={{
backgroundImage: `url(${blurredDashboardBackgroundMenuBottom})`,
aspectRatio: "auto",
@@ -27,7 +27,7 @@ export function BackgroundWrapper({ children }: { children: ReactNode }) {
/>
<div
className="absolute top-0 hidden bg-left-top bg-no-repeat lg:block"
className="absolute top-0 hidden bg-top-left bg-no-repeat lg:block"
style={{
left: "260px",
backgroundImage: `url(${blurredDashboardBackgroundTable})`,
@@ -304,7 +304,7 @@ export function DeploymentsNoneDev() {
organization={organization}
project={project}
environment={environment}
className="w-fit border border-charcoal-600 bg-secondary hover:border-charcoal-550 hover:bg-charcoal-600"
className="w-fit border border-border-bright bg-secondary hover:border-border-brighter hover:bg-surface-control"
/>
</StepContentContainer>
</>
@@ -17,11 +17,11 @@ export function DefinitionTip({
<TooltipProvider>
<Tooltip disableHoverableContent={disableHoverableContent}>
<TooltipTrigger className="text-left">
<span className="cursor-default underline decoration-charcoal-500 decoration-dashed underline-offset-4 transition hover:decoration-charcoal-400">
<span className="cursor-default underline decoration-text-faint decoration-dashed underline-offset-4 transition hover:decoration-text-dimmed">
{children}
</span>
</TooltipTrigger>
<TooltipContent align="end" side="right" className="w-[16rem] min-w-[16rem]">
<TooltipContent align="end" side="right" className="w-64 min-w-64">
<Header3 className="mb-1">{title}</Header3>
{typeof content === "string" ? (
<Paragraph variant="small">{content}</Paragraph>
+1 -1
View File
@@ -84,7 +84,7 @@ export function Feedback({ button, defaultValue = "bug", onOpenChange }: Feedbac
<DialogHeader>Contact us</DialogHeader>
<div className="mt-2 flex flex-col gap-4">
<div className="flex items-center gap-4">
<Icon icon={EnvelopeIcon} className="size-10 min-w-[2.5rem] text-blue-500" />
<Icon icon={EnvelopeIcon} className="size-10 min-w-10 text-blue-500" />
<Paragraph variant="base/bright">
How can we help? We read every message and will respond as quickly as we can.
</Paragraph>
+3 -3
View File
@@ -28,7 +28,7 @@ export function GitMetadataBranch({
leadingIconClassName="group-hover/table-row:text-text-bright"
iconSpacing="gap-x-1"
to={git.branchUrl}
className="pl-1 duration-0 [&_span]:duration-0 [&_span]:group-hover/table-row:text-text-bright"
className="pl-1 duration-0 [&_span]:duration-0 group-hover/table-row:[&_span]:text-text-bright"
>
{git.branchName}
</LinkButton>
@@ -52,7 +52,7 @@ export function GitMetadataCommit({
LeadingIcon={<GitCommitIcon className="size-4" />}
leadingIconClassName="group-hover/table-row:text-text-bright"
iconSpacing="gap-x-1"
className="pl-1 duration-0 [&_span]:duration-0 [&_span]:group-hover/table-row:text-text-bright"
className="pl-1 duration-0 [&_span]:duration-0 group-hover/table-row:[&_span]:text-text-bright"
>
{`${git.shortSha} / ${git.commitMessage}`}
</LinkButton>
@@ -78,7 +78,7 @@ export function GitMetadataPullRequest({
LeadingIcon={<GitPullRequestIcon className="size-4" />}
leadingIconClassName="group-hover/table-row:text-text-bright"
iconSpacing="gap-x-1"
className="pl-1 duration-0 [&_span]:duration-0 [&_span]:group-hover/table-row:text-text-bright"
className="pl-1 duration-0 [&_span]:duration-0 group-hover/table-row:[&_span]:text-text-bright"
>
#{git.pullRequestNumber} {git.pullRequestTitle}
</LinkButton>
@@ -23,7 +23,7 @@ export function ListPagination({ list, className }: { list: List; className?: st
<NextButton cursor={list.pagination.next} />
<div
className={cn(
"order-2 h-6 w-px bg-charcoal-600 transition-colors peer-hover/next:bg-charcoal-550 peer-hover/prev:bg-charcoal-550",
"order-2 h-6 w-px bg-surface-control transition-colors peer-hover/next:bg-surface-control-hover peer-hover/prev:bg-surface-control-hover",
bothDisabled && "opacity-30"
)}
/>
@@ -41,7 +41,7 @@ function PreviousButton({ cursor }: { cursor?: string }) {
variant={"secondary/small"}
LeadingIcon={ChevronLeftIcon}
className={cn(
"flex items-center rounded-r-none border-r-0 pl-2 pr-[0.5625rem]",
"flex items-center rounded-r-none border-r-0 pl-2 pr-2.25",
!path && "cursor-not-allowed opacity-50"
)}
onClick={(e) => !path && e.preventDefault()}
@@ -63,7 +63,7 @@ function NextButton({ cursor }: { cursor?: string }) {
variant={"secondary/small"}
TrailingIcon={ChevronRightIcon}
className={cn(
"flex items-center rounded-l-none border-l-0 pl-[0.5625rem] pr-2",
"flex items-center rounded-l-none border-l-0 pl-2.25 pr-2",
!path && "cursor-not-allowed opacity-50"
)}
onClick={(e) => !path && e.preventDefault()}
@@ -68,7 +68,7 @@ export function LoginPageLayout({ children }: { children: React.ReactNode }) {
</div>
<div className="flex flex-col items-center gap-4 px-8">
<Paragraph>Trusted by developers at</Paragraph>
<div className="flex w-full flex-wrap items-center justify-center gap-x-6 gap-y-3 text-charcoal-500 xl:justify-between xl:gap-0">
<div className="flex w-full flex-wrap items-center justify-center gap-x-6 gap-y-3 text-text-faint xl:justify-between xl:gap-0">
<LyftLogo className="w-11" />
<UnkeyLogo />
<MiddayLogo />
@@ -14,7 +14,7 @@ export function ProductHuntBanner() {
<LinkButton
to="https://www.producthunt.com/posts/trigger-dev"
target="_blank"
className="!text-white underline underline-offset-2 transition hover:decoration-charcoal-100 hover:decoration-2"
className="text-white! underline underline-offset-2 transition hover:decoration-text-bright hover:decoration-2"
variant="tertiary/small"
>
Vote for us today only!
@@ -26,6 +26,6 @@ export function UserAvatar({
/>
</div>
) : (
<UserCircleIcon className={cn("aspect-square text-charcoal-400", className)} />
<UserCircleIcon className={cn("aspect-square text-text-dimmed", className)} />
);
}
+3 -3
View File
@@ -30,7 +30,7 @@ export function WarmStartIconWithTooltip({
}) {
return (
<SimpleTooltip
className="relative z-[9999]"
className="relative z-9999"
button={<WarmStartIcon isWarmStart={isWarmStart} className={className} />}
content={<WarmStartTooltipContent />}
/>
@@ -42,14 +42,14 @@ function WarmStartTooltipContent() {
<div className="flex max-w-xs flex-col gap-4 p-1">
<div>
<WarmStartCombo isWarmStart={false} className="mb-0.5 text-text-bright" />
<Paragraph variant="small" className="!text-wrap text-text-dimmed">
<Paragraph variant="small" className="text-wrap! text-text-dimmed">
A cold start happens when we need to boot up a new machine for your run to execute. This
takes longer than a warm start.
</Paragraph>
</div>
<div>
<WarmStartCombo isWarmStart={true} className="mb-0.5 text-text-bright" />
<Paragraph variant="small" className="!text-wrap text-text-dimmed">
<Paragraph variant="small" className="text-wrap! text-text-dimmed">
A warm start happens when we can reuse a machine from a run that recently finished. This
takes less time than a cold start.
</Paragraph>
@@ -166,14 +166,14 @@ export function FeatureFlagsDialog({
return (
<div
key={key}
className="flex items-center justify-between rounded-md border border-transparent bg-charcoal-750 px-3 py-2.5"
className="flex items-center justify-between rounded-md border border-transparent bg-background-hover px-3 py-2.5"
title="Global-level setting - not editable per org"
>
<div className="min-w-0 flex-1">
<div className="truncate text-sm text-text-dimmed">{key}</div>
<div className="text-xs text-charcoal-400">global: {globalDisplay}</div>
<div className="text-xs text-text-dimmed">global: {globalDisplay}</div>
</div>
<LockClosedIcon className="size-4 text-charcoal-500" />
<LockClosedIcon className="size-4 text-text-faint" />
</div>
);
}
@@ -187,7 +187,7 @@ export function FeatureFlagsDialog({
"flex items-center justify-between rounded-md border px-3 py-2.5",
isOverridden
? "border-indigo-500/20 bg-indigo-500/5"
: "border-transparent bg-charcoal-750"
: "border-transparent bg-background-hover"
)}
>
<div className="min-w-0 flex-1">
@@ -199,7 +199,7 @@ export function FeatureFlagsDialog({
>
{key}
</div>
<div className="text-xs text-charcoal-400">global: {globalDisplay}</div>
<div className="text-xs text-text-dimmed">global: {globalDisplay}</div>
</div>
<div className="flex items-center gap-2">
@@ -283,7 +283,7 @@ export function FeatureFlagsDialog({
<summary className="cursor-pointer text-xs text-text-dimmed hover:text-text-bright">
Preview JSON
</summary>
<pre className="mt-1 max-h-40 overflow-auto rounded bg-charcoal-800 p-2 text-xs text-text-dimmed">
<pre className="mt-1 max-h-40 overflow-auto rounded bg-background-bright p-2 text-xs text-text-dimmed">
{jsonPreview}
</pre>
</details>
@@ -42,7 +42,7 @@ export function MaxProjectsSection({
}, [savedJustNow, hasFieldErrors]);
return (
<section className="flex flex-col gap-3 rounded-md border border-charcoal-700 bg-charcoal-800 p-4">
<section className="flex flex-col gap-3 rounded-md border border-grid-bright bg-background-bright p-4">
<div className="flex items-center justify-between">
<Header2>Maximum projects</Header2>
{!isEditing && (
@@ -94,7 +94,7 @@ export function RateLimitSection({
};
return (
<section className="flex flex-col gap-3 rounded-md border border-charcoal-700 bg-charcoal-800 p-4">
<section className="flex flex-col gap-3 rounded-md border border-grid-bright bg-background-bright p-4">
<div className="flex items-center justify-between">
<Header2>{title}</Header2>
{!isEditing && (
@@ -1,15 +1,20 @@
import { ArrowUpCircleIcon } from "@heroicons/react/24/outline";
import { Link } from "@remix-run/react";
import { motion, useMotionValue, useTransform } from "framer-motion";
import { useThemeColor } from "~/hooks/useThemeColor";
import { cn } from "~/utils/cn";
export function FreePlanUsage({ to, percentage }: { to: string; percentage: number }) {
const cappedPercentage = Math.min(percentage, 1);
const widthProgress = useMotionValue(cappedPercentage * 100);
// Resolved to concrete colors - framer-motion can't interpolate var() strings
const successColor = useThemeColor("--color-success", "#28bf5c");
const warningColor = useThemeColor("--color-warning", "#f59e0b");
const errorColor = useThemeColor("--color-error", "#e11d48");
const color = useTransform(
widthProgress,
[0, 74, 75, 95, 100],
["#22C55E", "#22C55E", "#F59E0B", "#F43F5E", "#F43F5E"]
[successColor, successColor, warningColor, errorColor, errorColor]
);
const hasHitLimit = cappedPercentage >= 1;
@@ -17,7 +22,7 @@ export function FreePlanUsage({ to, percentage }: { to: string; percentage: numb
return (
<div
className={cn(
"rounded border border-charcoal-700 bg-charcoal-750 p-2.5",
"rounded border border-grid-bright bg-background-hover p-2.5",
hasHitLimit && "border-error/40"
)}
>
@@ -110,7 +110,7 @@ function Legend({ text, value, position, percentage, tooltipContent }: LegendPro
return (
<div
className={cn(
"absolute left-full z-10 flex border-charcoal-500",
"absolute left-full z-10 flex border-border-brightest",
positions[position],
flipLegendPosition === true ? "-translate-x-full border-r" : "border-l"
)}
@@ -257,7 +257,7 @@ export function AIQueryInput({
onChange={(e) => setPrompt(e.target.value)}
disabled={isLoading}
rows={8}
className="m-0 min-h-10 w-full resize-none border-0 bg-background-bright px-3 py-2.5 text-sm text-text-bright scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600 file:border-0 file:bg-transparent file:text-base file:font-medium placeholder:text-text-dimmed focus:border-0 focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50"
className="m-0 min-h-10 w-full resize-none border-0 bg-background-bright px-3 py-2.5 text-sm text-text-bright scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control file:border-0 file:bg-transparent file:text-base file:font-medium placeholder:text-text-dimmed focus:border-0 focus:outline-hidden focus:ring-0 focus-visible:outline-hidden focus-visible:ring-0 focus-visible:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50"
onKeyDown={(e) => {
if (e.key === "Enter" && !e.shiftKey && prompt.trim() && !isLoading) {
e.preventDefault();
@@ -342,7 +342,7 @@ export function AIQueryInput({
className="overflow-hidden"
>
<div className="px-1">
<div className="rounded-b-lg border-x border-b border-grid-dimmed bg-charcoal-850 p-3 pb-1">
<div className="rounded-b-lg border-x border-b border-grid-dimmed bg-background-dimmed p-3 pb-1">
<div className="mb-1 flex items-center justify-between">
<div className="flex items-center gap-1">
{isLoading ? (
@@ -390,7 +390,7 @@ export function AIQueryInput({
</Button>
)}
</div>
<div className="streamdown-container max-h-96 overflow-y-auto text-xs text-text-dimmed scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600">
<div className="streamdown-container max-h-96 overflow-y-auto text-xs text-text-dimmed scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control">
<Suspense fallback={<p className="whitespace-pre-wrap">{thinking}</p>}>
<StreamdownRenderer isAnimating={isLoading}>{thinking}</StreamdownRenderer>
</Suspense>
@@ -381,7 +381,7 @@ export function ChartConfigPanel({ columns, config, onChange, className }: Chart
}
updateConfig(updates);
}}
className="rounded p-1 text-text-dimmed hover:bg-charcoal-700 hover:text-text-bright"
className="rounded p-1 text-text-dimmed hover:bg-background-raised hover:text-text-bright"
title="Remove series"
>
<XIcon className="h-3.5 w-3.5" />
@@ -406,7 +406,7 @@ export function ChartConfigPanel({ columns, config, onChange, className }: Chart
});
}
}}
className="flex items-center gap-1 self-start rounded px-1 py-0.5 text-xs text-text-dimmed hover:bg-charcoal-700 hover:text-text-bright"
className="flex items-center gap-1 self-start rounded px-1 py-0.5 text-xs text-text-dimmed hover:bg-background-raised hover:text-text-bright"
>
<Plus className="h-3 w-3" />
Add series
@@ -568,7 +568,7 @@ function SeriesColorPicker({
<PopoverTrigger asChild>
<button
type="button"
className="flex-shrink-0 rounded p-0.5 hover:bg-charcoal-700"
className="shrink-0 rounded p-0.5 hover:bg-background-raised"
title="Change series color"
>
<span
@@ -616,7 +616,7 @@ function TypeBadge({ type }: { type: string }) {
}
return (
<span className="rounded bg-charcoal-750 px-1 py-0.5 font-mono text-xxs text-text-dimmed">
<span className="rounded bg-background-hover px-1 py-0.5 font-mono text-xxs text-text-dimmed">
{displayType}
</span>
);
+29 -29
View File
@@ -79,68 +79,68 @@ const extraLinesWhenClipping = 0.35;
const defaultTheme: PrismTheme = {
plain: {
color: "#9C9AF2",
color: "var(--color-code-constant)",
backgroundColor: "rgba(0, 0, 0, 0)",
},
styles: [
{
types: ["comment", "prolog", "doctype", "cdata"],
style: {
color: "#5F6570",
color: "var(--color-code-muted)",
},
},
{
types: ["punctuation"],
style: {
color: "#878C99",
color: "var(--color-code-foreground)",
},
},
{
types: ["property", "tag", "constant", "symbol", "deleted"],
style: {
color: "#9B99FF",
color: "var(--color-code-language)",
},
},
{
types: ["boolean", "number"],
style: {
color: "#E5C07B",
color: "var(--color-code-builtin)",
},
},
{
types: ["selector", "attr-name", "string", "char", "builtin", "inserted"],
style: {
color: "#AFEC73",
color: "var(--color-code-string)",
},
},
{
types: ["operator", "entity", "url"],
style: {
color: "#D4D4D4",
color: "var(--color-code-plain)",
},
},
{
types: ["variable"],
style: {
color: "#CCCBFF",
color: "var(--color-code-variable)",
},
},
{
types: ["atrule", "attr-value", "keyword"],
style: {
color: "#E888F8",
color: "var(--color-code-keyword)",
},
},
{
types: ["function", "class-name"],
style: {
color: "#D9F07C",
color: "var(--color-code-function)",
},
},
{
types: ["regex"],
style: {
color: "#d16969",
color: "var(--color-code-regexp)",
},
},
{
@@ -164,31 +164,31 @@ const defaultTheme: PrismTheme = {
{
types: ["deleted"],
style: {
color: "#F85149",
color: "var(--color-code-deleted)",
},
},
{
types: ["char"],
style: {
color: "#b5cea8",
color: "var(--color-code-number)",
},
},
{
types: ["tag"],
style: {
color: "#D7BA7D",
color: "var(--color-code-escape)",
},
},
{
types: ["keyword.operator"],
style: {
color: "#8271ED",
color: "var(--color-code-storage)",
},
},
{
types: ["meta.template.expression"],
style: {
color: "#d4d4d4",
color: "var(--color-code-plain)",
},
},
],
@@ -359,7 +359,7 @@ export const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
<div
dir="ltr"
className={cn(
"min-h-0 flex-1 px-2 py-3 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600",
"min-h-0 flex-1 px-2 py-3 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control",
"overflow-auto"
)}
style={{
@@ -369,7 +369,7 @@ export const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
<pre
className={cn(
"relative mr-2 p-2 font-mono text-xs leading-relaxed",
isWrapped && "[&_span]:whitespace-pre-wrap [&_span]:break-words"
isWrapped && "[&_span]:whitespace-pre-wrap [&_span]:wrap-break-word"
)}
dir="ltr"
>
@@ -412,7 +412,7 @@ export const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
) : (
<div
dir="ltr"
className="overflow-auto px-3 py-3 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600"
className="overflow-auto px-3 py-3 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control"
>
<pre className="relative mr-2 p-2 font-mono text-base leading-relaxed" dir="ltr">
{highlightSearchText(code, searchTerm)}
@@ -430,14 +430,14 @@ CodeBlock.displayName = "CodeBlock";
function Chrome({ title }: { title?: string }) {
return (
<div className="grid h-7 grid-cols-[100px_auto_100px] border-b border-charcoal-800 bg-charcoal-900">
<div className="grid h-7 grid-cols-[100px_auto_100px] border-b border-background-bright bg-background-deep">
<div className="ml-2 flex items-center gap-2">
<div className="h-3 w-3 rounded-full bg-charcoal-700" />
<div className="h-3 w-3 rounded-full bg-charcoal-700" />
<div className="h-3 w-3 rounded-full bg-charcoal-700" />
<div className="h-3 w-3 rounded-full bg-background-raised" />
<div className="h-3 w-3 rounded-full bg-background-raised" />
<div className="h-3 w-3 rounded-full bg-background-raised" />
</div>
<div className="flex items-center justify-center">
<div className={cn("rounded-sm px-3 py-0.5 text-xs text-charcoal-500")}>{title}</div>
<div className={cn("rounded-sm px-3 py-0.5 text-xs text-text-faint")}>{title}</div>
</div>
<div></div>
</div>
@@ -493,7 +493,7 @@ function HighlightCode({
}, []);
const containerClasses = cn(
"min-h-0 flex-1 px-3 py-3 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600",
"min-h-0 flex-1 px-3 py-3 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control",
!isWrapped && "overflow-auto",
isWrapped && "overflow-auto",
className
@@ -502,7 +502,7 @@ function HighlightCode({
const preClasses = cn(
"relative mr-2 font-mono leading-relaxed",
preClassName,
isWrapped && "[&_span]:whitespace-pre-wrap [&_span]:break-words"
isWrapped && "[&_span]:whitespace-pre-wrap [&_span]:wrap-break-word"
);
if (!isLoaded) {
@@ -531,7 +531,7 @@ function HighlightCode({
}
const lineNumber = index + 1;
const lineProps = getLineProps({ line, key: index });
const lineProps = getLineProps({ line });
let hasAnyHighlights = highlightLines ? highlightLines.length > 0 : false;
@@ -557,7 +557,7 @@ function HighlightCode({
{showLineNumbers && (
<div
className={cn(
"mr-2 flex-none select-none text-right text-charcoal-500 transition-opacity duration-500",
"mr-2 flex-none select-none text-right text-text-faint transition-opacity duration-500",
isWrapped && "sticky left-0"
)}
style={{
@@ -570,7 +570,7 @@ function HighlightCode({
<div className="flex-1">
{line.map((token, key) => {
const tokenProps = getTokenProps({ token, key });
const tokenProps = getTokenProps({ token });
// Highlight search term matches in token
const content = highlightSearchText(token.content, searchTerm);
@@ -1,7 +1,7 @@
import { cn } from "~/utils/cn";
const inlineCode =
"px-1 py-0.5 rounded border border-charcoal-700 bg-charcoal-800 text-charcoal-200 font-mono text-wrap";
"px-1 py-0.5 rounded border border-grid-bright bg-background-bright text-text-bright font-mono text-wrap";
const variants = {
"extra-extra-small": "text-xxs",
@@ -12,7 +12,7 @@ import { ChartBlankState } from "../primitives/charts/ChartBlankState";
import { Callout } from "../primitives/Callout";
import type { AggregationType, ChartConfiguration } from "../metrics/QueryWidget";
import { aggregateValues } from "../primitives/charts/aggregation";
import { getRunStatusHexColor } from "~/components/runs/v3/TaskRunStatus";
import { getRunStatusChartColor } from "~/components/runs/v3/TaskRunStatus";
import { getSeriesColor } from "./chartColors";
const MAX_SERIES = 50;
@@ -936,7 +936,7 @@ export const QueryResultsChart = memo(function QueryResultsChart({
const chartConfig = useMemo(() => {
const cfg: ChartConfig = {};
sortedSeries.forEach((s, i) => {
const statusColor = groupByIsRunStatus ? getRunStatusHexColor(s) : undefined;
const statusColor = groupByIsRunStatus ? getRunStatusChartColor(s) : undefined;
const originalIndex = config.yAxisColumns.indexOf(s);
const colorIndex = originalIndex >= 0 ? originalIndex : i;
cfg[s] = {
@@ -1039,14 +1039,14 @@ export const QueryResultsChart = memo(function QueryResultsChart({
y1={axisY}
x2={x as number}
y2={axisY - 3}
stroke="#878C99"
stroke="var(--color-text-dimmed)"
strokeWidth={1}
/>
<text
x={x}
y={axisY}
dy={10}
fill="#878C99"
fill="var(--color-text-dimmed)"
fontSize={11}
textAnchor={xAxisAngle !== 0 ? "end" : "middle"}
style={{ fontVariantNumeric: "tabular-nums" }}
@@ -1066,7 +1066,7 @@ export const QueryResultsChart = memo(function QueryResultsChart({
y1={axisY}
x2={x as number}
y2={axisY - 3}
stroke="#272A2E"
stroke="var(--color-grid-bright)"
strokeWidth={1}
/>
);
@@ -271,7 +271,7 @@ export function TSQLEditor(opts: TSQLEditorProps) {
>
<div
className={cn(
"min-h-0 flex-1 overflow-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600"
"min-h-0 flex-1 overflow-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control"
)}
ref={editor}
onClick={() => {
@@ -284,7 +284,7 @@ export function TSQLEditor(opts: TSQLEditorProps) {
}}
/>
{showButtons && (
<div className="absolute right-0 top-0 z-10 flex items-center justify-end bg-charcoal-900/80 p-1.5">
<div className="absolute right-0 top-0 z-10 flex items-center justify-end bg-background-deep/80 p-1.5">
{additionalActions && additionalActions}
{showFormatButton && (
<Button
@@ -833,9 +833,9 @@ function CopyableCell({
<div
className={cn(
"relative flex h-full w-full items-center overflow-hidden px-2",
"bg-background-bright group-hover/row:bg-charcoal-750",
"bg-background-bright group-hover/row:bg-background-hover",
"font-mono text-xs text-text-dimmed group-hover/row:text-text-bright",
"[&_a:focus-visible]:underline [&_a:focus-visible]:underline-offset-[3px] [&_a:focus-visible]:outline-none",
"[&_a:focus-visible]:underline [&_a:focus-visible]:underline-offset-[3px] [&_a:focus-visible]:outline-hidden",
alignment === "right" && "justify-end"
)}
onMouseEnter={() => setIsHovered(true)}
@@ -855,10 +855,10 @@ function CopyableCell({
button={
<span
className={cn(
"flex size-6 items-center justify-center rounded border border-charcoal-650 bg-charcoal-750",
"flex size-6 items-center justify-center rounded border border-border-bright bg-background-hover",
copied
? "text-green-500"
: "text-text-dimmed hover:border-charcoal-600 hover:bg-charcoal-700 hover:text-text-bright"
: "text-text-dimmed hover:border-border-bright hover:bg-background-raised hover:text-text-bright"
)}
>
{copied ? (
@@ -925,7 +925,7 @@ function HeaderCellContent({
})}
>
<span className="truncate text-left">{children}</span>
<span className="flex flex-shrink-0">
<span className="flex shrink-0">
<InfoIconTooltip
content={tooltip}
contentClassName="normal-case tracking-normal"
@@ -941,7 +941,7 @@ function HeaderCellContent({
{canSort && (
<span
className={cn(
"flex-shrink-0 transition-colors",
"shrink-0 transition-colors",
sortHighlighted ? "text-text-bright" : "text-text-dimmed"
)}
>
@@ -962,7 +962,7 @@ function HeaderCellContent({
}}
onMouseEnter={() => setIsFilterHovered(true)}
onMouseLeave={() => setIsFilterHovered(false)}
className="flex-shrink-0 rounded text-text-dimmed transition-colors focus-custom hover:text-text-bright"
className="shrink-0 rounded text-text-dimmed transition-colors focus-custom hover:text-text-bright"
title="Toggle column filters"
>
{showFilters ? <IconFilter2X className="size-4" /> : <IconFilter2 className="size-4" />}
@@ -1004,9 +1004,9 @@ function FilterCell({
onChange={(value) => column.setFilterValue(value)}
placeholder="Filter..."
className={cn(
"w-full rounded border border-charcoal-700 bg-charcoal-800 px-2 py-1",
"w-full rounded border border-grid-bright bg-background-bright px-2 py-1",
"text-xs text-text-bright placeholder:text-text-dimmed",
"focus:border-indigo-500/50 focus:outline-none focus:ring-1 focus:ring-indigo-500/50"
"focus:border-indigo-500/50 focus:outline-hidden focus:ring-1 focus:ring-indigo-500/50"
)}
/>
</div>
@@ -1110,7 +1110,7 @@ export const TSQLResultsTable = memo(function TSQLResultsTable({
return (
<div
className="h-full min-h-0 w-full overflow-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600"
className="h-full min-h-0 w-full overflow-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control"
style={{ position: "relative" }}
>
<table style={{ display: "grid" }}>
@@ -1165,7 +1165,7 @@ export const TSQLResultsTable = memo(function TSQLResultsTable({
return (
<div
ref={tableContainerRef}
className="h-full min-h-0 w-full overflow-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600"
className="h-full min-h-0 w-full overflow-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control"
style={{ position: "relative" }}
>
<table style={{ display: "grid" }}>
@@ -1219,7 +1219,7 @@ export const TSQLResultsTable = memo(function TSQLResultsTable({
className={cn(
"absolute right-0 top-0 h-full w-0.5 cursor-col-resize touch-none select-none",
"opacity-0 group-hover/header:opacity-100",
"bg-charcoal-600 hover:bg-indigo-500",
"bg-surface-control hover:bg-indigo-500",
header.column.getIsResizing() && "bg-indigo-500 opacity-100"
)}
/>
@@ -1249,7 +1249,7 @@ export const TSQLResultsTable = memo(function TSQLResultsTable({
height: `${rowVirtualizer.getTotalSize()}px`,
position: "relative",
}}
className="divide-y divide-charcoal-700 bg-background-bright after:absolute after:bottom-0 after:left-0 after:right-0 after:z-[1] after:h-px after:bg-grid-bright"
className="divide-y divide-grid-bright bg-background-bright after:absolute after:bottom-0 after:left-0 after:right-0 after:z-1 after:h-px after:bg-grid-bright"
>
{rowVirtualizer.getVirtualItems().map((virtualRow) => {
const row = tableRows[virtualRow.index];
@@ -1257,7 +1257,7 @@ export const TSQLResultsTable = memo(function TSQLResultsTable({
<tr
key={row.id}
data-index={virtualRow.index}
className="group/row hover:bg-charcoal-750"
className="group/row hover:bg-background-hover"
style={{
display: "flex",
position: "absolute",
@@ -4,27 +4,28 @@ import { EditorView } from "@codemirror/view";
import { tags } from "@lezer/highlight";
export function darkTheme(): Extension {
const chalky = "#e5c07b",
coral = "#e06c75",
cyan = "#56b6c2",
invalid = "#ffffff",
ivory = "#abb2bf",
stone = "#7d8799",
malibu = "#61afef",
sage = "#afec73",
whiskey = "#d19a66",
violet = "#c678dd",
lilac = "#9b99ff",
darkBackground = "#21252b",
highlightBackground = "rgba(71,85,105,0.2)",
background = "#121317",
tooltipBackground = "#353a42",
selection = "rgb(71 85 105)",
cursor = "#528bff",
// Values come from the --color-editor-* theme palette in tailwind.css.
const chalky = "var(--color-editor-type)",
coral = "var(--color-editor-heading)",
cyan = "var(--color-editor-operator)",
invalid = "var(--color-editor-invalid)",
ivory = "var(--color-editor-foreground)",
stone = "var(--color-editor-comment)",
malibu = "var(--color-editor-function)",
sage = "var(--color-editor-string)",
whiskey = "var(--color-editor-constant)",
violet = "var(--color-editor-keyword)",
lilac = "var(--color-editor-name)",
darkBackground = "var(--color-editor-panel-background)",
highlightBackground = "var(--color-editor-highlight-background)",
background = "var(--color-editor-background)",
tooltipBackground = "var(--color-editor-tooltip-background)",
selection = "var(--color-editor-selection)",
cursor = "var(--color-editor-cursor)",
scrollbarTrack = "rgba(0,0,0,0)",
scrollbarTrackActive = "#131B2B",
scrollbarThumb = "#293649",
scrollbarThumbActive = "#3C4B62",
scrollbarTrackActive = "var(--color-editor-scrollbar-track-active)",
scrollbarThumb = "var(--color-editor-scrollbar-thumb)",
scrollbarThumbActive = "var(--color-editor-scrollbar-thumb-active)",
scrollbarBg = "rgba(0,0,0,0)";
const jsonHeroEditorTheme = EditorView.theme(
@@ -52,18 +53,18 @@ export function darkTheme(): Extension {
},
".cm-diagnostic-error": {
borderLeft: "2px solid #e11d48",
borderLeft: "2px solid var(--color-error)",
},
".cm-lint-marker-error": {
content: "none",
backgroundColor: "#e11d48",
backgroundColor: "var(--color-error)",
height: "100%",
width: "2px",
},
".cm-lintPoint:after": {
borderBottom: "4px solid #e11d48",
borderBottom: "4px solid var(--color-error)",
},
".cm-cursor, .cm-dropCursor": { borderLeftColor: cursor },
@@ -76,19 +77,19 @@ export function darkTheme(): Extension {
".cm-panels.cm-panels-bottom": { borderTop: "2px solid black" },
".cm-searchMatch": {
backgroundColor: "#72a1ff59",
outline: "1px solid #457dff",
backgroundColor: "var(--color-editor-search-match)",
outline: "1px solid var(--color-editor-search-match-outline)",
},
".cm-searchMatch.cm-searchMatch-selected": {
backgroundColor: "#6199ff2f",
backgroundColor: "var(--color-editor-search-match-selected)",
},
".cm-activeLine": { backgroundColor: highlightBackground },
".cm-selectionMatch": { backgroundColor: "#aafe661a" },
".cm-selectionMatch": { backgroundColor: "var(--color-editor-selection-match)" },
"&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket": {
backgroundColor: "rgba(18, 19, 23, 0.9)",
outline: "1px solid rgba(81, 90, 107, 0.5)",
backgroundColor: "var(--color-editor-matching-bracket)",
outline: "1px solid var(--color-editor-matching-bracket-outline)",
},
".cm-gutters": {
@@ -104,7 +105,7 @@ export function darkTheme(): Extension {
".cm-foldPlaceholder": {
backgroundColor: "transparent",
border: "none",
color: "#ddd",
color: "var(--color-editor-fold-placeholder)",
},
".cm-tooltip": {
+36 -36
View File
@@ -6,9 +6,9 @@ export const triggerDarkTheme: ThemeRegistrationAny = {
name: "trigger-dark",
type: "dark",
colors: {
"editor.background": "#212327",
"editor.foreground": "#878C99",
"editorLineNumber.foreground": "#484c54",
"editor.background": "var(--color-code-background)",
"editor.foreground": "var(--color-code-foreground)",
"editorLineNumber.foreground": "var(--color-code-line-number)",
},
tokenColors: [
// Control flow keywords: pink-purple
@@ -20,17 +20,17 @@ export const triggerDarkTheme: ThemeRegistrationAny = {
"keyword.other.operator",
"entity.name.operator",
],
settings: { foreground: "#E888F8" },
settings: { foreground: "var(--color-code-keyword)" },
},
// Storage type (const, let, var, function, class): purple
{
scope: "storage.type",
settings: { foreground: "#8271ED" },
settings: { foreground: "var(--color-code-storage)" },
},
// Storage modifiers (async, export, etc.): purple
{
scope: ["storage.modifier", "keyword.operator.noexcept"],
settings: { foreground: "#8271ED" },
settings: { foreground: "var(--color-code-storage)" },
},
// Keyword operator expressions (new, typeof, instanceof, etc.): purple
{
@@ -43,7 +43,7 @@ export const triggerDarkTheme: ThemeRegistrationAny = {
"keyword.operator.logical.python",
"keyword.operator.wordlike",
],
settings: { foreground: "#8271ED" },
settings: { foreground: "var(--color-code-storage)" },
},
// Types and namespaces: hot pink
{
@@ -56,12 +56,12 @@ export const triggerDarkTheme: ThemeRegistrationAny = {
"entity.name.class",
"entity.other.inherited-class",
],
settings: { foreground: "#F770C6" },
settings: { foreground: "var(--color-code-type)" },
},
// Functions: lime/yellow-green
{
scope: ["entity.name.function", "support.function"],
settings: { foreground: "#D9F07C" },
settings: { foreground: "var(--color-code-function)" },
},
// Variables and parameters: light lavender
{
@@ -72,27 +72,27 @@ export const triggerDarkTheme: ThemeRegistrationAny = {
"entity.name.variable",
"constant.other.placeholder",
],
settings: { foreground: "#CCCBFF" },
settings: { foreground: "var(--color-code-variable)" },
},
// Constants and enums: medium purple
{
scope: ["variable.other.constant", "variable.other.enummember"],
settings: { foreground: "#9C9AF2" },
settings: { foreground: "var(--color-code-constant)" },
},
// this/self: purple-blue
{
scope: "variable.language",
settings: { foreground: "#9B99FF" },
settings: { foreground: "var(--color-code-language)" },
},
// Object literal keys: medium purple-blue
{
scope: "meta.object-literal.key",
settings: { foreground: "#8B89FF" },
settings: { foreground: "var(--color-code-object-key)" },
},
// Strings: sage green
{
scope: ["string", "meta.embedded.assembly"],
settings: { foreground: "#AFEC73" },
settings: { foreground: "var(--color-code-string)" },
},
// String interpolation punctuation: blue-purple
{
@@ -101,27 +101,27 @@ export const triggerDarkTheme: ThemeRegistrationAny = {
"punctuation.definition.template-expression.end",
"punctuation.section.embedded",
],
settings: { foreground: "#7A78EA" },
settings: { foreground: "var(--color-code-template-punctuation)" },
},
// Template expression reset
{
scope: "meta.template.expression",
settings: { foreground: "#d4d4d4" },
settings: { foreground: "var(--color-code-plain)" },
},
// Operators: gray (same as foreground)
{
scope: "keyword.operator",
settings: { foreground: "#878C99" },
settings: { foreground: "var(--color-code-foreground)" },
},
// Comments: olive gray
{
scope: "comment",
settings: { foreground: "#6f736d" },
settings: { foreground: "var(--color-code-comment)" },
},
// Language constants (true, false, null, undefined): purple-blue
{
scope: "constant.language",
settings: { foreground: "#9B99FF" },
settings: { foreground: "var(--color-code-language)" },
},
// Numeric constants: light green
{
@@ -130,42 +130,42 @@ export const triggerDarkTheme: ThemeRegistrationAny = {
"keyword.operator.plus.exponent",
"keyword.operator.minus.exponent",
],
settings: { foreground: "#b5cea8" },
settings: { foreground: "var(--color-code-number)" },
},
// Regex: dark red
{
scope: "constant.regexp",
settings: { foreground: "#646695" },
settings: { foreground: "var(--color-code-regexp-constant)" },
},
// HTML/JSX tags: purple-blue
{
scope: "entity.name.tag",
settings: { foreground: "#9B99FF" },
settings: { foreground: "var(--color-code-language)" },
},
// Tag brackets: dark gray
{
scope: "punctuation.definition.tag",
settings: { foreground: "#5F6570" },
settings: { foreground: "var(--color-code-muted)" },
},
// HTML/JSX attributes: light purple
{
scope: "entity.other.attribute-name",
settings: { foreground: "#C39EFF" },
settings: { foreground: "var(--color-code-attribute)" },
},
// Escape characters: gold
{
scope: "constant.character.escape",
settings: { foreground: "#d7ba7d" },
settings: { foreground: "var(--color-code-escape)" },
},
// Regex string: dark red
{
scope: "string.regexp",
settings: { foreground: "#d16969" },
settings: { foreground: "var(--color-code-regexp)" },
},
// Storage: purple-blue
{
scope: "storage",
settings: { foreground: "#9B99FF" },
settings: { foreground: "var(--color-code-language)" },
},
// TS-specific: type casts, math/dom/json constants
{
@@ -176,47 +176,47 @@ export const triggerDarkTheme: ThemeRegistrationAny = {
"support.constant.dom",
"support.constant.json",
],
settings: { foreground: "#9B99FF" },
settings: { foreground: "var(--color-code-language)" },
},
// Markdown headings: purple-blue bold
{
scope: "markup.heading",
settings: { foreground: "#9B99FF", fontStyle: "bold" },
settings: { foreground: "var(--color-code-language)", fontStyle: "bold" },
},
// Markup bold: purple-blue
{
scope: "markup.bold",
settings: { foreground: "#9B99FF", fontStyle: "bold" },
settings: { foreground: "var(--color-code-language)", fontStyle: "bold" },
},
// Markup inline raw: sage green
{
scope: "markup.inline.raw",
settings: { foreground: "#AFEC73" },
settings: { foreground: "var(--color-code-string)" },
},
// Markup inserted: light green
{
scope: "markup.inserted",
settings: { foreground: "#b5cea8" },
settings: { foreground: "var(--color-code-number)" },
},
// Markup deleted: sage green
{
scope: "markup.deleted",
settings: { foreground: "#AFEC73" },
settings: { foreground: "var(--color-code-string)" },
},
// Markup changed: purple-blue
{
scope: "markup.changed",
settings: { foreground: "#9B99FF" },
settings: { foreground: "var(--color-code-language)" },
},
// Invalid: red
{
scope: "invalid",
settings: { foreground: "#f44747" },
settings: { foreground: "var(--color-code-invalid)" },
},
// JSX text content
{
scope: ["meta.jsx.children"],
settings: { foreground: "#D7D9DD" },
settings: { foreground: "var(--color-code-jsx-text)" },
},
],
};
@@ -103,9 +103,9 @@ export function AgentChart({ block }: { block: ChartBlock }) {
};
return (
<div className="overflow-hidden rounded-lg border border-charcoal-600 bg-charcoal-850">
<div className="overflow-hidden rounded-lg border border-border-bright bg-background-dimmed">
{block.title ? (
<div className="border-b border-charcoal-700 bg-charcoal-800 px-3 py-2 text-xs font-medium text-text-dimmed">
<div className="border-b border-grid-bright bg-background-bright px-3 py-2 text-xs font-medium text-text-dimmed">
{block.title}
</div>
) : null}
@@ -20,7 +20,7 @@ export function DashboardAgentComposer({
return (
<div className="border-t border-grid-bright p-3">
<div className="rounded-2xl border border-charcoal-650 bg-background-bright p-2 transition focus-within:border-charcoal-550">
<div className="rounded-2xl border border-border-bright bg-background-bright p-2 transition focus-within:border-border-brighter">
<div className="flex items-end gap-2">
<textarea
ref={ref}
@@ -34,7 +34,7 @@ export function DashboardAgentComposer({
}}
placeholder="Type a message…"
className={cn(
"max-h-[40vh] min-h-[40px] flex-1 resize-none border-0 bg-transparent px-2 py-1.5 text-sm text-text-bright placeholder-text-dimmed outline-none ring-0 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600 [field-sizing:content] focus:outline-none focus:ring-0"
"max-h-[40vh] min-h-[40px] flex-1 resize-none border-0 bg-transparent px-2 py-1.5 text-sm text-text-bright placeholder-text-dimmed outline-hidden ring-0 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control field-sizing-content focus:outline-hidden focus:ring-0"
)}
/>
{isStreaming ? (
@@ -8,7 +8,7 @@ export function DashboardAgentContextBanner({
currentPage: string;
}) {
return (
<div className="flex items-center gap-1.5 border-b border-grid-bright bg-charcoal-800/30 px-3 py-1.5 text-xs text-text-dimmed">
<div className="flex items-center gap-1.5 border-b border-grid-bright bg-background-bright/30 px-3 py-1.5 text-xs text-text-dimmed">
<span className="shrink-0">Context:</span>
<span className="truncate font-medium text-text-bright">{projectSlug}</span>
<span>/</span>
@@ -47,8 +47,8 @@ function IconButton({
aria-label={label}
onClick={onClick}
className={cn(
"rounded p-1.5 text-text-dimmed transition hover:bg-charcoal-700 hover:text-text-bright",
active && "bg-charcoal-700 text-text-bright"
"rounded p-1.5 text-text-dimmed transition hover:bg-background-raised hover:text-text-bright",
active && "bg-background-raised text-text-bright"
)}
>
<Icon className="size-4" />
@@ -25,12 +25,12 @@ export function DashboardAgentHistory({
onDelete: (chatId: string) => void;
}) {
return (
<div className="flex-1 overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600">
<div className="flex-1 overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control">
<div className="p-2">
<button
type="button"
onClick={onNewChat}
className="mb-1 flex w-full items-center gap-2 rounded-md px-2 py-2 text-left text-sm text-text-bright transition hover:bg-charcoal-800"
className="mb-1 flex w-full items-center gap-2 rounded-md px-2 py-2 text-left text-sm text-text-bright transition hover:bg-background-bright"
>
<PlusIcon className="size-4 text-green-500" />
New chat
@@ -46,14 +46,14 @@ export function DashboardAgentHistory({
<li key={chat.id}>
<div
className={cn(
"group flex items-center gap-2 rounded-sm px-2 py-1.5 transition-colors hover:bg-charcoal-800",
chat.id === currentChatId && "bg-charcoal-750 hover:bg-charcoal-750"
"group flex items-center gap-2 rounded-sm px-2 py-1.5 transition-colors hover:bg-background-bright",
chat.id === currentChatId && "bg-background-hover hover:bg-background-hover"
)}
>
<button
type="button"
onClick={() => onSelect(chat.id)}
className="flex min-w-0 flex-1 flex-col items-start gap-0.5 text-left outline-none focus-custom"
className="flex min-w-0 flex-1 flex-col items-start gap-0.5 text-left outline-hidden focus-custom"
>
<span className="line-clamp-1 text-sm text-text-bright">{chat.title}</span>
{chat.lastMessageAt && (
@@ -62,7 +62,7 @@ export function DashboardAgentMessages({
const rootRef = useAutoScrollToBottom([messages, isThinking]);
return (
<div className="flex-1 overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600">
<div className="flex-1 overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control">
<div ref={rootRef} className="space-y-4 p-4">
{messages.map((message) => (
<DashboardAgentMessageBubble key={message.id} message={stripStepParts(message)} />
@@ -28,7 +28,7 @@ export function DashboardAgentSuggestedPrompts({
key={prompt}
type="button"
onClick={() => onSelect(prompt)}
className="rounded-md border border-charcoal-700 bg-charcoal-800/40 px-3 py-2 text-left text-sm text-text-dimmed transition hover:border-charcoal-600 hover:text-text-bright"
className="rounded-md border border-grid-bright bg-background-bright/40 px-3 py-2 text-left text-sm text-text-dimmed transition hover:border-border-bright hover:text-text-bright"
>
{prompt}
</button>
@@ -30,7 +30,7 @@ const CATEGORY_LABELS: Record<DiagnosisBlock["category"], string> = {
const CONFIDENCE_STYLES: Record<DiagnosisBlock["confidence"], string> = {
high: "border-emerald-500/40 text-emerald-400",
medium: "border-amber-500/40 text-amber-400",
low: "border-charcoal-600 text-text-dimmed",
low: "border-border-bright text-text-dimmed",
};
const EVIDENCE_LABELS: Record<DiagnosisBlock["evidence"][number]["type"], string> = {
@@ -91,7 +91,7 @@ function EvidenceReference({ reference }: { reference: string }) {
function DiagnosisActions({ actions }: { actions: NonNullable<DiagnosisBlock["actions"]> }) {
const buttonClass =
"inline-flex items-center rounded border border-charcoal-600 bg-charcoal-800 px-2.5 py-1 text-xs text-text-bright transition-colors hover:border-charcoal-500 hover:bg-charcoal-750";
"inline-flex items-center rounded border border-border-bright bg-background-bright px-2.5 py-1 text-xs text-text-bright transition-colors hover:border-border-brightest hover:bg-background-hover";
return (
<div className="flex flex-wrap gap-2 pt-1">
{actions.map((action, i) => {
@@ -150,8 +150,8 @@ export function RunDiagnosisCard({ block }: { block: DiagnosisBlock }) {
const actions = block.actions ?? [];
return (
<div className="overflow-hidden rounded-lg border border-charcoal-600 bg-charcoal-850">
<div className="flex flex-wrap items-center gap-2 border-b border-charcoal-700 bg-charcoal-800 px-3 py-2">
<div className="overflow-hidden rounded-lg border border-border-bright bg-background-dimmed">
<div className="flex flex-wrap items-center gap-2 border-b border-grid-bright bg-background-bright px-3 py-2">
<span className="text-xs font-medium text-text-dimmed">Run diagnosis</span>
<Badge variant="small" className="border-rose-500/40 text-rose-400">
{CATEGORY_LABELS[block.category] ?? block.category}
@@ -174,7 +174,7 @@ export function RunDiagnosisCard({ block }: { block: DiagnosisBlock }) {
<ul className="space-y-1.5">
{evidence.map((item, i) => (
<li key={i} className="text-xs text-text-dimmed">
<span className="mr-1.5 rounded-sm bg-charcoal-700 px-1 py-0.5 text-[10px] uppercase tracking-wide text-text-dimmed">
<span className="mr-1.5 rounded-sm bg-background-raised px-1 py-0.5 text-[10px] uppercase tracking-wide text-text-dimmed">
{EVIDENCE_LABELS[item.type] ?? item.type}
</span>
<span className="text-text-bright">{item.detail}</span>
@@ -33,8 +33,8 @@ export function DashboardAgentLauncher() {
className={cn(
"flex shrink-0 items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs text-text-bright transition",
open
? "border-charcoal-550 bg-charcoal-750"
: "border-charcoal-650 bg-background-bright hover:border-charcoal-550"
? "border-border-brighter bg-background-hover"
: "border-border-bright bg-background-bright hover:border-border-brighter"
)}
>
{open ? (
@@ -89,7 +89,7 @@ const RegenerateApiKeyModalContent = ({
<Paragraph variant="small/bright">Enter this text below to confirm:</Paragraph>
<Paragraph
variant="small"
className="select-all rounded-md border border-grid-bright bg-charcoal-900 px-2 py-1 font-mono"
className="select-all rounded-md border border-grid-bright bg-background-deep px-2 py-1 font-mono"
>
{randomWord}
</Paragraph>
@@ -136,7 +136,7 @@ export function ConfigureErrorAlerts({
</div>
<fetcher.Form method="post" action={formAction} {...getFormProps(form)} className="contents">
<div className="flex-1 overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600">
<div className="flex-1 overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control">
<Fieldset className="flex flex-col gap-4 p-4">
<div className="flex flex-col">
<Header3>Receive alerts when</Header3>
@@ -82,7 +82,7 @@ export function BuildSettingsFields({
)}
</Hint>
</div>
<div className="flex flex-col gap-2 rounded border bg-charcoal-800 p-3">
<div className="flex flex-col gap-2 rounded border bg-background-bright p-3">
{availableEnvSlugs.map((slug) => {
const envType = envSlugToType(slug);
const disabled = isSlugDisabled(slug);
@@ -149,7 +149,7 @@ export function BuildSettingsFields({
variables from Vercel during builds.
</Hint>
</div>
<div className="flex flex-col gap-2 rounded border bg-charcoal-800 p-3">
<div className="flex flex-col gap-2 rounded border bg-background-bright p-3">
{availableEnvSlugs.map((slug) => {
const envType = envSlugToType(slug);
const disabled = isSlugDisabled(slug);
@@ -837,7 +837,7 @@ export function VercelOnboardingModal({
<Hint>
Once connected, your{" "}
<code className="text-xs rounded bg-charcoal-700 px-1 py-0.5 text-text-bright">
<code className="text-xs rounded bg-background-raised px-1 py-0.5 text-text-bright">
TRIGGER_SECRET_KEY
</code>{" "}
will be automatically synced to Vercel for each environment.
@@ -881,7 +881,7 @@ export function VercelOnboardingModal({
Select which custom Vercel environment should map to Trigger.dev's Staging
environment. Production and Preview environments are mapped automatically. If you
skip this step, the{" "}
<code className="rounded bg-charcoal-700 px-1 py-0.5 text-text-bright">
<code className="rounded bg-background-raised px-1 py-0.5 text-text-bright">
TRIGGER_SECRET_KEY
</code>{" "}
will not be installed for the staging environment in Vercel. You can configure this
@@ -958,7 +958,7 @@ export function VercelOnboardingModal({
for the recommended setup.
</Paragraph>
</div>
<div className="flex items-center justify-between rounded border bg-charcoal-800 p-3">
<div className="flex items-center justify-between rounded border bg-background-bright p-3">
<div>
<Label>Pull all environment variables now</Label>
<Hint>Select all variables to pull from Vercel.</Hint>
@@ -48,7 +48,7 @@ export const PageBody = forwardRef<
ref={ref}
className={cn(
scrollable
? "overflow-y-auto p-3 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600"
? "overflow-y-auto p-3 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control"
: "overflow-hidden",
className
)}
@@ -70,7 +70,7 @@ export function MainCenteredContainer({
return (
<div
className={cn(
"h-full w-full overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600",
"h-full w-full overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control",
variant === "onboarding" && "flex flex-col p-4 lg:p-0"
)}
>
@@ -95,10 +95,10 @@ export function MainHorizontallyCenteredContainer({
className?: string;
}) {
return (
<div className="w-full overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600">
<div className="w-full overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control">
<div
className={cn(
"mx-auto mt-6 max-w-lg overflow-y-auto p-1 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600 md:mt-14",
"mx-auto mt-6 max-w-lg overflow-y-auto p-1 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control md:mt-14",
className
)}
>
@@ -143,7 +143,7 @@ export function LogDetailView({ logId, initialLog, onClose, searchTerm }: LogDet
className="pl-1"
/>
</div>
<div className="overflow-y-auto px-3 py-3 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600">
<div className="overflow-y-auto px-3 py-3 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control">
<DetailsTab log={log} runPath={runPath} runStatus={runStatus} searchTerm={searchTerm} />
</div>
</div>
@@ -20,7 +20,7 @@ const allLogLevels: { level: LogLevel; label: string; color: string }[] = [
{ level: "INFO", label: "Info", color: "text-blue-400" },
{ level: "WARN", label: "Warning", color: "text-warning" },
{ level: "ERROR", label: "Error", color: "text-error" },
{ level: "DEBUG", label: "Debug", color: "text-charcoal-400" },
{ level: "DEBUG", label: "Debug", color: "text-text-dimmed" },
];
// In the future we might add other levels or change which are available
@@ -37,11 +37,11 @@ function getLevelBadgeColor(level: LogLevel): string {
case "TRACE":
return "text-purple-400 bg-purple-500/10 border-purple-500/20";
case "DEBUG":
return "text-charcoal-400 bg-charcoal-700 border-charcoal-600";
return "text-text-dimmed bg-background-raised border-border-bright";
case "INFO":
return "text-blue-400 bg-blue-500/10 border-blue-500/20";
default:
return "text-text-dimmed bg-charcoal-750 border-charcoal-700";
return "text-text-dimmed bg-background-hover border-grid-bright";
}
}
@@ -113,7 +113,7 @@ export function LogsTable({
}, [hasMore, isLoadingMore, onLoadMore]);
return (
<div className="relative h-full overflow-auto border-t scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600">
<div className="relative h-full overflow-auto border-t scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control">
<Table variant="compact/mono" containerClassName="overflow-visible" showTopBorder={false}>
<TableHeader className="sticky top-0 z-10">
<TableRow>
@@ -151,7 +151,7 @@ export function LogsTable({
key={log.id}
className={cn(
"cursor-pointer transition-colors",
isSelected ? "bg-charcoal-750" : "hover:bg-charcoal-850"
isSelected ? "bg-background-hover" : "hover:bg-background-dimmed"
)}
isSelected={isSelected}
>
@@ -187,7 +187,7 @@ export function LogsTable({
variant="minimal/small"
TrailingIcon={RunsIcon}
trailingIconClassName="text-text-bright"
className="h-[1.375rem] pl-1.5 pr-2"
className="h-5.5 pl-1.5 pr-2"
>
<span className="text-[0.6875rem] text-text-bright">View run</span>
</LinkButton>
@@ -40,7 +40,7 @@ export function BigNumber({
<div className="flex flex-col justify-between gap-4 rounded-sm border border-grid-dimmed bg-background-bright p-4">
<div className="flex flex-wrap items-center justify-between gap-2">
<Header3 className="leading-6">{title}</Header3>
{accessory && <div className="flex-shrink-0">{accessory}</div>}
{accessory && <div className="shrink-0">{accessory}</div>}
</div>
<div
className={cn(
@@ -227,7 +227,7 @@ export function QueryWidget({
LeadingIcon={Maximize2}
leadingIconClassName="text-text-dimmed group-hover/button:text-text-bright"
onClick={() => setIsFullscreen(true)}
className="!px-1"
className="px-1!"
/>
</span>
}
@@ -321,7 +321,7 @@ export function QueryWidget({
icon={TrashIcon}
title="Delete chart"
leadingIconClassName="text-error"
className="text-error hover:!bg-error/10"
className="text-error hover:bg-error/10!"
onClick={() => {
onDelete();
setIsMenuOpen(false);
@@ -97,7 +97,7 @@ export function SaveToDashboardDialog({
<Dialog open={isOpen} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-sm">
<DialogHeader>Add to dashboard</DialogHeader>
<div className="!mt-1 space-y-4">
<div className="mt-1! space-y-4">
<Paragraph variant="small" className="text-text-dimmed">
You don't have any custom dashboards yet. Create one first from the sidebar menu.
</Paragraph>
@@ -125,7 +125,7 @@ export function SaveToDashboardDialog({
<input type="hidden" name="query" value={query} />
<input type="hidden" name="config" value={JSON.stringify(config)} />
<div className="!mt-1 space-y-2">
<div className="mt-1! space-y-2">
<Paragraph variant="small" className="text-text-dimmed">
Select a dashboard to add this chart to:
</Paragraph>
@@ -143,8 +143,8 @@ export function SaveToDashboardDialog({
isAtLimit
? "cursor-not-allowed opacity-50"
: selectedDashboardId === dashboard.friendlyId
? "bg-charcoal-700 text-text-bright"
: "text-text-dimmed hover:bg-charcoal-750 hover:text-text-bright"
? "bg-background-raised text-text-bright"
: "text-text-dimmed hover:bg-background-hover hover:text-text-bright"
)}
>
{selectedDashboardId === dashboard.friendlyId ? (
@@ -72,7 +72,7 @@ export function ScopeFilter({ shortcut, value, onValueChange }: ScopeFilterProps
/>
</Ariakit.TooltipAnchor>
{shortcut && (
<Ariakit.Tooltip className="z-40 cursor-default rounded border border-charcoal-700 bg-background-bright py-1.5 pl-2.5 pr-2 text-xs text-text-dimmed">
<Ariakit.Tooltip className="z-40 cursor-default rounded border border-grid-bright bg-background-bright py-1.5 pl-2.5 pr-2 text-xs text-text-dimmed">
<div className="flex items-center gap-1.5">
<span>Change scope</span>
<ShortcutKey className="size-4 flex-none" shortcut={shortcut} variant="small" />
@@ -49,7 +49,7 @@ export function TitleWidget({
{title}
</span>
{hasMenu && (
<div className="flex-shrink-0 opacity-0 transition-opacity group-hover:opacity-100">
<div className="shrink-0 opacity-0 transition-opacity group-hover:opacity-100">
<Popover open={isMenuOpen} onOpenChange={setIsMenuOpen}>
<PopoverVerticalEllipseTrigger isOpen={isMenuOpen} />
<PopoverContent align="end" className="p-0">
@@ -70,7 +70,7 @@ export function TitleWidget({
icon={TrashIcon}
title="Delete"
leadingIconClassName="text-error"
className="text-error hover:!bg-error/10"
className="text-error hover:bg-error/10!"
onClick={() => {
onDelete();
setIsMenuOpen(false);
@@ -34,7 +34,7 @@ export function AccountSideMenu({ user }: { user: User }) {
<span className="text-text-bright">Back to app</span>
</LinkButton>
</div>
<div className="mb-6 flex grow flex-col overflow-y-auto px-1 pt-2 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600">
<div className="mb-6 flex grow flex-col overflow-y-auto px-1 pt-2 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control">
<SideMenuHeader title="Account" />
<SideMenuItem
name="Profile"
@@ -24,6 +24,7 @@ import { Label } from "../primitives/Label";
import { Paragraph } from "../primitives/Paragraph";
import { TextLink } from "../primitives/TextLink";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../primitives/Tooltip";
import { useThemeColor } from "~/hooks/useThemeColor";
import { v3BillingPath } from "~/utils/pathBuilder";
import { type SideMenuEnvironment, type SideMenuProject } from "./SideMenu";
@@ -90,7 +91,7 @@ export function CreateDashboardButton({
<DialogTrigger asChild>
<button
type="button"
className="flex h-full w-full items-center justify-center rounded text-text-dimmed focus-custom hover:bg-charcoal-600 hover:text-text-bright"
className="flex h-full w-full items-center justify-center rounded text-text-dimmed focus-custom hover:bg-surface-control hover:text-text-bright"
>
<PlusIcon className="size-4" />
</button>
@@ -161,8 +162,6 @@ export function CreateDashboardPageButton({
const PROGRESS_RING_R = 27.5;
const PROGRESS_RING_CIRCUMFERENCE = 2 * Math.PI * PROGRESS_RING_R;
const PROGRESS_COLOR_SUCCESS = "#28BF5C"; // mint-500 / success
const PROGRESS_COLOR_ERROR = "#E11D48"; // rose-600 / error
function CreateDashboardUpgradeDialog({
limits,
@@ -175,6 +174,11 @@ function CreateDashboardUpgradeDialog({
isFreePlan: boolean;
organization: { slug: string };
}) {
// Resolved to concrete colors - framer-motion can't interpolate var() strings.
// Must be called before the early return below (rules of hooks).
const progressColorSuccess = useThemeColor("--color-success", "#28bf5c");
const progressColorError = useThemeColor("--color-error", "#e11d48");
if (isFreePlan) {
return (
<DialogContent>
@@ -223,11 +227,11 @@ function CreateDashboardUpgradeDialog({
strokeLinecap="round"
initial={{
strokeDasharray: `0 ${PROGRESS_RING_CIRCUMFERENCE}`,
stroke: PROGRESS_COLOR_SUCCESS,
stroke: progressColorSuccess,
}}
animate={{
strokeDasharray: `${filled} ${PROGRESS_RING_CIRCUMFERENCE}`,
stroke: PROGRESS_COLOR_ERROR,
stroke: progressColorError,
}}
transition={{ duration: 1.2, ease: "easeInOut" }}
/>
@@ -173,7 +173,7 @@ function DashboardChildMenuItem({
? "text-text-bright"
: undefined;
const inactiveIconColor = isCollapsed ? "text-text-dimmed" : "text-charcoal-700";
const inactiveIconColor = isCollapsed ? "text-text-dimmed" : "text-tertiary";
return (
<SideMenuItem
@@ -73,7 +73,7 @@ export function EnvironmentSelector({
button={
<PopoverTrigger
className={cn(
"group flex h-8 items-center rounded pl-[0.4375rem] transition-colors hover:bg-charcoal-750",
"group flex h-8 items-center rounded pl-1.75 transition-colors hover:bg-background-hover",
isCollapsed ? "justify-center pr-0.5" : "justify-between pr-1",
className
)}
@@ -107,12 +107,12 @@ export function EnvironmentSelector({
side="right"
sideOffset={8}
hidden={!isCollapsed}
buttonClassName="!h-8"
buttonClassName="h-8!"
asChild
disableHoverableContent
/>
<PopoverContent
className="min-w-[14rem] overflow-y-auto p-0 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600"
className="min-w-56 overflow-y-auto p-0 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control"
side={isCollapsed ? "right" : "bottom"}
sideOffset={isCollapsed ? 8 : 4}
align="start"
@@ -257,7 +257,7 @@ function Branches({
<PopoverTrigger className="w-full justify-between overflow-hidden focus-custom">
<ButtonContent
variant="small-menu-item"
className="hover:bg-charcoal-750"
className="hover:bg-background-hover"
TrailingIcon={ChevronRightIcon}
trailingIconClassName="text-text-dimmed"
textAlignLeft
@@ -267,7 +267,7 @@ function Branches({
</ButtonContent>
</PopoverTrigger>
<PopoverContent
className="min-w-[16rem] overflow-y-auto p-0 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600"
className="min-w-64 overflow-y-auto p-0 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control"
align="start"
style={{ maxHeight: `calc(var(--radix-popover-content-available-height) - 10vh)` }}
side="right"
@@ -339,7 +339,7 @@ function Branches({
</div>
)}
</div>
<div className="border-t border-charcoal-700 p-1">
<div className="border-t border-grid-bright p-1">
{parentEnvironment.type === "DEVELOPMENT" ? (
<PopoverMenuItem
to={branchesDevPath(organization, project, environment)}
@@ -55,7 +55,7 @@ export function HelpAndFeedback({
button={
<PopoverTrigger
className={cn(
"group flex h-8 items-center gap-1.5 rounded pl-[0.4375rem] pr-2 transition-colors hover:bg-charcoal-750 focus-custom",
"group flex h-8 items-center gap-1.5 rounded pl-1.75 pr-2 transition-colors hover:bg-background-hover focus-custom",
isCollapsed ? "w-full" : "w-full justify-between"
)}
>
@@ -89,12 +89,12 @@ export function HelpAndFeedback({
side="right"
sideOffset={8}
hidden={!isCollapsed}
buttonClassName="!h-8 w-full"
buttonClassName="h-8! w-full"
asChild
disableHoverableContent
/>
<PopoverContent
className="min-w-[14rem] divide-y divide-grid-bright overflow-y-auto p-0 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600"
className="min-w-56 divide-y divide-grid-bright overflow-y-auto p-0 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control"
side={isCollapsed ? "right" : "top"}
sideOffset={isCollapsed ? 8 : 4}
align="start"
@@ -52,7 +52,7 @@ export function NotificationCard({
const safeImage = sanitizeUrl(image);
return (
<div className="group/card relative overflow-hidden rounded border border-charcoal-650 bg-charcoal-700/50 shadow-lg">
<div className="group/card relative overflow-hidden rounded border border-border-bright bg-background-raised/50 shadow-lg">
{safeActionUrl && (
<a
href={safeActionUrl}
@@ -71,7 +71,7 @@ export function NotificationCard({
onClick={handleDismiss}
aria-label="Dismiss notification"
title="Dismiss notification"
className="relative z-20 -mr-1 shrink-0 rounded p-0.5 text-text-dimmed opacity-0 transition group-hover/card:opacity-100 hover:bg-charcoal-700 hover:text-text-bright focus-visible:opacity-100"
className="relative z-20 -mr-1 shrink-0 rounded p-0.5 text-text-dimmed opacity-0 transition group-hover/card:opacity-100 hover:bg-background-raised hover:text-text-bright focus-visible:opacity-100"
>
<XMarkIcon className="size-3.5" />
</button>
@@ -123,7 +123,7 @@ function getMarkdownComponents(onLinkClick?: () => void) {
),
em: ({ children }: { children?: React.ReactNode }) => <em>{children}</em>,
code: ({ children }: { children?: React.ReactNode }) => (
<code className="rounded bg-charcoal-700 px-1 py-0.5 text-[11px]">{children}</code>
<code className="rounded bg-background-raised px-1 py-0.5 text-[11px]">{children}</code>
),
};
}
@@ -128,7 +128,7 @@ export function NotificationPanel({
button={
<div className="relative">
<PopoverTrigger asChild>
<Button variant="small-menu-item" className="h-8 w-[2.1875rem] justify-center">
<Button variant="small-menu-item" className="h-8 w-8.75 justify-center">
<NotificationIcon className="size-5 text-success" />
</Button>
</PopoverTrigger>
@@ -143,7 +143,7 @@ export function NotificationPanel({
card
)}
</div>
<PopoverContent side="right" sideOffset={8} align="end" className="w-56 !min-w-0 p-0">
<PopoverContent side="right" sideOffset={8} align="end" className="w-56 min-w-0! p-0">
{card}
</PopoverContent>
</Popover>
@@ -79,7 +79,7 @@ export function OrganizationSettingsSideMenu({
<span className="text-text-bright">Back to app</span>
</LinkButton>
</div>
<div className="mb-6 flex grow flex-col gap-4 overflow-y-auto px-1 pt-2 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600">
<div className="mb-6 flex grow flex-col gap-4 overflow-y-auto px-1 pt-2 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control">
<div className="flex flex-col">
<div className="mb-1">
<SideMenuHeader title="Organization" />
@@ -283,7 +283,7 @@ export function SideMenu({
<div
className={cn(
"relative h-full border-r border-grid-bright bg-background-bright transition-all duration-200",
isCollapsed ? "w-[2.75rem]" : "w-56"
isCollapsed ? "w-11" : "w-56"
)}
>
<CollapseToggle isCollapsed={isCollapsed} onToggle={handleToggleCollapsed} />
@@ -333,7 +333,7 @@ export function SideMenu({
"min-h-0 overflow-y-auto pt-2",
isCollapsed
? "scrollbar-none"
: "scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600"
: "scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control"
)}
ref={borderRef}
>
@@ -762,7 +762,7 @@ function V3DeprecationPanel({
>
<SimpleTooltip
button={
<PopoverTrigger className="flex !h-8 w-full items-center justify-center rounded border border-amber-500/30 bg-amber-500/15 transition-colors hover:border-amber-500/50 hover:bg-amber-500/25">
<PopoverTrigger className="flex h-8! w-full items-center justify-center rounded border border-amber-500/30 bg-amber-500/15 transition-colors hover:border-amber-500/50 hover:bg-amber-500/25">
<ExclamationTriangleIcon className="size-5 text-amber-400" />
</PopoverTrigger>
}
@@ -774,7 +774,7 @@ function V3DeprecationPanel({
/>
</motion.div>
</div>
<PopoverContent side="right" sideOffset={8} align="start" className="w-52 !min-w-0 p-0">
<PopoverContent side="right" sideOffset={8} align="start" className="w-52 min-w-0! p-0">
<V3DeprecationContent />
</PopoverContent>
</Popover>
@@ -801,7 +801,7 @@ function V3DeprecationContent() {
fullWidth
TrailingIcon={ArrowTopRightOnSquareIcon}
trailingIconClassName="text-amber-300"
className="border-amber-500/30 bg-amber-500/15 hover:!border-amber-500/50 hover:!bg-amber-500/25"
className="border-amber-500/30 bg-amber-500/15 hover:border-amber-500/50! hover:bg-amber-500/25!"
>
<span className="text-amber-300">View migration guide</span>
</LinkButton>
@@ -844,7 +844,7 @@ function ProjectSelector({
button={
<PopoverTrigger
className={cn(
"group flex h-8 items-center rounded pl-[0.4375rem] transition-colors hover:bg-charcoal-750",
"group flex h-8 items-center rounded pl-1.75 transition-colors hover:bg-background-hover",
isCollapsed ? "justify-center pr-0.5" : "w-full justify-between pr-1"
)}
>
@@ -876,22 +876,22 @@ function ProjectSelector({
side="right"
sideOffset={8}
hidden={!isCollapsed}
buttonClassName="!h-8"
buttonClassName="h-8!"
asChild
disableHoverableContent
/>
<PopoverContent
className="min-w-[16rem] overflow-y-auto p-0 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600"
className="min-w-64 overflow-y-auto p-0 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control"
side={isCollapsed ? "right" : "bottom"}
sideOffset={isCollapsed ? 8 : 4}
align="start"
style={{ maxHeight: `calc(var(--radix-popover-content-available-height) - 10vh)` }}
>
<div className="flex flex-col gap-2 bg-charcoal-750 p-2">
<div className="flex flex-col gap-2 bg-background-hover p-2">
<div className="flex items-center gap-2.5">
<Link
to={organizationSettingsPath(organization)}
className="group relative box-content size-10 overflow-clip rounded-sm bg-charcoal-800"
className="group relative box-content size-10 overflow-clip rounded-sm bg-background-bright"
>
<Avatar avatar={organization.avatar} size={2.5} orgName={organization.title} />
<div className="absolute inset-0 z-10 grid h-full w-full place-items-center bg-black/50 opacity-0 transition group-hover:opacity-100">
@@ -924,7 +924,7 @@ function ProjectSelector({
to={organizationSettingsPath(organization)}
fullWidth
iconSpacing="gap-1.5"
className="group-hover/button:border-charcoal-500"
className="group-hover/button:border-border-brightest"
>
<SlidersIcon className="size-4 text-text-dimmed" />
<span className="text-text-bright">Settings</span>
@@ -935,7 +935,7 @@ function ProjectSelector({
to={v3UsagePath(organization)}
fullWidth
iconSpacing="gap-1.5"
className="group-hover/button:border-charcoal-500"
className="group-hover/button:border-border-brightest"
>
<UsageIcon className="size-4 text-text-dimmed" />
<span className="text-text-bright">Usage</span>
@@ -963,7 +963,7 @@ function ProjectSelector({
})}
<PopoverMenuItem to={newProjectPath(organization)} title="New project" icon={PlusIcon} />
</div>
<div className="border-t border-charcoal-700 p-1">
<div className="border-t border-grid-bright p-1">
{organizations.length > 1 ? (
<SwitchOrganizations organizations={organizations} organization={organization} />
) : (
@@ -975,7 +975,7 @@ function ProjectSelector({
/>
)}
</div>
<div className="border-t border-charcoal-700 p-1">
<div className="border-t border-grid-bright p-1">
<PopoverMenuItem
to={accountPath()}
title="Account"
@@ -983,7 +983,7 @@ function ProjectSelector({
leadingIconClassName="text-text-dimmed"
/>
</div>
<div className="border-t border-charcoal-700 p-1">
<div className="border-t border-grid-bright p-1">
<PopoverMenuItem
to={logoutPath()}
title="Logout"
@@ -1041,7 +1041,7 @@ function SwitchOrganizations({
<PopoverTrigger className="w-full justify-between overflow-hidden focus-custom">
<ButtonContent
variant="small-menu-item"
className="hover:bg-charcoal-750"
className="hover:bg-background-hover"
LeadingIcon={ArrowLeftRightIcon}
leadingIconClassName="text-text-dimmed"
TrailingIcon={ChevronRightIcon}
@@ -1053,7 +1053,7 @@ function SwitchOrganizations({
</ButtonContent>
</PopoverTrigger>
<PopoverContent
className="min-w-[16rem] overflow-y-auto p-0 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600"
className="min-w-64 overflow-y-auto p-0 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control"
align="start"
style={{ maxHeight: `calc(var(--radix-popover-content-available-height) - 10vh)` }}
side="right"
@@ -1074,7 +1074,7 @@ function SwitchOrganizations({
/>
))}
</div>
<div className="border-t border-charcoal-700 p-1">
<div className="border-t border-grid-bright p-1">
<PopoverMenuItem
to={newOrganizationPath()}
title="New organization"
@@ -1096,7 +1096,7 @@ function SelectorDivider() {
y1="0.606339"
x2="0.606339"
y2="19.6362"
stroke="#3B3E45"
stroke="var(--color-border-bright)"
strokeLinecap="round"
/>
</svg>
@@ -1269,7 +1269,7 @@ function CollapseToggle({ isCollapsed, onToggle }: { isCollapsed: boolean; onTog
<div
className={cn(
"pointer-events-none absolute left-1/2 top-1/2 h-10 w-px -translate-y-1/2 transition-colors duration-200",
isHovering ? "bg-charcoal-750" : "bg-background-bright"
isHovering ? "bg-background-hover" : "bg-background-bright"
)}
/>
<TooltipProvider disableHoverableContent>
@@ -1284,7 +1284,7 @@ function CollapseToggle({ isCollapsed, onToggle }: { isCollapsed: boolean; onTog
className={cn(
"group flex h-12 w-6 items-center justify-center rounded-md text-text-dimmed transition-all duration-200 focus-custom",
isHovering
? "border border-grid-bright bg-background-bright shadow-md hover:bg-charcoal-750 hover:text-text-bright"
? "border border-grid-bright bg-background-bright shadow-md hover:bg-background-hover hover:text-text-bright"
: "border border-transparent bg-transparent"
)}
>
@@ -54,10 +54,10 @@ export function SideMenuHeader({
{children !== undefined ? (
<Popover onOpenChange={(open) => setHeaderMenuOpen(open)} open={isHeaderMenuOpen}>
<PopoverCustomTrigger className="p-1">
<EllipsisHorizontalIcon className="h-4 w-4 text-charcoal-500 transition group-hover:text-text-bright" />
<EllipsisHorizontalIcon className="h-4 w-4 text-text-faint transition group-hover:text-text-bright" />
</PopoverCustomTrigger>
<PopoverContent
className="min-w-max overflow-y-auto p-0 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600"
className="min-w-max overflow-y-auto p-0 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control"
align="start"
>
<div className="flex flex-col gap-1 p-1">{children}</div>
@@ -56,11 +56,11 @@ export function SideMenuItem({
target={target}
data-action={dataAction}
className={cn(
"group/menulink flex h-8 items-center gap-2 overflow-hidden rounded pl-[0.4375rem] pr-2",
"group/menulink flex h-8 items-center gap-2 overflow-hidden rounded pl-1.75 pr-2",
isIndented ? "min-w-0 flex-1" : "w-full",
isActive
? "bg-tertiary text-text-bright"
: "text-text-dimmed group-hover/menuitem:bg-charcoal-750 group-hover/menuitem:text-text-bright hover:bg-charcoal-750 hover:text-text-bright"
: "text-text-dimmed group-hover/menuitem:bg-background-hover group-hover/menuitem:text-text-bright hover:bg-background-hover hover:text-text-bright"
)}
>
<Icon
@@ -122,7 +122,7 @@ export function SideMenuItem({
content={name}
side="right"
sideOffset={8}
buttonClassName="!h-8 block w-full"
buttonClassName="h-8! block w-full"
hidden={!isCollapsed}
asChild
disableHoverableContent
@@ -131,7 +131,9 @@ export function SideMenuItem({
<div
className={cn(
"absolute bottom-1 right-1 top-1 flex aspect-square items-center justify-center rounded",
isActive ? "group-hover/menuitem:bg-tertiary" : "group-hover/menuitem:bg-charcoal-750"
isActive
? "group-hover/menuitem:bg-tertiary"
: "group-hover/menuitem:bg-background-hover"
)}
>
{action}
@@ -147,7 +149,7 @@ export function SideMenuItem({
content={name}
side="right"
sideOffset={8}
buttonClassName="!h-8 block w-full"
buttonClassName="h-8! block w-full"
hidden={!isCollapsed}
asChild
disableHoverableContent
@@ -40,7 +40,7 @@ export function SideMenuSection({
<div className="relative w-full">
{/* Header - fades out when sidebar is collapsed */}
<motion.div
className="group/section flex cursor-pointer items-center justify-between overflow-hidden rounded-sm py-1 pl-1.5 pr-1 transition hover:bg-charcoal-750"
className="group/section flex cursor-pointer items-center justify-between overflow-hidden rounded-sm py-1 pl-1.5 pr-1 transition hover:bg-background-hover"
initial={false}
animate={{
opacity: isSideMenuCollapsed ? 0 : 1,
@@ -63,7 +63,7 @@ export function SideMenuSection({
</motion.div>
{/* Divider - absolutely positioned, visible when sidebar is collapsed but section is expanded */}
<motion.div
className="absolute left-2 right-2 top-1 h-px bg-charcoal-600"
className="absolute left-2 right-2 top-1 h-px bg-surface-control"
initial={false}
animate={{
opacity: isSideMenuCollapsed && !isCollapsed ? 1 : 0,
@@ -281,7 +281,7 @@ export function TechnologyPicker({
}}
virtualFocus
>
<Ariakit.Select className="group flex h-8 w-full items-center rounded bg-charcoal-750 pl-2 pr-2.5 text-sm text-text-dimmed ring-charcoal-600 transition focus-custom hover:bg-charcoal-650 hover:ring-1">
<Ariakit.Select className="group flex h-8 w-full items-center rounded bg-background-hover pl-2 pr-2.5 text-sm text-text-dimmed ring-border-bright transition focus-custom hover:bg-secondary hover:ring-1">
<div className="flex grow items-center">
<CubeIcon className="mr-1.5 size-4 flex-none text-text-dimmed" />
<span>Select your technologies</span>
@@ -293,22 +293,22 @@ export function TechnologyPicker({
gutter={5}
unmountOnHide
className={cn(
"z-50 flex flex-col overflow-clip rounded border border-charcoal-700 bg-background-bright shadow-md outline-none animate-in fade-in-40",
"z-50 flex flex-col overflow-clip rounded border border-grid-bright bg-background-bright shadow-md outline-hidden animate-in fade-in-40",
"min-w-[max(180px,var(--popover-anchor-width))]",
"max-w-[min(480px,var(--popover-available-width))]",
"max-h-[min(400px,var(--popover-available-height))]"
)}
>
<div className="flex h-9 w-full flex-none items-center gap-2 border-b border-grid-dimmed bg-transparent px-3 text-xs text-text-dimmed outline-none">
<div className="flex h-9 w-full flex-none items-center gap-2 border-b border-grid-dimmed bg-transparent px-3 text-xs text-text-dimmed outline-hidden">
<MagnifyingGlassIcon className="size-3.5 flex-none text-text-dimmed" />
<Ariakit.Combobox
autoSelect
placeholder="Search technologies…"
className="flex-1 bg-transparent text-xs text-text-dimmed outline-none"
className="flex-1 bg-transparent text-xs text-text-dimmed outline-hidden"
/>
</div>
<Ariakit.ComboboxList className="overflow-y-auto overscroll-contain scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600 focus-custom">
<Ariakit.ComboboxList className="overflow-y-auto overscroll-contain scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control focus-custom">
{filteredOptions.map((option) => (
<Ariakit.ComboboxItem
key={option}
@@ -332,9 +332,9 @@ export function TechnologyPicker({
)}
</Ariakit.ComboboxList>
<div className="sticky bottom-0 border-t border-charcoal-700 bg-background-bright px-1 py-1">
<div className="sticky bottom-0 border-t border-grid-bright bg-background-bright px-1 py-1">
{showOtherInput ? (
<div className="flex h-8 w-full items-center rounded-sm bg-tertiary pl-0 pr-2 ring-1 ring-charcoal-650">
<div className="flex h-8 w-full items-center rounded-sm bg-tertiary pl-0 pr-2 ring-1 ring-border-bright">
<input
ref={otherInputRef}
type="text"
@@ -342,7 +342,7 @@ export function TechnologyPicker({
onChange={(e) => setOtherInputValue(e.target.value)}
onKeyDown={handleOtherKeyDown}
placeholder="Type and press Enter to add"
className="flex-1 border-none bg-transparent pl-2 text-2sm text-text-bright shadow-none outline-none ring-0 placeholder:text-text-dimmed focus:border-none focus:outline-none focus:ring-0"
className="flex-1 border-none bg-transparent pl-2 text-2sm text-text-bright shadow-none outline-hidden ring-0 placeholder:text-text-dimmed focus:border-none focus:outline-hidden focus:ring-0"
autoFocus
/>
<ShortcutKey
@@ -3,13 +3,13 @@ import { cn } from "~/utils/cn";
const variants = {
small: {
size: "size-[1rem]",
size: "size-4",
arrowHeadRight: "group-hover:translate-x-[3px]",
arrowLineRight: "h-[1.5px] w-[7px] translate-x-1 top-[calc(50%-0.5px)]",
arrowHeadLeft: "group-hover:translate-x-[3px]",
arrowLineLeft: "h-[1.5px] w-[7px] translate-x-1 top-[calc(50%-0.5px)]",
arrowHeadTopRight:
"-translate-x-0 transition group-hover:translate-x-[3px] group-hover:translate-y-[-3px]",
"translate-x-0 transition group-hover:translate-x-[3px] group-hover:translate-y-[-3px]",
},
medium: {
size: "size-[1.1rem]",
@@ -18,7 +18,7 @@ const variants = {
arrowHeadLeft: "group-hover:translate-x-[-3px]",
arrowLineLeft: "h-[1.5px] w-[9px] translate-x-1 top-[calc(50%-1px)]",
arrowHeadTopRight:
"-translate-x-0 transition group-hover:translate-x-[3px] group-hover:translate-y-[-3px]",
"translate-x-0 transition group-hover:translate-x-[3px] group-hover:translate-y-[-3px]",
},
large: {
size: "size-6",
@@ -27,7 +27,7 @@ const variants = {
arrowHeadLeft: "group-hover:translate-x-1",
arrowLineLeft: "h-[2.3px] w-[12px] translate-x-[6px] top-[calc(50%-1px)]",
arrowHeadTopRight:
"-translate-x-0 transition group-hover:translate-x-[3px] group-hover:translate-y-[-3px]",
"translate-x-0 transition group-hover:translate-x-[3px] group-hover:translate-y-[-3px]",
},
"extra-large": {
size: "size-8",
@@ -36,7 +36,7 @@ const variants = {
arrowHeadLeft: "group-hover:translate-x-1",
arrowLineLeft: "h-[3px] w-[16px] translate-x-[8px] top-[calc(50%-1.5px)]",
arrowHeadTopRight:
"-translate-x-0 transition group-hover:translate-x-[3px] group-hover:translate-y-[-3px]",
"translate-x-0 transition group-hover:translate-x-[3px] group-hover:translate-y-[-3px]",
},
};
@@ -4,11 +4,11 @@ import { cn } from "~/utils/cn";
const variants = {
"secondary/small": {
box: "h-6 bg-secondary rounded pl-1.5 gap-1.5 text-xs divide-x divide-black/15 group-hover:bg-charcoal-600 group-hover:border-charcoal-550 text-text-bright border border-charcoal-600",
box: "h-6 bg-secondary rounded pl-1.5 gap-1.5 text-xs divide-x divide-black/15 group-hover:bg-surface-control group-hover:border-border-brighter text-text-bright border border-border-bright",
clear: "size-6 text-text-bright hover:text-text-bright transition-colors",
},
"tertiary/small": {
box: "h-6 bg-tertiary rounded pl-1.5 gap-1.5 text-xs divide-x divide-black/15 group-hover:bg-charcoal-600",
box: "h-6 bg-tertiary rounded pl-1.5 gap-1.5 text-xs divide-x divide-black/15 group-hover:bg-surface-control",
clear: "size-6 text-text-dimmed hover:text-text-bright transition-colors",
},
"minimal/medium": {
@@ -53,7 +53,7 @@ export function AppliedFilter({
<div
className={cn("flex items-start leading-4", label === undefined ? "gap-1.5" : "gap-0.5")}
>
<div className="-mt-[0.5px] flex items-center gap-1.5">
<div className="mt-[-0.5px] flex items-center gap-1.5">
{icon}
{label && (
<div className="text-text-bright">
@@ -146,7 +146,7 @@ function AvatarLetters({
<span
className={cn(
"relative grid place-items-center overflow-hidden rounded-[10%] font-semibold",
includePadding ? "size-[80%]" : "size-[100%]"
includePadding ? "size-[80%]" : "size-full"
)}
style={style}
>
@@ -177,7 +177,7 @@ function AvatarIcon({
const IconComponent = avatarIcons[avatar.name];
return (
<span className="grid aspect-square place-items-center" style={styleFromSize(size)}>
<IconComponent className={includePadding ? "size-[80%]" : "size-[100%]"} style={style} />
<IconComponent className={includePadding ? "size-[80%]" : "size-full"} style={style} />
</span>
);
}
@@ -3,11 +3,11 @@ import { cn } from "~/utils/cn";
const variants = {
default:
"grid place-items-center rounded-full px-2 h-5 tracking-wider text-xxs bg-charcoal-750 text-text-bright uppercase whitespace-nowrap",
"grid place-items-center rounded-full px-2 h-5 tracking-wider text-xxs bg-background-hover text-text-bright uppercase whitespace-nowrap",
"extra-small":
"grid place-items-center border border-charcoal-650 rounded-sm px-1 h-4 text-xxs bg-background-bright text-blue-500 whitespace-nowrap",
"grid place-items-center border border-border-bright rounded-sm px-1 h-4 text-xxs bg-background-bright text-blue-500 whitespace-nowrap",
small:
"grid place-items-center border border-charcoal-650 rounded-sm px-1 h-5 text-xs bg-background-bright text-blue-500 whitespace-nowrap",
"grid place-items-center border border-border-bright rounded-sm px-1 h-5 text-xs bg-background-bright text-blue-500 whitespace-nowrap",
"outline-rounded":
"grid place-items-center rounded-full px-1 h-4 tracking-wider text-xxs border border-blue-500 text-blue-500 uppercase whitespace-nowrap",
rounded:
@@ -60,7 +60,7 @@ const theme = {
secondary: {
textColor: "text-text-bright transition group-disabled/button:text-text-dimmed/80",
button:
"bg-secondary group-hover/button:bg-charcoal-600 group-hover/button:border-charcoal-550 border border-charcoal-600 group-disabled/button:bg-secondary group-disabled/button:opacity-60 group-disabled/button:pointer-events-none",
"bg-secondary group-hover/button:bg-surface-control group-hover/button:border-border-brighter border border-border-bright group-disabled/button:bg-secondary group-disabled/button:opacity-60 group-disabled/button:pointer-events-none",
shortcut:
"border-text-dimmed/40 text-text-dimmed group-hover/button:text-text-bright group-hover/button:border-text-dimmed",
icon: "text-text-bright",
@@ -68,7 +68,7 @@ const theme = {
tertiary: {
textColor: "text-text-bright transition group-disabled/button:text-text-dimmed/80",
button:
"bg-tertiary group-hover/button:bg-charcoal-600 group-disabled/button:bg-tertiary group-disabled/button:opacity-60 group-disabled/button:pointer-events-none",
"bg-tertiary group-hover/button:bg-surface-control group-disabled/button:bg-tertiary group-disabled/button:opacity-60 group-disabled/button:pointer-events-none",
shortcut:
"border-text-dimmed/40 text-text-dimmed group-hover/button:text-text-bright group-hover/button:border-text-dimmed",
icon: "text-text-bright",
@@ -86,13 +86,13 @@ const theme = {
"text-text-bright group-hover/button:text-white transition group-disabled/button:text-text-bright/80",
button:
"bg-error group-hover/button:bg-rose-500 disabled:opacity-50 group-disabled/button:bg-error group-disabled/button:pointer-events-none",
shortcut: "border-text-bright text-text-bright group-hover/button:border-bright/60",
shortcut: "border-text-bright text-text-bright group-hover/button:border-text-bright/60",
icon: "text-text-bright",
},
docs: {
textColor: "text-blue-200/70 transition group-disabled/button:text-text-dimmed/80",
button:
"bg-charcoal-700 border border-charcoal-600/50 shadow group-hover/button:bg-charcoal-650 group-disabled/button:bg-tertiary group-disabled/button:opacity-60 group-disabled/button:pointer-events-none",
"bg-background-raised border border-border-bright/50 shadow-sm group-hover/button:bg-secondary group-disabled/button:bg-tertiary group-disabled/button:opacity-60 group-disabled/button:pointer-events-none",
shortcut:
"border-text-dimmed/40 text-text-dimmed group-hover/button:text-text-bright group-hover/button:border-text-dimmed",
icon: "text-blue-500",
@@ -140,7 +140,7 @@ const variant = {
"menu-item": {
textColor: "text-text-bright px-1",
button:
"h-9 px-[0.475rem] text-sm rounded-sm bg-transparent group-hover/button:bg-charcoal-750",
"h-9 px-[0.475rem] text-sm rounded-sm bg-transparent group-hover/button:bg-background-hover",
icon: "h-5",
iconSpacing: "gap-x-0.5",
shortcutVariant: undefined,
@@ -149,7 +149,7 @@ const variant = {
"small-menu-item": {
textColor: "text-text-bright",
button:
"h-[1.8rem] px-[0.4rem] text-2sm rounded-sm text-text-dimmed bg-transparent group-hover/button:bg-charcoal-750",
"h-[1.8rem] px-[0.4rem] text-2sm rounded-sm text-text-dimmed bg-transparent group-hover/button:bg-background-hover",
icon: "h-[1.125rem]",
iconSpacing: "gap-x-1.5",
shortcutVariant: undefined,
@@ -158,7 +158,7 @@ const variant = {
"small-menu-sub-item": {
textColor: "text-text-dimmed",
button:
"h-[1.8rem] px-[0.5rem] ml-5 text-2sm rounded-sm text-text-dimmed bg-transparent group-hover/button:bg-charcoal-750 focus-custom",
"h-[1.8rem] px-2 ml-5 text-2sm rounded-sm text-text-dimmed bg-transparent group-hover/button:bg-background-hover focus-custom",
icon: undefined,
iconSpacing: undefined,
shortcutVariant: undefined,
@@ -167,7 +167,7 @@ const variant = {
};
const allVariants = {
$all: "font-normal text-center font-sans justify-center items-center shrink-0 transition duration-150 rounded-[3px] select-none group-focus/button:outline-none group-disabled/button:opacity-75 group-disabled/button:pointer-events-none focus-custom",
$all: "font-normal text-center font-sans justify-center items-center shrink-0 transition duration-150 rounded-[3px] select-none group-focus/button:outline-hidden group-disabled/button:opacity-75 group-disabled/button:pointer-events-none focus-custom",
variant: variant,
};
@@ -343,7 +343,7 @@ export const Button = forwardRef<HTMLButtonElement, ButtonPropsType>(
const buttonElement = (
<button
className={cn("group/button outline-none focus-custom", props.fullWidth ? "w-full" : "")}
className={cn("group/button outline-hidden focus-custom", props.fullWidth ? "w-full" : "")}
type={type}
disabled={isDisabled}
onClick={onClick}
@@ -415,7 +415,7 @@ export const LinkButton = ({
return (
<div
className={cn(
"group/button pointer-events-none cursor-default opacity-40 outline-none",
"group/button pointer-events-none cursor-default opacity-40 outline-hidden",
props.fullWidth ? "w-full" : ""
)}
>
@@ -466,7 +466,7 @@ export const NavLinkButton = ({ to, className, target, ...props }: NavLinkPropsT
return (
<NavLink
to={to}
className={cn("group/button outline-none block", props.fullWidth ? "w-full" : "")}
className={cn("group/button outline-hidden block", props.fullWidth ? "w-full" : "")}
target={target}
>
{({ isActive, isPending }) => (
@@ -9,7 +9,7 @@ import { cn } from "~/utils/cn";
export type CalendarProps = React.ComponentProps<typeof DayPicker>;
const navButtonClass =
"size-7 rounded-[3px] bg-secondary border border-charcoal-600 text-text-bright hover:bg-charcoal-600 hover:border-charcoal-550 transition inline-flex items-center justify-center";
"size-7 rounded-[3px] bg-secondary border border-border-bright text-text-bright hover:bg-surface-control hover:border-border-brighter transition inline-flex items-center justify-center";
function CustomMonthCaption({ calendarMonth }: { calendarMonth: { date: Date } }) {
const { goToMonth, nextMonth, previousMonth } = useDayPicker();
@@ -27,7 +27,7 @@ function CustomMonthCaption({ calendarMonth }: { calendarMonth: { date: Date } }
</button>
<div className="flex items-center gap-2">
<select
className="rounded border border-charcoal-600 bg-charcoal-750 px-2 py-1 text-sm text-text-bright focus:border-charcoal-500 focus:outline-none"
className="rounded border border-border-bright bg-background-hover px-2 py-1 text-sm text-text-bright focus:border-border-brightest focus:outline-hidden"
value={calendarMonth.date.getMonth()}
onChange={(e) => {
const newDate = new Date(calendarMonth.date);
@@ -42,7 +42,7 @@ function CustomMonthCaption({ calendarMonth }: { calendarMonth: { date: Date } }
))}
</select>
<select
className="rounded border border-charcoal-600 bg-charcoal-750 px-2 py-1 text-sm text-text-bright focus:border-charcoal-500 focus:outline-none"
className="rounded border border-border-bright bg-background-hover px-2 py-1 text-sm text-text-bright focus:border-border-brightest focus:outline-hidden"
value={calendarMonth.date.getFullYear()}
onChange={(e) => {
const newDate = new Date(calendarMonth.date);
@@ -94,26 +94,26 @@ export function Calendar({
weekdays: "flex",
weekday: "text-text-dimmed rounded-md w-8 font-normal text-[0.8rem]",
week: "flex w-full mt-2",
day: "relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-charcoal-700 [&:has([aria-selected].day-outside)]:bg-charcoal-700/50 [&:has([aria-selected].day-range-end)]:rounded-r-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md",
day: "relative p-0 text-center text-sm focus-within:relative focus-within:z-20 has-aria-[selected]:bg-background-raised [&:has([aria-selected].day-outside)]:bg-background-raised/50 [&:has([aria-selected].day-range-end)]:rounded-r-md first:has-aria-[selected]:rounded-l-md last:has-aria-[selected]:rounded-r-md",
day_button: cn(
"size-8 p-0 font-normal text-text-bright rounded-md",
"hover:bg-charcoal-700 hover:text-text-bright",
"focus:bg-charcoal-700 focus:text-text-bright focus:outline-none",
"hover:bg-background-raised hover:text-text-bright",
"focus:bg-background-raised focus:text-text-bright focus:outline-hidden",
"aria-selected:opacity-100"
),
range_start: "day-range-start rounded-l-md",
range_end: "day-range-end rounded-r-md",
selected:
"bg-indigo-600 text-text-bright hover:bg-indigo-600 hover:text-text-bright focus:bg-indigo-600 focus:text-text-bright rounded-md",
today: "bg-charcoal-700 text-text-bright rounded-md",
today: "bg-background-raised text-text-bright rounded-md",
outside:
"day-outside text-text-dimmed opacity-50 aria-selected:bg-charcoal-700/50 aria-selected:text-text-dimmed aria-selected:opacity-30",
"day-outside text-text-dimmed opacity-50 aria-selected:bg-background-raised/50 aria-selected:text-text-dimmed aria-selected:opacity-30",
disabled: "text-text-dimmed opacity-50",
range_middle: "aria-selected:bg-charcoal-700 aria-selected:text-text-bright",
range_middle: "aria-selected:bg-background-raised aria-selected:text-text-bright",
hidden: "invisible",
dropdowns: "flex gap-2 items-center justify-center",
dropdown:
"bg-charcoal-750 border border-charcoal-600 rounded px-2 py-1 text-sm text-text-bright focus:outline-none focus:border-charcoal-500",
"bg-background-hover border border-border-bright rounded px-2 py-1 text-sm text-text-bright focus:outline-hidden focus:border-border-brightest",
...classNames,
}}
components={{
@@ -18,52 +18,52 @@ import { Spinner } from "./Spinner";
export const variantClasses = {
info: {
className: "border-charcoal-700 bg-charcoal-800",
className: "border-grid-bright bg-background-bright",
icon: <InformationCircleIcon className="h-5 w-5 shrink-0 text-text-dimmed" />,
textColor: "text-text-bright",
linkClassName: "transition hover:bg-charcoal-750",
linkClassName: "transition hover:bg-background-hover",
},
warning: {
className: "border-warning/20 bg-warning/10",
icon: <ExclamationTriangleIcon className="h-5 w-5 shrink-0 text-warning" />,
textColor: "text-yellow-200",
textColor: "text-callout-warning-text",
linkClassName: "transition hover:bg-warning/20",
},
error: {
className: "border-error/20 bg-error/10",
icon: <ExclamationCircleIcon className="h-5 w-5 shrink-0 text-error" />,
textColor: "text-rose-200",
textColor: "text-callout-error-text",
linkClassName: "transition hover:bg-error/20",
},
idea: {
className: "border-success/20 bg-success/10",
icon: <LightBulbIcon className="h-5 w-5 shrink-0 text-success" />,
textColor: "text-green-200",
textColor: "text-callout-success-text",
linkClassName: "transition hover:bg-success/20",
},
success: {
className: "border-success/20 bg-success/10",
icon: <CheckCircleIcon className="h-5 w-5 shrink-0 text-success" />,
textColor: "text-green-200",
textColor: "text-callout-success-text",
linkClassName: "transition hover:bg-success/20",
},
docs: {
className: "border-blue-400/20 bg-blue-400/10",
icon: <BookOpenIcon className="mt-0.5 h-5 w-5 shrink-0 text-blue-400" />,
textColor: "text-blue-200",
linkClassName: "transition hover:bg-blue-400/20",
className: "border-callout-docs/20 bg-callout-docs/10",
icon: <BookOpenIcon className="mt-0.5 h-5 w-5 shrink-0 text-callout-docs" />,
textColor: "text-callout-docs-text",
linkClassName: "transition hover:bg-callout-docs/20",
},
pending: {
className: "border-blue-400/20 bg-blue-800/30",
className: "border-callout-pending/20 bg-callout-pending-bg/30",
icon: <Spinner className="h-5 w-5 shrink-0 " />,
textColor: "text-blue-300",
linkClassName: "transition hover:bg-blue-400/20",
textColor: "text-callout-pending-text",
linkClassName: "transition hover:bg-callout-pending/20",
},
pricing: {
className: "border-indigo-400/20 bg-indigo-800/30",
icon: <CreditCardIcon className="h-5 w-5 shrink-0 text-indigo-400" />,
textColor: "text-indigo-300",
linkClassName: "transition hover:bg-indigo-400/20",
className: "border-callout-pricing/20 bg-callout-pricing-bg/30",
icon: <CreditCardIcon className="h-5 w-5 shrink-0 text-callout-pricing" />,
textColor: "text-callout-pricing-text",
linkClassName: "transition hover:bg-callout-pricing/20",
},
} as const;
@@ -93,7 +93,7 @@ export function Callout({
href={to}
target="_blank"
className={cn(
`flex w-full items-start justify-between gap-2.5 rounded-md border py-2 pl-2 pr-3 shadow-md backdrop-blur-sm`,
`flex w-full items-start justify-between gap-2.5 rounded-md border py-2 pl-2 pr-3 shadow-md backdrop-blur-xs`,
variantDefinition.className,
variantDefinition.linkClassName,
className
@@ -118,7 +118,7 @@ export function Callout({
<Link
to={to}
className={cn(
`flex w-full items-start justify-between gap-2.5 rounded-md border py-2 pl-2 pr-3 shadow-md backdrop-blur-sm`,
`flex w-full items-start justify-between gap-2.5 rounded-md border py-2 pl-2 pr-3 shadow-md backdrop-blur-xs`,
variantDefinition.className,
variantDefinition.linkClassName,
className
@@ -146,7 +146,7 @@ export function Callout({
return (
<div
className={cn(
"flex w-full items-start gap-2 rounded-md border pl-2 pr-2 shadow-md backdrop-blur-sm",
"flex w-full items-start gap-2 rounded-md border pl-2 pr-2 shadow-md backdrop-blur-xs",
cta ? "py-2" : "py-2.5",
variantDefinition.className,
className
@@ -23,28 +23,28 @@ const variants = {
},
"button/small": {
button:
"flex items-center w-fit h-8 pl-2 pr-3 rounded border border-charcoal-600 hover:bg-charcoal-850 hover:border-charcoal-500 transition",
"flex items-center w-fit h-8 pl-2 pr-3 rounded border border-border-bright hover:bg-background-dimmed hover:border-border-brightest transition",
label: "text-sm text-text-bright select-none",
description: "text-text-dimmed",
inputPosition: "mt-0",
isChecked: "bg-charcoal-850 border-charcoal-750 hover:!bg-charcoal-850",
isChecked: "bg-background-dimmed border-grid-dimmed hover:bg-background-dimmed!",
isDisabled: "opacity-70 hover:bg-transparent",
},
button: {
button:
"w-fit py-2 pl-3 pr-4 rounded border border-charcoal-600 hover:bg-charcoal-850 hover:border-charcoal-500 transition",
"w-fit py-2 pl-3 pr-4 rounded border border-border-bright hover:bg-background-dimmed hover:border-border-brightest transition",
label: "text-text-bright select-none",
description: "text-text-dimmed",
inputPosition: "mt-1",
isChecked: "bg-charcoal-850 border-charcoal-750 hover:!bg-charcoal-850",
isChecked: "bg-background-dimmed border-grid-dimmed hover:bg-background-dimmed!",
isDisabled: "opacity-70 hover:bg-transparent",
},
description: {
button: "w-full py-2 pl-3 pr-4 checked:hover:bg-charcoal-850 transition",
button: "w-full py-2 pl-3 pr-4 checked:hover:bg-background-dimmed transition",
label: "text-text-bright font-semibold",
description: "text-text-dimmed",
inputPosition: "mt-1",
isChecked: "bg-charcoal-850",
isChecked: "bg-background-dimmed",
isDisabled: "opacity-70",
},
};
@@ -139,7 +139,7 @@ export const CheckboxWithLabel = React.forwardRef<HTMLInputElement, CheckboxProp
className={cn(
inputPositionClasses,
props.readOnly || disabled ? "cursor-default" : "cursor-pointer",
"read-only:border-charcoal-650 disabled:border-charcoal-650 rounded-sm border border-charcoal-600 bg-transparent transition checked:!bg-indigo-500 read-only:!bg-charcoal-700 group-hover:bg-charcoal-900 group-hover:checked:bg-indigo-500 group-focus:ring-1 focus:ring-indigo-500 focus:ring-offset-0 focus:ring-offset-transparent focus-visible:outline-none focus-visible:ring-indigo-500 disabled:!bg-charcoal-700"
"read-only:border-border-bright disabled:border-border-bright rounded-sm border border-border-bright bg-transparent transition checked:bg-indigo-500! read-only:bg-background-raised! group-hover:bg-background-deep checked:group-hover:bg-indigo-500 group-focus:ring-1 focus:ring-indigo-500 focus:ring-offset-0 focus:ring-offset-transparent focus-visible:outline-hidden focus-visible:ring-indigo-500 disabled:bg-background-raised!"
)}
id={id}
ref={ref}
@@ -189,7 +189,7 @@ export const Checkbox = forwardRef<HTMLInputElement, SimpleCheckboxProps>(
: props.readOnly
? "cursor-default"
: "cursor-pointer",
"read-only:border-charcoal-650 disabled:border-charcoal-650 disabled:opacity-50 rounded-sm border border-charcoal-600 bg-transparent transition checked:!bg-indigo-500 read-only:!bg-charcoal-700 group-hover:bg-charcoal-900 group-hover:checked:bg-indigo-500 group-focus:ring-1 focus:ring-indigo-500 focus:ring-offset-0 focus:ring-offset-transparent focus-visible:outline-none focus-visible:ring-indigo-500 disabled:!bg-charcoal-700"
"read-only:border-border-bright disabled:border-border-bright disabled:opacity-50 rounded-sm border border-border-bright bg-transparent transition checked:bg-indigo-500! read-only:bg-background-raised! group-hover:bg-background-deep checked:group-hover:bg-indigo-500 group-focus:ring-1 focus:ring-indigo-500 focus:ring-offset-0 focus:ring-offset-transparent focus-visible:outline-hidden focus-visible:ring-indigo-500 disabled:bg-background-raised!"
)}
{...props}
ref={ref}
@@ -5,7 +5,7 @@ export function CheckboxIndicator({ checked }: { checked: boolean }) {
<div
className={cn(
"flex size-4 flex-none items-center justify-center rounded border",
checked ? "border-indigo-500 bg-indigo-600" : "border-charcoal-600 bg-charcoal-700"
checked ? "border-indigo-500 bg-indigo-600" : "border-border-bright bg-background-raised"
)}
>
{checked && (
@@ -70,7 +70,7 @@ const ClientTabsList = React.forwardRef<
const variantClassName = (() => {
switch (variant) {
case "segmented":
return "relative flex h-10 w-full items-center rounded bg-charcoal-700/50 p-1";
return "relative flex h-10 w-full items-center rounded bg-background-raised/50 p-1";
case "underline":
return "flex gap-x-6 border-b border-grid-bright";
default:
@@ -122,10 +122,10 @@ const ClientTabsTrigger = React.forwardRef<
<motion.div
layoutId={layoutId}
transition={{ duration: 0.4, type: "spring" }}
className="absolute inset-0 rounded-[2px] border border-charcoal-500/50 bg-charcoal-600"
className="absolute inset-0 rounded-[2px] border border-border-brightest/50 bg-surface-control"
/>
) : (
<div className="absolute inset-0 rounded-[2px] border border-charcoal-500/50 bg-charcoal-600" />
<div className="absolute inset-0 rounded-[2px] border border-border-brightest/50 bg-surface-control" />
)
) : null}
</TabsPrimitive.Trigger>
@@ -159,12 +159,12 @@ const ClientTabsTrigger = React.forwardRef<
className="mt-1 h-0.5 w-full bg-indigo-500"
/>
) : (
<div className="mt-1 h-0.5 w-full bg-charcoal-500 opacity-0 transition duration-200 group-hover:opacity-100" />
<div className="mt-1 h-0.5 w-full bg-surface-control-active opacity-0 transition duration-200 group-hover:opacity-100" />
)
) : isActive ? (
<div className="mt-1 h-0.5 w-full bg-indigo-500" />
) : (
<div className="mt-1 h-0.5 w-full bg-charcoal-500 opacity-0 transition duration-200 group-hover:opacity-100" />
<div className="mt-1 h-0.5 w-full bg-surface-control-active opacity-0 transition duration-200 group-hover:opacity-100" />
)}
</TabsPrimitive.Trigger>
);
@@ -175,7 +175,7 @@ const ClientTabsTrigger = React.forwardRef<
ref={ref}
tabIndex={0}
className={cn(
"inline-flex items-center justify-center whitespace-nowrap border-r border-charcoal-700 px-2 text-sm transition-all first:pl-0 last:border-none focus-custom data-[state=active]:text-indigo-500 data-[state=inactive]:text-text-dimmed data-[state=inactive]:hover:text-text-bright disabled:pointer-events-none disabled:opacity-50",
"inline-flex items-center justify-center whitespace-nowrap border-r border-grid-bright px-2 text-sm transition-all first:pl-0 last:border-none focus-custom data-[state=active]:text-indigo-500 data-[state=inactive]:text-text-dimmed data-[state=inactive]:hover:text-text-bright disabled:pointer-events-none disabled:opacity-50",
className
)}
{...props}
@@ -193,7 +193,7 @@ const ClientTabsContent = React.forwardRef<
<TabsPrimitive.Content
ref={ref}
tabIndex={-1}
className={cn("mt-1 outline-none", className, "data-[state=inactive]:hidden")}
className={cn("mt-1 outline-hidden", className, "data-[state=inactive]:hidden")}
{...props}
/>
));
@@ -5,7 +5,7 @@ import { CopyButton } from "./CopyButton";
const variants = {
"primary/small": {
container:
"flex items-center text-text-dimmed font-mono rounded border bg-charcoal-750 text-xs transition hover:bg-charcoal-700 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 focus:border-transparent focus:outline-none focus:ring-0 focus:ring-transparent",
"flex items-center text-text-dimmed font-mono rounded border bg-background-hover text-xs transition hover:bg-background-raised focus-visible:outline-hidden focus-visible:ring-0 focus-visible:ring-offset-0 focus:border-transparent focus:outline-hidden focus:ring-0 focus:ring-transparent",
input:
"bg-transparent border-0 text-xs px-2 w-auto rounded-l h-6 leading-6 focus:ring-transparent",
buttonVariant: "primary" as const,
@@ -14,26 +14,26 @@ const variants = {
},
"secondary/small": {
container:
"flex items-center text-text-dimmed font-mono rounded border bg-charcoal-750 text-xs transition hover:bg-charcoal-700 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 focus:border-transparent focus:outline-none focus:ring-0 focus:ring-transparent",
"flex items-center text-text-dimmed font-mono rounded border bg-background-hover text-xs transition hover:bg-background-raised focus-visible:outline-hidden focus-visible:ring-0 focus-visible:ring-offset-0 focus:border-transparent focus:outline-hidden focus:ring-0 focus:ring-transparent",
input:
"bg-transparent border-0 text-xs px-2 w-auto rounded-l h-6 leading-6 focus:ring-transparent",
buttonVariant: "tertiary" as const,
size: "small" as const,
button: "rounded-l-none border-l border-charcoal-750",
button: "rounded-l-none border-l border-grid-dimmed",
},
"tertiary/small": {
container:
"group/clipboard flex items-center text-text-dimmed font-mono rounded bg-transparent border border-transparent text-xs transition duration-150 hover:border-charcoal-700 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 focus:border-transparent focus:outline-none focus:ring-0 focus:ring-transparent",
"group/clipboard flex items-center text-text-dimmed font-mono rounded bg-transparent border border-transparent text-xs transition duration-150 hover:border-grid-bright focus-visible:outline-hidden focus-visible:ring-0 focus-visible:ring-offset-0 focus:border-transparent focus:outline-hidden focus:ring-0 focus:ring-transparent",
input:
"bg-transparent border-0 text-xs px-2 w-auto rounded-l h-6 leading-6 focus:ring-transparent",
buttonVariant: "minimal" as const,
size: "small" as const,
button:
"rounded-l-none border-l border-transparent transition group-hover/clipboard:border-charcoal-700",
"rounded-l-none border-l border-transparent transition group-hover/clipboard:border-grid-bright",
},
"primary/medium": {
container:
"flex items-center text-text-dimmed font-mono rounded border bg-charcoal-750 text-sm transition hover:bg-charcoal-700 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 focus:border-transparent focus:outline-none focus:ring-0 focus:ring-transparent",
"flex items-center text-text-dimmed font-mono rounded border bg-background-hover text-sm transition hover:bg-background-raised focus-visible:outline-hidden focus-visible:ring-0 focus-visible:ring-offset-0 focus:border-transparent focus:outline-hidden focus:ring-0 focus:ring-transparent",
input:
"bg-transparent border-0 text-sm px-3 w-auto rounded-l h-8 leading-6 focus:ring-transparent",
buttonVariant: "primary" as const,
@@ -42,21 +42,21 @@ const variants = {
},
"secondary/medium": {
container:
"flex items-center text-text-dimmed font-mono rounded bg-charcoal-750 text-sm transition hover:bg-charcoal-700 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 focus:border-transparent focus:outline-none focus:ring-0 focus:ring-transparent",
"flex items-center text-text-dimmed font-mono rounded bg-background-hover text-sm transition hover:bg-background-raised focus-visible:outline-hidden focus-visible:ring-0 focus-visible:ring-offset-0 focus:border-transparent focus:outline-hidden focus:ring-0 focus:ring-transparent",
input:
"bg-transparent border-0 text-sm px-3 w-auto rounded-l h-8 leading-6 focus:ring-transparent",
buttonVariant: "tertiary" as const,
size: "medium" as const,
button: "rounded-l-none border-l border-charcoal-750",
button: "rounded-l-none border-l border-grid-dimmed",
},
"tertiary/medium": {
container:
"group flex items-center text-text-dimmed font-mono rounded bg-transparent border border-transparent text-sm transition hover:border-charcoal-700 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 focus:border-transparent focus:outline-none focus:ring-0 focus:ring-transparent",
"group flex items-center text-text-dimmed font-mono rounded bg-transparent border border-transparent text-sm transition hover:border-grid-bright focus-visible:outline-hidden focus-visible:ring-0 focus-visible:ring-offset-0 focus:border-transparent focus:outline-hidden focus:ring-0 focus:ring-transparent",
input:
"bg-transparent border-0 text-sm px-3 w-auto rounded-l h-8 leading-6 focus:ring-transparent",
buttonVariant: "minimal" as const,
size: "medium" as const,
button: "rounded-l-none border-l border-transparent transition group-hover:border-charcoal-700",
button: "rounded-l-none border-l border-transparent transition group-hover:border-grid-bright",
},
};
@@ -50,10 +50,10 @@ export function CopyButton({
onClick={copy}
className={cn(
buttonSize,
"flex items-center justify-center rounded border border-charcoal-650 bg-charcoal-750",
"flex items-center justify-center rounded border border-border-bright bg-background-hover",
copied
? "text-green-500"
: "text-text-dimmed hover:border-charcoal-600 hover:bg-charcoal-700 hover:text-text-bright",
: "text-text-dimmed hover:border-border-bright hover:bg-background-raised hover:text-text-bright",
buttonClassName
)}
>
@@ -42,11 +42,11 @@ export function CopyableText({
button={
<span
className={cn(
"ml-1 flex size-6 items-center justify-center rounded border border-charcoal-650 bg-charcoal-750",
"ml-1 flex size-6 items-center justify-center rounded border border-border-bright bg-background-hover",
asChild && "p-1",
copied
? "text-green-500"
: "text-text-dimmed hover:border-charcoal-600 hover:bg-charcoal-700 hover:text-text-bright"
: "text-text-dimmed hover:border-border-bright hover:bg-background-raised hover:text-text-bright"
)}
>
{copied ? (
@@ -120,7 +120,7 @@ export function DateField({
{...fieldProps}
ref={ref}
className={cn(
"flex rounded-sm border bg-charcoal-700 p-0.5 transition focus-within:border-charcoal-600 hover:border-charcoal-600",
"flex rounded-sm border bg-background-raised p-0.5 transition focus-within:border-border-bright hover:border-border-bright",
fieldClassName
)}
>
@@ -227,15 +227,15 @@ function DateSegment({ segment, state, variant }: DateSegmentProps) {
minWidth: minWidthForSegment(segment),
}}
className={cn(
"group box-content text-center tabular-nums outline-none focus:bg-charcoal-600 focus:text-text-bright",
"group box-content text-center tabular-nums outline-hidden focus:bg-surface-control focus:text-text-bright",
sizeVariant.fieldStyles,
!segment.isEditable ? "text-charcoal-500" : "text-text-bright"
!segment.isEditable ? "text-text-faint" : "text-text-bright"
)}
>
{/* Always reserve space for the placeholder, to prevent layout shift when editing. */}
<span
aria-hidden="true"
className="flex h-full items-center justify-center text-center text-charcoal-500 group-focus:text-text-bright"
className="flex h-full items-center justify-center text-center text-text-faint group-focus:text-text-bright"
style={{
visibility: segment.isPlaceholder ? undefined : "hidden",
height: segment.isPlaceholder ? undefined : 0,
@@ -275,11 +275,11 @@ function DateSegmentGuide({ segment }: { segment: DateSegment }) {
style={{
minWidth: minWidthForSegment(segment),
}}
className={`group box-content rounded-sm px-0.5 text-right text-sm tabular-nums text-rose-500 outline-none ${
!segment.isEditable ? "text-charcoal-500" : "text-text-bright"
className={`group box-content rounded-sm px-0.5 text-right text-sm tabular-nums text-rose-500 outline-hidden ${
!segment.isEditable ? "text-text-faint" : "text-text-bright"
}`}
>
<span className="block text-center italic text-charcoal-500">
<span className="block text-center italic text-text-faint">
{segment.type !== "literal" ? segment.placeholder : segment.text}
</span>
</div>
@@ -77,14 +77,14 @@ export function DateTimePicker({
return (
<div className={cn("flex items-center gap-2", className)}>
{showInlineLabel && (
<span className="w-6 shrink-0 text-right text-xxs text-charcoal-500">{label}</span>
<span className="w-6 shrink-0 text-right text-xxs text-text-faint">{label}</span>
)}
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<button
type="button"
className={cn(
"flex h-[1.8rem] w-full items-center justify-between gap-2 whitespace-nowrap rounded border border-charcoal-650 bg-charcoal-750 px-2 text-xs tabular-nums transition hover:border-charcoal-600",
"flex h-[1.8rem] w-full items-center justify-between gap-2 whitespace-nowrap rounded border border-border-bright bg-background-hover px-2 text-xs tabular-nums transition hover:border-border-bright",
value ? "text-text-bright" : "text-text-dimmed"
)}
>
@@ -107,9 +107,9 @@ export function DateTimePicker({
value={value ? timeValue : ""}
onChange={handleTimeChange}
className={cn(
"h-[1.8rem] rounded border border-charcoal-650 bg-charcoal-750 px-2 text-xs tabular-nums transition hover:border-charcoal-600",
"h-[1.8rem] rounded border border-border-bright bg-background-hover px-2 text-xs tabular-nums transition hover:border-border-bright",
value ? "text-text-bright" : "text-text-dimmed",
"focus:border-charcoal-500 focus:outline-none",
"focus:border-border-brightest focus:outline-hidden",
"[&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none"
)}
aria-label={`${label} time`}
@@ -55,7 +55,7 @@ export function DetailCell({
<div className={cn("group flex h-11 w-full items-center gap-3 rounded-md p-1 pr-3", className)}>
<IconInBox
icon={leadingIcon}
className={cn("flex-none transition group-hover:border-charcoal-750", leadingIconClassName)}
className={cn("flex-none transition group-hover:border-grid-dimmed", leadingIconClassName)}
boxClassName={boxClassName}
/>
<div className="flex flex-1 flex-col">
@@ -78,7 +78,7 @@ export function DetailCell({
<Icon
icon={trailingIcon}
className={cn(
"h-6 w-6 flex-none transition group-hover:border-charcoal-750",
"h-6 w-6 flex-none transition group-hover:border-grid-dimmed",
trailingIconClassName
)}
/>
@@ -26,7 +26,7 @@ const DialogOverlay = React.forwardRef<
<DialogPrimitive.Overlay
ref={ref}
className={cn(
"fixed inset-0 z-50 bg-background-dimmed/90 backdrop-blur-sm transition-all duration-100 data-[state=closed]:animate-out data-[state=closed]:fade-out data-[state=open]:fade-in",
"fixed inset-0 z-50 bg-background-dimmed/90 backdrop-blur-xs transition-all duration-100 data-[state=closed]:animate-out data-[state=closed]:fade-out data-[state=open]:fade-in",
className
)}
{...props}
@@ -49,7 +49,7 @@ const DialogContent = React.forwardRef<
"fixed z-50 grid gap-4 border bg-background-dimmed shadow-lg animate-in data-[state=open]:fade-in-90",
fullscreen
? "inset-6 rounded-lg pt-2.5 px-4 pb-4"
: "w-full rounded-b-lg px-4 pb-4 pt-2.5 data-[state=open]:slide-in-from-bottom-10 sm:max-w-lg sm:rounded-lg sm:zoom-in-90 data-[state=open]:sm:slide-in-from-bottom-0",
: "w-full rounded-b-lg px-4 pb-4 pt-2.5 data-[state=open]:slide-in-from-bottom-10 sm:max-w-lg sm:rounded-lg sm:zoom-in-90 sm:data-[state=open]:slide-in-from-bottom-0",
className
)}
{...props}
@@ -57,7 +57,7 @@ const DialogContent = React.forwardRef<
<hr className="absolute left-0 top-11 w-full" />
{children}
{showCloseButton && (
<DialogPrimitive.Close className="data-[state=open]:bg-accent data-[state=open]:text-muted-foreground group absolute right-2 top-[0.5625rem] flex items-center gap-1 rounded-sm p-1 py-1 pl-0 pr-1 opacity-70 transition focus-custom hover:bg-charcoal-750 hover:opacity-100 focus-visible:focus-custom disabled:pointer-events-none">
<DialogPrimitive.Close className="data-[state=open]:bg-accent data-[state=open]:text-muted-foreground group absolute right-2 top-2.25 flex items-center gap-1 rounded-sm p-1 py-1 pl-0 pr-1 opacity-70 transition focus-custom hover:bg-background-hover hover:opacity-100 focus-visible:focus-custom disabled:pointer-events-none">
<ShortcutKey
shortcut={{
key: "esc",
@@ -40,7 +40,7 @@ export function IconInBox({ boxClassName, ...props }: IconProps & { boxClassName
return (
<div
className={cn(
"grid h-9 w-9 place-content-center rounded-sm border border-charcoal-750 bg-charcoal-850",
"grid h-9 w-9 place-content-center rounded-sm border border-grid-dimmed bg-background-dimmed",
boxClassName
)}
>
+10 -10
View File
@@ -4,60 +4,60 @@ import { cn } from "~/utils/cn";
import { Icon, type RenderIcon } from "./Icon";
const containerBase =
"has-[:focus-visible]:outline-none has-[:focus-visible]:ring-1 has-[:focus-visible]:ring-charcoal-650 has-[:focus-visible]:ring-offset-0 has-[:focus]:border-ring has-[:focus]:outline-none has-[:focus]:ring-1 has-[:focus]:ring-ring has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-50 ring-offset-background transition cursor-text";
"has-focus-visible:outline-hidden has-focus-visible:ring-1 has-focus-visible:ring-border-bright has-focus-visible:ring-offset-0 has-[:focus]:border-ring has-focus:outline-hidden has-focus:ring-1 has-[:focus]:ring-ring has-disabled:cursor-not-allowed has-disabled:opacity-50 ring-offset-background transition cursor-text";
const inputBase =
"h-full w-full text-text-bright bg-transparent file:border-0 file:bg-transparent file:text-base file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-0 disabled:cursor-not-allowed outline-none ring-0 border-none [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:m-0 [&::-webkit-inner-spin-button]:m-0 [&]:[-moz-appearance:textfield]";
"h-full w-full text-text-bright bg-transparent file:border-0 file:bg-transparent file:text-base file:font-medium placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-0 disabled:cursor-not-allowed outline-hidden ring-0 border-none [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:m-0 [&::-webkit-inner-spin-button]:m-0 [&]:[-moz-appearance:textfield]";
const variants = {
large: {
container:
"px-1 w-full h-10 rounded-[3px] border border-charcoal-800 bg-charcoal-750 hover:border-charcoal-600 hover:bg-charcoal-650",
"px-1 w-full h-10 rounded-[3px] border border-background-bright bg-background-hover hover:border-border-bright hover:bg-secondary",
input: "px-2 text-sm",
iconSize: "size-4 ml-1",
accessory: "pr-1",
},
medium: {
container:
"px-1 h-8 w-full rounded border border-charcoal-800 bg-charcoal-750 hover:border-charcoal-600 hover:bg-charcoal-650",
"px-1 h-8 w-full rounded border border-background-bright bg-background-hover hover:border-border-bright hover:bg-secondary",
input: "px-1.5 rounded text-sm",
iconSize: "size-4 ml-0.5",
accessory: "pr-1",
},
small: {
container:
"px-1 h-6 w-full rounded border border-charcoal-800 bg-charcoal-750 hover:border-charcoal-600 hover:bg-charcoal-650",
"px-1 h-6 w-full rounded border border-background-bright bg-background-hover hover:border-border-bright hover:bg-secondary",
input: "px-1 rounded text-xs",
iconSize: "size-3 ml-0.5",
accessory: "pr-0.5",
},
tertiary: {
container: "px-1 h-6 w-full rounded hover:bg-charcoal-750",
container: "px-1 h-6 w-full rounded hover:bg-background-hover",
input: "px-1 rounded text-xs",
iconSize: "size-3 ml-0.5",
accessory: "pr-0.5",
},
"secondary-small": {
container:
"px-1 h-6 w-full rounded border border-charcoal-600 hover:border-charcoal-550 bg-grid-dimmed hover:bg-charcoal-650",
"px-1 h-6 w-full rounded border border-border-bright hover:border-border-brighter bg-grid-dimmed hover:bg-secondary",
input: "px-1 rounded text-xs",
iconSize: "size-3 ml-0.5",
accessory: "pr-0.5",
},
"outline/large": {
container: "px-1 h-10 w-full rounded border border-grid-bright hover:border-charcoal-550",
container: "px-1 h-10 w-full rounded border border-grid-bright hover:border-border-brighter",
input: "px-2 rounded text-sm",
iconSize: "size-4 ml-1",
accessory: "pr-1",
},
"outline/medium": {
container: "px-1 h-8 w-full rounded border border-grid-bright hover:border-charcoal-550",
container: "px-1 h-8 w-full rounded border border-grid-bright hover:border-border-brighter",
input: "px-1 rounded text-sm",
iconSize: "size-4 ml-0.5",
accessory: "pr-1",
},
"outline/small": {
container: "px-1 h-6 w-full rounded border border-grid-bright hover:border-charcoal-550",
container: "px-1 h-6 w-full rounded border border-grid-bright hover:border-border-brighter",
input: "px-1 rounded text-xs",
iconSize: "size-3 ml-0.5",
accessory: "pr-0.5",
@@ -119,7 +119,7 @@ export function InputNumberStepper({
input: "text-base px-3.5",
button: "size-8",
icon: "size-5",
gap: "gap-[0.3125rem] pr-[0.3125rem]",
gap: "gap-1.25 pr-1.25",
},
} as const;
@@ -128,9 +128,9 @@ export function InputNumberStepper({
return (
<div
className={cn(
"flex items-center rounded border border-charcoal-600 bg-tertiary transition hover:border-charcoal-550/80 hover:bg-charcoal-600/80",
"flex items-center rounded border border-border-bright bg-tertiary transition hover:border-border-brighter/80 hover:bg-surface-control/80",
size.container,
"has-[:focus-visible]:outline has-[:focus-visible]:outline-1 has-[:focus-visible]:outline-offset-0 has-[:focus-visible]:outline-text-link",
"has-focus-visible:outline-solid has-focus-visible:outline-1 has-focus-visible:outline-offset-0 has-focus-visible:outline-text-link",
disabled && "cursor-not-allowed opacity-50",
className
)}
@@ -172,10 +172,10 @@ export function InputNumberStepper({
disabled={disabled}
readOnly={readOnly}
className={cn(
"placeholder:text-muted-foreground h-full grow border-0 bg-transparent text-left text-text-bright outline-none ring-0 focus:border-0 focus:outline-none focus:ring-0 disabled:cursor-not-allowed",
"placeholder:text-muted-foreground h-full grow border-0 bg-transparent text-left text-text-bright outline-hidden ring-0 focus:border-0 focus:outline-hidden focus:ring-0 disabled:cursor-not-allowed",
size.input,
// Hide number input arrows
"[type=number]:border-0 [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
"[&[type=number]]:border-0 [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
)}
{...props}
/>
@@ -192,7 +192,7 @@ export function InputNumberStepper({
size.button,
"hover:border-error/50 hover:bg-error/30",
"disabled:cursor-not-allowed disabled:opacity-40",
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-text-link"
"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-text-link"
)}
>
<MinusIcon className={cn("text-error", size.icon)} />
@@ -209,7 +209,7 @@ export function InputNumberStepper({
size.button,
"hover:border-success/40 hover:bg-success/20",
"disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:bg-transparent",
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-text-link"
"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-text-link"
)}
>
<PlusIcon className={cn("text-success", size.icon)} />
@@ -10,17 +10,17 @@ const variants = {
default: {
container: "flex items-center gap-2 has-disabled:opacity-50",
group: "flex items-center",
slot: "data-[active=true]:border-ring data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive dark:bg-input/30 border-input relative flex size-9 items-center justify-center border-y border-r text-sm outline-none transition-all first:rounded-l-md first:border-l last:rounded-r-md data-[active=true]:z-10 data-[active=true]:ring-[3px]",
slot: "data-[active=true]:border-ring data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive dark:bg-input/30 border-input relative flex size-9 items-center justify-center border-y border-r text-sm outline-hidden transition-all first:rounded-l-md first:border-l last:rounded-r-md data-[active=true]:z-10 data-[active=true]:ring-[3px]",
},
large: {
container: "flex items-center gap-3 has-disabled:opacity-50",
group: "flex items-center gap-1",
slot: "data-[active=true]:border-ring data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive bg-charcoal-750 border-charcoal-700 hover:border-charcoal-600 hover:bg-charcoal-650 relative flex h-12 w-12 items-center justify-center border text-base outline-none transition-all rounded-md data-[active=true]:z-10 data-[active=true]:ring-[3px] data-[active=true]:border-indigo-500",
slot: "data-[active=true]:border-ring data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive bg-background-hover border-grid-bright hover:border-border-bright hover:bg-secondary relative flex h-12 w-12 items-center justify-center border text-base outline-hidden transition-all rounded-md data-[active=true]:z-10 data-[active=true]:ring-[3px] data-[active=true]:border-indigo-500",
},
minimal: {
container: "flex items-center gap-2 has-disabled:opacity-50",
group: "flex items-center",
slot: "data-[active=true]:border-ring data-[active=true]:ring-ring/50 border-transparent bg-transparent relative flex h-9 w-9 items-center justify-center border-b-2 border-b-charcoal-600 text-sm outline-none transition-all data-[active=true]:border-b-indigo-500 data-[active=true]:z-10",
slot: "data-[active=true]:border-ring data-[active=true]:ring-ring/50 border-transparent bg-transparent relative flex h-9 w-9 items-center justify-center border-b-2 border-b-border-bright text-sm outline-hidden transition-all data-[active=true]:border-b-indigo-500 data-[active=true]:z-10",
},
};
@@ -46,7 +46,7 @@ export function AnimationDivider({ isLoading }: LoadingBarDividerProps) {
{isLoading && (
<div
ref={scope}
className="width-0 absolute left-0 top-0 h-full bg-gradient-to-r from-transparent from-5% via-blue-500 to-transparent to-95%"
className="width-0 absolute left-0 top-0 h-full bg-linear-to-r from-transparent from-5% via-blue-500 to-transparent to-95%"
/>
)}
</AnimatePresence>
@@ -52,7 +52,7 @@ export function PageTitle({ title, backButton, accessory }: PageTitleProps) {
<div className="group -ml-1.5 flex items-center gap-0">
<Link
to={backButton.to}
className="rounded px-1.5 py-1 text-xs text-text-dimmed transition focus-custom group-hover:bg-charcoal-700 group-hover:text-text-bright"
className="rounded px-1.5 py-1 text-xs text-text-dimmed transition focus-custom group-hover:bg-background-raised group-hover:text-text-bright"
>
{backButton.text}
</Link>
@@ -65,7 +65,7 @@ export function PaginationControls({
tooltip="Previous"
disabled={currentPage === 1}
className={cn(
"flex items-center rounded-r-none border-r-0 pl-2 pr-[0.5625rem]",
"flex items-center rounded-r-none border-r-0 pl-2 pr-2.25",
currentPage === 1 && "cursor-not-allowed opacity-50"
)}
/>
@@ -73,7 +73,7 @@ export function PaginationControls({
<div
className={cn(
"order-2 h-6 w-px bg-charcoal-600 transition-colors peer-hover/next:bg-charcoal-550 peer-hover/prev:bg-charcoal-550",
"order-2 h-6 w-px bg-surface-control transition-colors peer-hover/next:bg-surface-control-hover peer-hover/prev:bg-surface-control-hover",
currentPage === 1 && nextDisabled && "opacity-30"
)}
/>
@@ -87,7 +87,7 @@ export function PaginationControls({
tooltip="Next"
disabled={nextDisabled}
className={cn(
"flex items-center rounded-l-none border-l-0 pl-[0.5625rem] pr-2",
"flex items-center rounded-l-none border-l-0 pl-2.25 pr-2",
nextDisabled && "cursor-not-allowed opacity-50"
)}
/>
@@ -109,7 +109,8 @@ function pageUrl(location: ReturnType<typeof useLocation>, page: number): string
const baseClass =
"flex items-center justify-center border border-transparent min-w-6 h-6 px-1 text-xs font-medium transition text-text-dimmed rounded-sm focus-visible:focus-custom";
const unselectedClass = "hover:bg-tertiary hover:text-text-bright";
const selectedClass = "border-charcoal-600 bg-tertiary text-text-bright hover:bg-charcoal-600/50";
const selectedClass =
"border-border-bright bg-tertiary text-text-bright hover:bg-surface-control/50";
function PageLinkComponent({
page,
@@ -27,7 +27,7 @@ const PopoverContent = React.forwardRef<
sideOffset={sideOffset}
avoidCollisions={true}
className={cn(
"z-50 min-w-max rounded border border-charcoal-700 bg-background-bright p-4 shadow-md outline-none animate-in data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
"z-50 min-w-max rounded border border-grid-bright bg-background-bright p-4 shadow-md outline-hidden animate-in data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className
)}
style={{
@@ -47,7 +47,7 @@ function PopoverSectionHeader({
variant?: ParagraphVariant;
}) {
return (
<Paragraph variant={variant} className="bg-charcoal-750 px-2.5 py-1.5">
<Paragraph variant={variant} className="bg-background-hover px-2.5 py-1.5">
{title}
</Paragraph>
);
@@ -102,9 +102,9 @@ const PopoverMenuItem = React.forwardRef<
TrailingIcon: isSelected ? CheckIcon : undefined,
className: cn(
danger
? "transition-colors group-hover/button:bg-error/10 group-hover/button:text-error [&_span]:transition-colors [&_span]:group-hover/button:text-error"
: "group-hover:bg-charcoal-700",
isSelected ? "bg-charcoal-750 group-hover:bg-charcoal-600/50" : undefined,
? "transition-colors group-hover/button:bg-error/10 group-hover/button:text-error [&_span]:transition-colors group-hover/button:[&_span]:text-error"
: "group-hover:bg-background-raised",
isSelected ? "bg-background-hover group-hover:bg-surface-control/50" : undefined,
className
),
} as const;
@@ -130,7 +130,7 @@ const PopoverMenuItem = React.forwardRef<
onClick={onClick}
disabled={disabled}
className={cn(
"group/button outline-none focus-custom",
"group/button outline-hidden focus-custom",
contentProps.fullWidth ? "w-full" : ""
)}
name={name}
@@ -154,7 +154,7 @@ function PopoverCustomTrigger({
<PopoverTrigger
{...props}
className={cn(
"group flex items-center justify-end gap-1 rounded text-text-dimmed transition focus-custom hover:bg-charcoal-850 hover:text-text-bright",
"group flex items-center justify-end gap-1 rounded text-text-dimmed transition focus-custom hover:bg-background-dimmed hover:text-text-bright",
className
)}
>
@@ -192,7 +192,7 @@ function PopoverSideMenuTrigger({
{...props}
ref={ref}
className={cn(
"flex h-[1.8rem] shrink-0 select-none items-center rounded-sm bg-transparent pl-[0.4rem] pr-2.5 text-center font-sans text-2sm font-normal text-text-bright transition duration-150 focus-custom hover:bg-charcoal-750",
"flex h-[1.8rem] shrink-0 select-none items-center rounded-sm bg-transparent pl-[0.4rem] pr-2.5 text-center font-sans text-2sm font-normal text-text-bright transition duration-150 focus-custom hover:bg-background-hover",
shortcut && !hideShortcutKey ? "justify-between gap-x-1.5" : "",
className
)}
@@ -207,7 +207,7 @@ function PopoverSideMenuTrigger({
const popoverArrowTriggerVariants = {
minimal: {
trigger: "text-text-dimmed hover:bg-charcoal-700 hover:text-text-bright",
trigger: "text-text-dimmed hover:bg-background-raised hover:text-text-bright",
text: "group-hover:text-text-bright",
icon: "text-text-dimmed group-hover:text-text-bright",
},
@@ -219,12 +219,12 @@ const popoverArrowTriggerVariants = {
},
secondary: {
trigger:
"bg-secondary border border-charcoal-600 text-text-bright hover:bg-charcoal-600 hover:border-charcoal-550 disabled:opacity-60 disabled:pointer-events-none",
"bg-secondary border border-border-bright text-text-bright hover:bg-surface-control hover:border-border-brighter disabled:opacity-60 disabled:pointer-events-none",
text: "text-text-bright",
icon: "text-text-bright",
},
tertiary: {
trigger: "bg-tertiary text-text-bright hover:bg-charcoal-600",
trigger: "bg-tertiary text-text-bright hover:bg-surface-control",
text: "text-text-bright",
icon: "text-text-bright",
},
@@ -276,7 +276,7 @@ const popoverVerticalEllipseVariants = {
},
secondary: {
trigger:
"size-6 rounded border border-charcoal-600 bg-secondary text-text-bright hover:bg-charcoal-600 hover:border-charcoal-550",
"size-6 rounded border border-border-bright bg-secondary text-text-bright hover:bg-surface-control hover:border-border-brighter",
icon: "size-4",
},
} as const;
@@ -7,14 +7,14 @@ import { Paragraph } from "./Paragraph";
const variants = {
"simple/small": {
button: "w-fit pr-4 data-[disabled]:opacity-70",
button: "w-fit pr-4 data-disabled:opacity-70",
label: "text-sm text-text-bright mt-0.5 select-none",
description: "text-text-dimmed",
inputPosition: "mt-1",
icon: "w-8 h-8 mb-2",
},
simple: {
button: "w-fit pr-4 data-[disabled]:opacity-70",
button: "w-fit pr-4 data-disabled:opacity-70",
label: "text-text-bright select-none",
description: "text-text-dimmed",
inputPosition: "mt-1",
@@ -22,7 +22,7 @@ const variants = {
},
"button/small": {
button:
"flex items-center w-fit h-8 pl-2 pr-3 rounded-md border hover:data-[state=checked]:border-charcoal-600 border-charcoal-650 hover:border-charcoal-600 transition data-[disabled]:opacity-70 data-[disabled]:hover:bg-transparent hover:data-[state=checked]:bg-white/[4%] data-[state=checked]:bg-white/[4%]",
"flex items-center w-fit h-8 pl-2 pr-3 rounded-md border hover:data-[state=checked]:border-border-bright border-border-bright hover:border-border-bright transition data-disabled:opacity-70 data-disabled:hover:bg-transparent hover:data-[state=checked]:bg-white/4 data-[state=checked]:bg-white/4",
label: "text-sm text-text-bright select-none",
description: "text-text-dimmed",
inputPosition: "mt-0",
@@ -30,7 +30,7 @@ const variants = {
},
button: {
button:
"w-fit py-2 pl-3 pr-4 rounded border border-charcoal-600 hover:bg-charcoal-850 hover:border-charcoal-500 transition data-[state=checked]:bg-charcoal-850 data-[disabled]:opacity-70",
"w-fit py-2 pl-3 pr-4 rounded border border-border-bright hover:bg-background-dimmed hover:border-border-brightest transition data-[state=checked]:bg-background-dimmed data-disabled:opacity-70",
label: "text-text-bright select-none",
description: "text-text-dimmed",
inputPosition: "mt-1",
@@ -38,17 +38,17 @@ const variants = {
},
description: {
button:
"w-full p-2.5 hover:data-[state=checked]:bg-white/[4%] data-[state=checked]:bg-white/[4%] transition data-[disabled]:opacity-70 hover:border-charcoal-600 border-charcoal-650 hover:data-[state=checked]:border-charcoal-600 border rounded-md",
"w-full p-2.5 hover:data-[state=checked]:bg-white/4 data-[state=checked]:bg-white/4 transition data-disabled:opacity-70 hover:border-border-bright border-border-bright hover:data-[state=checked]:border-border-bright border rounded-md",
label: "text-text-bright font-semibold -mt-0.5 text-left text-sm",
description: "text-text-dimmed -mt-0 text-left",
description: "text-text-dimmed mt-0 text-left",
inputPosition: "mt-0",
icon: "w-8 h-8 mb-2",
},
icon: {
button:
"w-full p-2.5 pb-4 hover:bg-charcoal-850 transition data-[disabled]:opacity-70 data-[state=checked]:bg-charcoal-850 border-charcoal-600 border rounded-sm",
"w-full p-2.5 pb-4 hover:bg-background-dimmed transition data-disabled:opacity-70 data-[state=checked]:bg-background-dimmed border-border-bright border rounded-sm",
label: "text-text-bright font-semibold -mt-1 text-left",
description: "text-text-dimmed -mt-0 text-left",
description: "text-text-dimmed mt-0 text-left",
inputPosition: "mt-0",
icon: "mb-3",
},
@@ -70,7 +70,7 @@ export function RadioButtonCircle({
return (
<div
className={cn(
"ring-offset-background aspect-square h-4 w-4 shrink-0 overflow-hidden rounded-full border border-charcoal-600 bg-charcoal-700 focus-custom disabled:cursor-not-allowed disabled:opacity-50",
"ring-offset-background aspect-square h-4 w-4 shrink-0 overflow-hidden rounded-full border border-border-bright bg-background-raised focus-custom disabled:cursor-not-allowed disabled:opacity-50",
boxClassName
)}
>
@@ -131,7 +131,7 @@ export const RadioGroupItem = React.forwardRef<
>
<div
className={cn(
"ring-offset-background focus-visible:ring-ring aspect-square h-4 w-4 shrink-0 overflow-hidden rounded-full border border-charcoal-600 focus-custom group-data-[state=checked]:border-indigo-500 disabled:cursor-not-allowed disabled:opacity-50",
"ring-offset-background focus-visible:ring-ring aspect-square h-4 w-4 shrink-0 overflow-hidden rounded-full border border-border-bright focus-custom group-data-[state=checked]:border-indigo-500 disabled:cursor-not-allowed disabled:opacity-50",
variation.inputPosition
)}
>
@@ -53,15 +53,15 @@ const ResizableHandle = ({
{withHandle && (
<>
{/* Horizontal orientation dots (vertical arrangement) */}
<div className="relative z-[1] flex h-5 w-0.75 flex-col items-center justify-center gap-[0.1875rem] bg-background-dimmed transition-opacity group-hover:opacity-0 group-data-[handle-orientation=vertical]:hidden">
<div className="relative z-1 flex h-5 w-0.75 flex-col items-center justify-center gap-0.75 bg-background-dimmed transition-opacity group-hover:opacity-0 group-data-[handle-orientation=vertical]:hidden">
{Array.from({ length: 3 }).map((_, index) => (
<div key={index} className="h-[0.1875rem] w-0.75 rounded-full bg-charcoal-600" />
<div key={index} className="h-[0.1875rem] w-0.75 rounded-full bg-surface-control" />
))}
</div>
{/* Vertical orientation dots (horizontal arrangement) */}
<div className="relative z-[1] hidden h-0.75 w-5 flex-row items-center justify-center gap-[0.1875rem] bg-background-dimmed transition-opacity group-hover:opacity-0 group-data-[handle-orientation=vertical]:flex">
<div className="relative z-1 hidden h-0.75 w-5 flex-row items-center justify-center gap-0.75 bg-background-dimmed transition-opacity group-hover:opacity-0 group-data-[handle-orientation=vertical]:flex">
{Array.from({ length: 3 }).map((_, index) => (
<div key={index} className="h-0.75 w-[0.1875rem] rounded-full bg-charcoal-600" />
<div key={index} className="h-0.75 w-[0.1875rem] rounded-full bg-surface-control" />
))}
</div>
</>
@@ -154,7 +154,7 @@ export function SearchInput({
type="button"
onMouseDown={(e) => e.preventDefault()}
onClick={() => handleClear()}
className="flex size-4.5 items-center justify-center rounded-[2px] border border-text-dimmed/40 text-text-dimmed transition hover:bg-charcoal-600 hover:text-text-bright"
className="flex size-4.5 items-center justify-center rounded-[2px] border border-text-dimmed/40 text-text-dimmed transition hover:bg-surface-control hover:text-text-bright"
>
<XMarkIcon className="size-3" />
</button>
@@ -18,16 +18,16 @@ const sizes = {
const theme = {
primary: {
base: "bg-charcoal-700",
active: "text-text-bright hover:bg-charcoal-750/50",
base: "bg-background-raised",
active: "text-text-bright hover:bg-background-hover/50",
inactive: "text-text-dimmed transition hover:text-text-bright",
selected: "absolute inset-0 rounded-[2px] outline outline-3 outline-primary",
selected: "absolute inset-0 rounded-[2px] outline-solid outline-3 outline-primary",
},
secondary: {
base: "bg-charcoal-700/50",
base: "bg-background-raised/50",
active: "text-text-bright",
inactive: "text-text-dimmed transition hover:text-text-bright",
selected: "absolute inset-0 rounded bg-charcoal-700 border border-charcoal-600",
selected: "absolute inset-0 rounded bg-background-raised border border-border-bright",
},
};
@@ -22,7 +22,7 @@ const sizes = {
const style = {
tertiary: {
button:
"bg-tertiary focus-custom border border-tertiary hover:text-text-bright hover:border-charcoal-600",
"bg-tertiary focus-custom border border-tertiary hover:text-text-bright hover:border-border-bright",
},
minimal: {
button:
@@ -30,7 +30,7 @@ const style = {
},
secondary: {
button:
"bg-secondary focus-custom border border-charcoal-600 hover:text-text-bright hover:border-charcoal-550 text-text-bright hover:bg-charcoal-600",
"bg-secondary focus-custom border border-border-bright hover:text-text-bright hover:border-border-brighter text-text-bright hover:bg-surface-control",
},
};
@@ -358,7 +358,7 @@ export function SelectTrigger({
{showTooltip && (
<Ariakit.Tooltip
disabled={!tooltipTitle && !shortcut}
className="z-40 cursor-default rounded border border-charcoal-700 bg-background-bright px-2 py-1.5 text-xs"
className="z-40 cursor-default rounded border border-grid-bright bg-background-bright px-2 py-1.5 text-xs"
>
<div className="flex items-center gap-2">
<span>{tooltipTitle ?? "Open menu"}</span>
@@ -437,7 +437,7 @@ export function SelectList(props: SelectListProps) {
<Component
{...props}
className={cn(
"overflow-y-auto overscroll-contain scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600 focus-custom",
"overflow-y-auto overscroll-contain scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control focus-custom",
props.className
)}
/>
@@ -518,7 +518,9 @@ export function SelectItem({
{checkPosition === "right" && checkIcon}
{shortcut && (
<ShortcutKey
className={cn("size-4 flex-none transition duration-0 group-hover:border-charcoal-600")}
className={cn(
"size-4 flex-none transition duration-0 group-hover:border-border-bright"
)}
shortcut={shortcut}
variant={"small"}
/>
@@ -603,7 +605,7 @@ export function shortcutFromIndex(
export interface SelectSeparatorProps extends React.ComponentProps<"div"> {}
export function SelectSeparator(props: SelectSeparatorProps) {
return <div {...props} className={cn("h-px bg-charcoal-700", props.className)} />;
return <div {...props} className={cn("h-px bg-background-raised", props.className)} />;
}
export interface SelectGroupProps extends Ariakit.SelectGroupProps {}
@@ -619,7 +621,7 @@ export function SelectGroupLabel(props: SelectGroupLabelProps) {
<Ariakit.SelectGroupLabel
{...props}
className={cn(
"flex h-[1.375rem] items-center border-b border-charcoal-700 bg-charcoal-750 px-2.5 text-xxs uppercase text-text-bright",
"flex h-5.5 items-center border-b border-grid-bright bg-background-hover px-2.5 text-xxs uppercase text-text-bright",
props.className
)}
/>
@@ -629,7 +631,7 @@ export function SelectGroupLabel(props: SelectGroupLabelProps) {
export interface SelectHeadingProps extends Ariakit.SelectHeadingProps {}
export function SelectHeading({ render, ...props }: SelectHeadingProps) {
return (
<div className="flex h-[1.375rem] flex-none cursor-default items-center gap-2 border-b border-charcoal-700 bg-charcoal-750 px-2.5 text-xxs uppercase text-text-bright">
<div className="flex h-5.5 flex-none cursor-default items-center gap-2 border-b border-grid-bright bg-background-hover px-2.5 text-xxs uppercase text-text-bright">
<Ariakit.SelectHeading render={render} />
</div>
);
@@ -649,11 +651,11 @@ export function SelectPopover({
shift={shift}
unmountOnHide={unmountOnHide}
className={cn(
"z-50 flex flex-col overflow-clip rounded border border-charcoal-700 bg-background-bright shadow-md outline-none animate-in fade-in-40",
"z-50 flex flex-col overflow-clip rounded border border-grid-bright bg-background-bright shadow-md outline-hidden animate-in fade-in-40",
"min-w-[max(180px,var(--popover-anchor-width))]",
"max-w-[min(480px,var(--popover-available-width))]",
"max-h-[min(600px,var(--popover-available-height))]",
"origin-[var(--popover-transform-origin)]",
"origin-(--popover-transform-origin)",
className
)}
{...props}
@@ -678,11 +680,11 @@ export function ComboBox({
...props
}: ComboBoxProps) {
return (
<div className="flex h-9 w-full flex-none items-center border-b border-grid-dimmed bg-transparent px-3 text-xs text-text-dimmed outline-none">
<div className="flex h-9 w-full flex-none items-center border-b border-grid-dimmed bg-transparent px-3 text-xs text-text-dimmed outline-hidden">
<Ariakit.Combobox
autoSelect={autoSelect}
render={<input placeholder={placeholder} />}
className="flex-1 bg-transparent text-xs text-text-dimmed outline-none"
className="flex-1 bg-transparent text-xs text-text-dimmed outline-hidden"
{...props}
/>
{shortcut && (
@@ -155,7 +155,7 @@ const SheetContent = React.forwardRef<
>
<div className="grid max-h-full grid-rows-[2.75rem_1fr] overflow-hidden">
<div className="flex items-center gap-2 border-b border-grid-bright p-2">
<SheetPrimitive.Close className="rounded-sm p-1 transition hover:bg-charcoal-800 disabled:pointer-events-none">
<SheetPrimitive.Close className="rounded-sm p-1 transition hover:bg-background-bright disabled:pointer-events-none">
<XMarkIcon className="size-4 text-text-dimmed" />
<span className="sr-only">Close</span>
</SheetPrimitive.Close>
@@ -171,7 +171,7 @@ SheetContent.displayName = SheetPrimitive.Content.displayName;
export const SheetBody = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"overflow-y-auto p-4 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600",
"overflow-y-auto p-4 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control",
className
)}
{...props}
@@ -91,7 +91,7 @@ const SheetTitle = React.forwardRef<
{...props}
>
{children}
<SheetPrimitive.Close className="flex items-center gap-1 rounded-sm p-1 pl-0 transition hover:bg-charcoal-750 focus-visible:focus-custom disabled:pointer-events-none">
<SheetPrimitive.Close className="flex items-center gap-1 rounded-sm p-1 pl-0 transition hover:bg-background-hover focus-visible:focus-custom disabled:pointer-events-none">
<ShortcutKey shortcut={{ key: "esc" }} variant="small" />
<XMarkIcon className="size-4 text-text-dimmed" />
<span className="sr-only">Close</span>
@@ -9,19 +9,19 @@ import { useOperatingSystem } from "./OperatingSystemProvider";
import { KeyboardEnterIcon } from "~/assets/icons/KeyboardEnterIcon";
const small =
"justify-center text-[0.6rem] font-mono font-medium min-w-[1rem] min-h-[1rem] rounded-[2px] tabular-nums px-1 ml-1 -mr-0.5 flex items-center gap-x-1 border transition uppercase";
"justify-center text-[0.6rem] font-mono font-medium min-w-4 min-h-4 rounded-[2px] tabular-nums px-1 ml-1 -mr-0.5 flex items-center gap-x-1 border transition uppercase";
const medium =
"justify-center min-w-[1.25rem] min-h-[1.25rem] text-[0.65rem] font-mono font-medium rounded-[2px] tabular-nums px-1 ml-1 -mr-0.5 flex items-center gap-x-1.5 border border-dimmed/40 text-text-dimmed group-hover:text-text-bright/80 group-hover:border-dimmed/60 transition uppercase";
"justify-center min-w-5 min-h-5 text-[0.65rem] font-mono font-medium rounded-[2px] tabular-nums px-1 ml-1 -mr-0.5 flex items-center gap-x-1.5 border border-dimmed/40 text-text-dimmed group-hover:text-text-bright/80 group-hover:border-dimmed/60 transition uppercase";
export const variants = {
small: cn(
small,
"border-text-dimmed/40 text-text-dimmed group-hover:text-text-bright/80 group-hover:border-text-dimmed/60"
),
"small/bright": cn(small, "bg-charcoal-750 text-text-bright border-charcoal-650"),
medium: cn(medium, "group-hover:border-charcoal-550"),
"medium/bright": cn(medium, "bg-charcoal-750 text-text-bright border-charcoal-650"),
"small/bright": cn(small, "bg-background-hover text-text-bright border-border-bright"),
medium: cn(medium, "group-hover:border-border-brighter"),
"medium/bright": cn(medium, "bg-background-hover text-text-bright border-border-bright"),
};
export type ShortcutKeyVariant = keyof typeof variants;
@@ -7,8 +7,8 @@ import { cn } from "~/utils/cn";
const sizes = {
"secondary/small":
"text-xs h-6 bg-tertiary border border-tertiary group-hover:text-text-bright hover:border-charcoal-600 pr-2 pl-1.5",
medium: "text-sm h-8 bg-tertiary border border-tertiary hover:border-charcoal-600 px-2.5",
"text-xs h-6 bg-tertiary border border-tertiary group-hover:text-text-bright hover:border-border-bright pr-2 pl-1.5",
medium: "text-sm h-8 bg-tertiary border border-tertiary hover:border-border-bright px-2.5",
minimal: "text-xs h-6 bg-transparent hover:bg-tertiary pl-1.5 pr-2",
};
@@ -57,7 +57,7 @@ const SelectContent = React.forwardRef<
<SelectPrimitive.Content
ref={ref}
className={cn(
"relative z-50 min-w-max overflow-hidden rounded-md border border-charcoal-700 bg-background-dimmed text-text-bright shadow-md animate-in fade-in-40",
"relative z-50 min-w-max overflow-hidden rounded-md border border-grid-bright bg-background-dimmed text-text-bright shadow-md animate-in fade-in-40",
position === "popper" && "translate-y-1",
className
)}
@@ -68,7 +68,7 @@ const SelectContent = React.forwardRef<
className={cn(
"space-y-0.5 px-1 py-1",
position === "popper" &&
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
"h-(--radix-select-trigger-height) w-full min-w-(--radix-select-trigger-width)"
)}
>
{children}
@@ -85,7 +85,7 @@ const SelectLabel = React.forwardRef<
<SelectPrimitive.Label
ref={ref}
className={cn(
"-ml-1 -mr-1 mb-1 bg-charcoal-900 py-1.5 pl-2 pr-2 font-sans text-xxs font-normal uppercase leading-normal tracking-wider text-text-dimmed first-of-type:-mt-0",
"-ml-1 -mr-1 mb-1 bg-background-deep py-1.5 pl-2 pr-2 font-sans text-xxs font-normal uppercase leading-normal tracking-wider text-text-dimmed first-of-type:mt-0",
className
)}
{...props}
@@ -102,7 +102,7 @@ const SelectItem = React.forwardRef<React.ElementRef<typeof SelectPrimitive.Item
<SelectPrimitive.Item
ref={ref}
className={cn(
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-12 text-sm outline-none transition data-[disabled]:pointer-events-none data-[disabled]:opacity-50 hover:bg-charcoal-750 focus:bg-charcoal-750/50",
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-12 text-sm outline-hidden transition data-disabled:pointer-events-none data-disabled:opacity-50 hover:bg-background-hover focus:bg-background-hover/50",
className
)}
{...props}
@@ -6,13 +6,13 @@ import { Icon } from "./Icon";
const variants = {
tertiary: {
container: "h-6 gap-1 rounded-sm hover:bg-charcoal-700 px-1",
container: "h-6 gap-1 rounded-sm hover:bg-background-raised px-1",
icons: "h-4 w-4 text-text-bright",
root: "h-4",
track: "h-1 bg-grid-bright group-hover:bg-background-dimmed",
range: "bg-transparent group-hover:bg-secondary",
thumb:
"h-3 w-3 border-2 border-text-dimmed bg-grid-bright shadow-[0_1px_3px_4px_rgb(0_0_0_/_0.2),_0_1px_2px_-1px_rgb(0_0_0_/_0.1)] hover:border-text-dimmed focus:shadow-[0_1px_3px_4px_rgb(0_0_0_/_0.2),_0_1px_2px_-1px_rgb(0_0_0_/_0.1)]",
"h-3 w-3 border-2 border-text-dimmed bg-grid-bright shadow-[0_1px_3px_4px_rgb(0_0_0/0.2),0_1px_2px_-1px_rgb(0_0_0/0.1)] hover:border-text-dimmed focus:shadow-[0_1px_3px_4px_rgb(0_0_0/0.2),0_1px_2px_-1px_rgb(0_0_0/0.1)]",
},
};
@@ -42,7 +42,7 @@ export function Slider({ variant, className, LeadingIcon, TrailingIcon, ...props
</RadixSlider.Track>
<RadixSlider.Thumb
className={cn(
"block cursor-pointer rounded-full transition focus:outline-none",
"block cursor-pointer rounded-full transition focus:outline-hidden",
variation.thumb
)}
/>
@@ -29,7 +29,7 @@ export function StepNumber({
</div>
) : (
<div className="flex items-center gap-x-3">
<span className="flex h-6 w-6 items-center justify-center rounded border border-charcoal-700 bg-charcoal-800 py-1 text-xs font-semibold text-text-dimmed">
<span className="flex h-6 w-6 items-center justify-center rounded border border-grid-bright bg-background-bright py-1 text-xs font-semibold text-text-dimmed">
{complete ? <CheckIcon className="size-4" /> : stepNumber}
</span>
@@ -7,7 +7,7 @@ import { type ShortcutDefinition, useShortcutKeys } from "~/hooks/useShortcutKey
const small = {
container:
"flex items-center h-[1.5rem] gap-x-1.5 rounded hover:bg-tertiary pr-1 py-[0.1rem] pl-1.5 hover:disabled:bg-charcoal-700 transition focus-custom disabled:opacity-50 text-text-dimmed hover:text-text-bright disabled:hover:cursor-not-allowed hover:cursor-pointer disabled:hover:text-rose-500",
"flex items-center h-6 gap-x-1.5 rounded hover:bg-tertiary pr-1 py-[0.1rem] pl-1.5 hover:disabled:bg-background-raised transition focus-custom disabled:opacity-50 text-text-dimmed hover:text-text-bright disabled:hover:cursor-not-allowed hover:cursor-pointer disabled:hover:text-rose-500",
root: "h-3 w-6",
thumb: "size-2.5 data-[state=checked]:translate-x-2.5 data-[state=unchecked]:translate-x-0",
text: "text-xs text-text-dimmed",
@@ -25,25 +25,25 @@ const variations = {
container: small.container,
root: cn(
small.root,
"group-data-[state=unchecked]:bg-charcoal-600 group-data-[state=unchecked]:group-hover:bg-charcoal-500/50"
"group-data-[state=unchecked]:bg-surface-control group-hover:group-data-[state=unchecked]:bg-surface-control-active/50"
),
thumb: small.thumb,
text: cn(
small.text,
"transition group-hover:text-text-bright group-disabled:group-hover:text-text-dimmed"
"transition group-hover:text-text-bright group-hover:group-disabled:text-text-dimmed"
),
},
"secondary/small": {
container: cn(
small.container,
"border border-charcoal-600 hover:border-charcoal-550 bg-secondary hover:bg-charcoal-600"
"border border-border-bright hover:border-border-brighter bg-secondary hover:bg-surface-control"
),
root: cn(
small.root,
"group-data-[state=unchecked]:bg-charcoal-550 group-data-[state=unchecked]:group-hover:bg-charcoal-500"
"group-data-[state=unchecked]:bg-surface-control-hover group-hover:group-data-[state=unchecked]:bg-surface-control-active"
),
thumb: small.thumb,
text: cn(small.text, "transition text-text-bright group-disabled:group-hover:text-text-dimmed"),
text: cn(small.text, "transition text-text-bright group-hover:group-disabled:text-text-dimmed"),
},
medium: {
container:
@@ -91,7 +91,7 @@ export const Switch = React.forwardRef<React.ElementRef<typeof SwitchPrimitives.
const switchElement = (
<div
className={cn(
"inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors group-disabled:cursor-not-allowed group-disabled:opacity-50 group-data-[state=checked]:bg-blue-500 group-data-[state=unchecked]:bg-charcoal-700 group-data-[state=unchecked]:group-hover:bg-charcoal-500/50",
"inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors group-disabled:cursor-not-allowed group-disabled:opacity-50 group-data-[state=checked]:bg-blue-500 group-data-[state=unchecked]:bg-background-raised group-hover:group-data-[state=unchecked]:bg-surface-control-active/50",
root
)}
>
+25 -25
View File
@@ -11,14 +11,14 @@ const variants = {
bright: {
header: "bg-background-bright",
headerCell: "px-3 py-2.5 pb-3 text-sm",
cell: "group-hover/table-row:bg-charcoal-750 group-has-[[tabindex='0']:focus]/table-row:bg-charcoal-750",
cell: "group-hover/table-row:bg-background-hover group-has-[[tabindex='0']:focus]/table-row:bg-background-hover",
cellSize: "px-3 py-3",
cellText: "text-xs group-hover/table-row:text-text-bright",
stickyCell: "bg-background-bright group-hover/table-row:bg-charcoal-750",
stickyCell: "bg-background-bright group-hover/table-row:bg-background-hover",
menuButton:
"bg-background-bright group-hover/table-row:bg-charcoal-750 group-hover/table-row:ring-charcoal-600/70 group-has-[[tabindex='0']:focus]/table-row:bg-charcoal-750",
menuButtonDivider: "group-hover/table-row:border-charcoal-600/70",
rowSelected: "bg-charcoal-750 group-hover/table-row:bg-charcoal-750",
"bg-background-bright group-hover/table-row:bg-background-hover group-hover/table-row:ring-border-bright/70 group-has-[[tabindex='0']:focus]/table-row:bg-background-hover",
menuButtonDivider: "group-hover/table-row:border-border-bright/70",
rowSelected: "bg-background-hover group-hover/table-row:bg-background-hover",
},
"bright/no-hover": {
header: "bg-transparent",
@@ -29,31 +29,31 @@ const variants = {
stickyCell: "bg-background-bright",
menuButton: "bg-background-bright",
menuButtonDivider: "",
rowSelected: "bg-charcoal-750",
rowSelected: "bg-background-hover",
},
dimmed: {
header: "bg-background-dimmed",
headerCell: "px-3 py-2.5 pb-3 text-sm",
cell: "group-hover/table-row:bg-charcoal-800 group-has-[[tabindex='0']:focus]/table-row:bg-background-bright",
cell: "group-hover/table-row:bg-background-bright group-has-[[tabindex='0']:focus]/table-row:bg-background-bright",
cellSize: "px-3 py-3",
cellText: "text-xs group-hover/table-row:text-text-bright",
stickyCell: "group-hover/table-row:bg-charcoal-800",
stickyCell: "group-hover/table-row:bg-background-bright",
menuButton:
"bg-background-dimmed group-hover/table-row:bg-charcoal-800 group-hover/table-row:ring-grid-bright group-has-[[tabindex='0']:focus]/table-row:bg-background-bright",
"bg-background-dimmed group-hover/table-row:bg-background-bright group-hover/table-row:ring-grid-bright group-has-[[tabindex='0']:focus]/table-row:bg-background-bright",
menuButtonDivider: "group-hover/table-row:border-grid-bright",
rowSelected: "bg-charcoal-750 group-hover/table-row:bg-charcoal-750",
rowSelected: "bg-background-hover group-hover/table-row:bg-background-hover",
},
"compact/mono": {
header: "bg-background-dimmed",
headerCell: "px-2 py-1.5 text-sm",
cell: "group-hover/table-row:bg-charcoal-800 group-has-[[tabindex='0']:focus]/table-row:bg-background-bright",
cell: "group-hover/table-row:bg-background-bright group-has-[[tabindex='0']:focus]/table-row:bg-background-bright",
cellSize: "px-2 py-1.5",
cellText: "text-xs font-mono group-hover/table-row:text-text-bright",
stickyCell: "group-hover/table-row:bg-charcoal-800",
stickyCell: "group-hover/table-row:bg-background-bright",
menuButton:
"bg-background-dimmed group-hover/table-row:bg-charcoal-800 group-hover/table-row:ring-grid-bright group-has-[[tabindex='0']:focus]/table-row:bg-background-bright",
"bg-background-dimmed group-hover/table-row:bg-background-bright group-hover/table-row:ring-grid-bright group-has-[[tabindex='0']:focus]/table-row:bg-background-bright",
menuButtonDivider: "group-hover/table-row:border-grid-bright",
rowSelected: "bg-charcoal-750 group-hover/table-row:bg-charcoal-750",
rowSelected: "bg-background-hover group-hover/table-row:bg-background-hover",
},
} as const;
@@ -88,7 +88,7 @@ export const Table = forwardRef<HTMLTableElement, TableProps & { variant?: Table
<TableContext.Provider value={{ variant }}>
<div
className={cn(
"whitespace-nowrap scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600",
"whitespace-nowrap scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control",
stickyHeader ? "overflow-visible" : "overflow-x-auto",
showTopBorder && "border-t",
containerClassName,
@@ -158,7 +158,7 @@ export const TableRow = forwardRef<HTMLTableRowElement, TableRowProps>(
ref={ref}
{...props}
className={cn(
"group/table-row relative w-full outline-none after:absolute after:bottom-0 after:left-3 after:right-0 after:h-px after:bg-grid-dimmed",
"group/table-row relative w-full outline-hidden after:absolute after:bottom-0 after:left-3 after:right-0 after:h-px after:bg-grid-dimmed",
isSelected && variants[variant].rowSelected,
disabled && "opacity-50",
className
@@ -306,19 +306,18 @@ export const TableCell = forwardRef<HTMLTableCellElement, TableCellProps>(
<td
ref={ref}
className={cn(
"safari-only text-xs text-charcoal-400 has-[[tabindex='0']:focus]:before:absolute has-[[tabindex='0']:focus]:before:-top-px has-[[tabindex='0']:focus]:before:left-0 has-[[tabindex='0']:focus]:before:h-px has-[[tabindex='0']:focus]:before:w-3 has-[[tabindex='0']:focus]:before:bg-grid-dimmed has-[[tabindex='0']:focus]:after:absolute has-[[tabindex='0']:focus]:after:bottom-0 has-[[tabindex='0']:focus]:after:left-0 has-[[tabindex='0']:focus]:after:right-0 has-[[tabindex='0']:focus]:after:h-px has-[[tabindex='0']:focus]:after:bg-grid-dimmed",
"safari-only text-xs text-text-dimmed has-[[tabindex='0']:focus]:before:absolute has-[[tabindex='0']:focus]:before:-top-px has-[[tabindex='0']:focus]:before:left-0 has-[[tabindex='0']:focus]:before:h-px has-[[tabindex='0']:focus]:before:w-3 has-[[tabindex='0']:focus]:before:bg-grid-dimmed has-[[tabindex='0']:focus]:after:absolute has-[[tabindex='0']:focus]:after:bottom-0 has-[[tabindex='0']:focus]:after:left-0 has-[[tabindex='0']:focus]:after:right-0 has-[[tabindex='0']:focus]:after:h-px has-[[tabindex='0']:focus]:after:bg-grid-dimmed",
variants[variant].cellText,
variants[variant].cell,
to || onClick || hasAction
? "cursor-pointer"
: cn("cursor-default align-middle", variants[variant].cellSize),
!to && !onClick && alignmentClassName,
isSticky &&
"[&:has(.group-hover/table-row:block)]:w-auto sticky right-0 bg-background-dimmed",
isSticky && "[&:has([data-hidden-buttons])]:w-auto sticky right-0 bg-background-dimmed",
isSticky && variants[variant].stickyCell,
isSelected && variants[variant].rowSelected,
!isSelected &&
"group-hover/table-row:before:absolute group-hover/table-row:before:left-0 group-hover/table-row:before:top-[-1px] group-hover/table-row:before:h-px group-hover/table-row:before:w-3 group-hover/table-row:before:bg-charcoal-750 group-hover/table-row:after:absolute group-hover/table-row:after:bottom-0 group-hover/table-row:after:left-0 group-hover/table-row:after:h-px group-hover/table-row:after:w-3 group-hover/table-row:after:bg-charcoal-750 group-focus-visible/table-row:bg-background-bright",
"group-hover/table-row:before:absolute group-hover/table-row:before:left-0 group-hover/table-row:before:-top-px group-hover/table-row:before:h-px group-hover/table-row:before:w-3 group-hover/table-row:before:bg-background-hover group-hover/table-row:after:absolute group-hover/table-row:after:bottom-0 group-hover/table-row:after:left-0 group-hover/table-row:after:h-px group-hover/table-row:after:w-3 group-hover/table-row:after:bg-background-hover group-focus-visible/table-row:bg-background-bright",
className
)}
colSpan={colSpan}
@@ -327,7 +326,7 @@ export const TableCell = forwardRef<HTMLTableCellElement, TableCellProps>(
{to ? (
<Link
to={to}
className={cn("cursor-pointer focus:outline-none", flexClasses, actionClassName)}
className={cn("cursor-pointer focus:outline-hidden", flexClasses, actionClassName)}
tabIndex={isTabbableCell ? 0 : -1}
>
{children}
@@ -335,7 +334,7 @@ export const TableCell = forwardRef<HTMLTableCellElement, TableCellProps>(
) : onClick ? (
<button
onClick={onClick}
className={cn("cursor-pointer focus:outline-none", flexClasses, actionClassName)}
className={cn("cursor-pointer focus:outline-hidden", flexClasses, actionClassName)}
tabIndex={isTabbableCell ? 0 : -1}
>
{children}
@@ -378,10 +377,10 @@ export const CopyableTableCell = forwardRef<HTMLTableCellElement, CopyableTableC
button={
<span
className={cn(
"flex size-6 items-center justify-center rounded border border-charcoal-650 bg-charcoal-750",
"flex size-6 items-center justify-center rounded border border-border-bright bg-background-hover",
copied
? "text-green-500"
: "text-text-dimmed hover:border-charcoal-600 hover:bg-charcoal-700 hover:text-text-bright"
: "text-text-dimmed hover:border-border-bright hover:bg-background-raised hover:text-text-bright"
)}
>
{copied ? (
@@ -480,6 +479,7 @@ export const TableCellMenu = forwardRef<
{/* Hidden buttons that show on hover */}
{hiddenButtons && (
<div
data-hidden-buttons
className={cn(
"hidden group-hover/table-row:block",
popoverContent && "pr-0.5 group-hover/table-row:border-r",
@@ -501,7 +501,7 @@ export const TableCellMenu = forwardRef<
className="duration-0 group-hover/table-row:text-text-bright"
/>
<PopoverContent
className="min-w-[10rem] max-w-[20rem] overflow-y-auto p-0 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600"
className="min-w-40 max-w-80 overflow-y-auto p-0 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control"
align="end"
>
{typeof popoverContent === "function" ? (

Some files were not shown because too many files have changed in this diff Show More