Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
ee88a8e
feat(webapp): switch themes from the account menu
samejr Aug 10, 2026
54939fe
feat(webapp): more options entry, theme select and a finer contrast s…
samejr Aug 10, 2026
41a9789
fix(webapp): stop the contrast label sticking, tighten the theme picker
samejr Aug 10, 2026
47d3246
feat(webapp): mark the default contrast on the slider
samejr Aug 10, 2026
4d5645d
fix(webapp): widen the theme select and correct the tooltip arrow
samejr Aug 10, 2026
4c6ddfb
fix(webapp): notch the contrast track at the default mark
samejr Aug 10, 2026
5c9de3d
fix(webapp): notch the contrast mark against the real page colour
samejr Aug 10, 2026
2a1e291
fix(webapp): widen the gap either side of the contrast mark
samejr Aug 10, 2026
74802cf
fix(webapp): thicken the contrast mark line to 2px
samejr Aug 10, 2026
e0a58ca
feat(webapp): click the contrast mark to reset to the default
samejr Aug 10, 2026
0aeee45
feat(webapp): split icon and badge accents out into an Icon contrast …
samejr Aug 10, 2026
34ad34f
feat(webapp): add an App sidebar row and descriptions to the profile …
samejr Aug 10, 2026
ade0691
fix(webapp): tighten settings row descriptions
samejr Aug 10, 2026
07d62a1
feat(webapp): open the customize sidebar modal from the profile page
samejr Aug 10, 2026
f1b7413
fix(webapp): apply the theme on click, not on the loader's next pass
samejr Aug 11, 2026
23533dd
fix(webapp): brighten the secondary button on hover in the dark themes
samejr Aug 11, 2026
77ed110
fix(webapp): brighten the secondary select on hover in the dark themes
samejr Aug 11, 2026
b80cc8c
feat(webapp): add a surround-free switch variant and move it to indigo
samejr Aug 11, 2026
e0b7a8a
feat(webapp): drop the switch surround on the onboarding emails row
samejr Aug 11, 2026
3037a21
fix(webapp): dim the contrast handle and brighten it on hover
samejr Aug 11, 2026
d9866d8
fix(webapp): step the Customize button and theme select down a size
samejr Aug 11, 2026
641dc25
feat(webapp): floor the contrast slider at 15% and mark the default a…
samejr Aug 11, 2026
bb48233
feat(webapp): add an Underline links preference
samejr Aug 11, 2026
f2adfeb
chore(webapp): temporary underline audit story
samejr Aug 11, 2026
c9e6590
refactor(webapp): route hand-rolled links through TextLink
samejr Aug 11, 2026
1afd029
Merge remote-tracking branch 'origin/main' into samejr/appearance-the…
samejr Aug 12, 2026
5175479
feat(webapp): add Black and White themes
samejr Aug 12, 2026
948db74
feat(webapp): swap the Black and White icons with the active theme
samejr Aug 12, 2026
38dc6a5
feat(webapp): use a custom monitor icon for the System theme
samejr Aug 12, 2026
ab1f24e
feat(webapp): split Theme from Interface and let System pick its two …
samejr Aug 12, 2026
f4ef1b3
fix(webapp): rename the Theme section to Appearance
samejr Aug 12, 2026
f44e574
feat(webapp): slide the system Light and Dark rows open and shut
samejr Aug 12, 2026
b4cfb15
chore(webapp): remove the temporary underline audit story
samejr Aug 12, 2026
1570540
Merge remote-tracking branch 'origin/main' into samejr/appearance-the…
samejr Aug 12, 2026
3b65be0
fix(webapp): treat the White theme as light, not dark
samejr Aug 12, 2026
9cb6fc1
fix(webapp): keep the button text color when the label isn't plain text
samejr Aug 12, 2026
e9080b2
fix(webapp): give loading spinners a color that suits the theme
samejr Aug 12, 2026
aec652d
fix(webapp): swap the last hard-coded greys for theme tokens
samejr Aug 12, 2026
e09b00e
fix(webapp): list White above Black in the theme picker
samejr Aug 12, 2026
9ac591f
fix(webapp): stop CopyButton nesting a button inside its tooltip trigger
samejr Aug 13, 2026
b9a30e7
feat(webapp): give the storybook a theme switcher and a categorised s…
samejr Aug 13, 2026
b443b2d
feat(webapp): cover the remaining components in the storybook
samejr Aug 13, 2026
7040f45
fix(webapp): stop a ClickHouse outage crashing the dev server
samejr Aug 13, 2026
267ab71
feat(webapp): add theme shortcuts, an icon contrast toggle and an H2 …
samejr Aug 13, 2026
305c8b3
feat(webapp): show a story's component file names, copyable on hover
samejr Aug 13, 2026
10e1fde
feat(webapp): complete the storybook's variant coverage
samejr Aug 13, 2026
a385493
feat(webapp): make Dark the default theme and retire Classic
samejr Aug 13, 2026
4a6e9d3
feat(webapp): move the light themes onto ramp travel too
samejr Aug 13, 2026
cef20b9
fix(webapp): let light's whole surface stack respond to contrast
samejr Aug 13, 2026
59dbe5b
fix(webapp): keep light's surfaces distinct and soften its grid lines
samejr Aug 13, 2026
cbe3788
fix(webapp): hover text links by color, never by adding an underline
samejr Aug 14, 2026
bcb48e7
fix(webapp): move hand-rolled text links onto the shared treatment
samejr Aug 14, 2026
1ddf734
fix(webapp): let markdown prose links follow the underline preference
samejr Aug 14, 2026
bc1d745
fix(webapp): make the text link hover big enough to see
samejr Aug 14, 2026
9d7fc59
refactor(webapp): give every text link one theme-aware color
samejr Aug 14, 2026
638649c
refactor(webapp): move the last hand-rolled links onto TextLink
samejr Aug 14, 2026
838c10f
fix(webapp): let the switch's checked fill follow the theme
samejr Aug 14, 2026
e67da93
fix(webapp): give the primary button and the switch one shared accent
samejr Aug 14, 2026
3faf71c
fix(webapp): drop the stray full stop from the Dark system setting row
samejr Aug 14, 2026
abf3f19
feat(webapp): update each profile field on its own instead of one big…
samejr Aug 14, 2026
2cf0672
fix(webapp): let log level chips and a few stray accents follow the t…
samejr Aug 14, 2026
6682a3d
fix(webapp): show the Stronger colors example chip on hover, not in a…
samejr Aug 14, 2026
781fb4a
feat(webapp): move the profile name and email onto the row, behind an…
samejr Aug 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions apps/webapp/app/assets/icons/AppearanceIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/** Circle with one half filled — the theme/appearance setting. */
export function AppearanceIcon({ className }: { className?: string }) {
return (
<svg
className={className}
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21Z"
stroke="currentColor"
strokeWidth="2"
/>
<path
d="M12 8C9.79086 8 8 9.79086 8 12C8 14.2091 9.79086 16 12 16V21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3V8ZM12 8C14.2091 8 16 9.79086 16 12C16 14.2091 14.2091 16 12 16V8Z"
fill="currentColor"
/>
</svg>
);
}
16 changes: 16 additions & 0 deletions apps/webapp/app/assets/icons/CircleFilledIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/** Solid circle. Paired with {@link CircleOutlineIcon} by the Black and White
* theme options — the filled disc reads as the opposite of the active theme. */
export function CircleFilledIcon({ className }: { className?: string }) {
return (
<svg
className={className}
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="12" cy="12" r="9" fill="currentColor" />
</svg>
);
}
16 changes: 16 additions & 0 deletions apps/webapp/app/assets/icons/CircleOutlineIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/** Hollow circle. Paired with {@link CircleFilledIcon} by the Black and White
* theme options, which show the active theme's background through the ring. */
export function CircleOutlineIcon({ className }: { className?: string }) {
return (
<svg
className={className}
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="12" cy="12" r="8" stroke="currentColor" strokeWidth="2" />
</svg>
);
}
22 changes: 22 additions & 0 deletions apps/webapp/app/assets/icons/EditPencilIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/** Pencil over a couple of text lines — editing a value in place. */
export function EditPencilIcon({ className }: { className?: string }) {
return (
<svg
className={className}
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M18.7573 3.6275L20.3732 5.24335C21.1542 6.0244 21.1542 7.29073 20.3732 8.07178L9.72032 18.7246C9.57777 18.8671 9.3957 18.9631 9.19759 19.0002L4.03377 19.9669L5.00052 14.8031C5.03765 14.6051 5.1336 14.4229 5.27604 14.2804L15.9289 3.6275C16.71 2.84645 17.9763 2.84645 18.7573 3.6275Z"
stroke="currentColor"
strokeWidth="2"
/>
<line x1="17.6464" y1="10.3536" x2="13.6464" y2="6.35355" stroke="currentColor" />
<path d="M13 21L21 21" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
<path d="M18 17L21 17" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
</svg>
);
}
21 changes: 21 additions & 0 deletions apps/webapp/app/assets/icons/MonitorIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/** Monitor on a stand — the System theme, which follows the OS appearance. */
export function MonitorIcon({ className }: { className?: string }) {
return (
<svg
className={className}
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M21 13H3M11 17H13L14 21H10L11 17ZM5 17H19C20.1046 17 21 16.1046 21 15V6C21 4.89543 20.1046 4 19 4H5C3.89543 4 3 4.89543 3 6V15C3 16.1046 3.89543 17 5 17Z"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="square"
strokeLinejoin="round"
/>
</svg>
);
}
21 changes: 21 additions & 0 deletions apps/webapp/app/assets/icons/MoonIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/** Crescent moon — the dark theme. */
export function MoonIcon({ className }: { className?: string }) {
return (
<svg
className={className}
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M20.9638 12.7674C19.8361 13.5447 18.4693 13.9998 16.9961 13.9998C13.1301 13.9998 9.99609 10.8657 9.99609 6.99975C9.99609 5.52667 10.4511 4.15987 11.2283 3.03223C6.61911 3.42277 3 7.28768 3 11.9979C3 16.9674 7.0286 20.996 11.9981 20.996C16.7084 20.996 20.5734 17.3767 20.9638 12.7674Z"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}
34 changes: 34 additions & 0 deletions apps/webapp/app/assets/icons/SunIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Sun with rays — the light theme. The source artwork wrapped this in a mask and
* a clip path; both were no-ops at this viewBox, and dropping them keeps the
* markup free of ids that would collide when the icon renders more than once.
*/
export function SunIcon({ className }: { className?: string }) {
return (
<svg
className={className}
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M15.5355 8.46447C17.4882 10.4171 17.4882 13.5829 15.5355 15.5355C13.5829 17.4882 10.4171 17.4882 8.46447 15.5355C6.51184 13.5829 6.51184 10.4171 8.46447 8.46447C10.4171 6.51184 13.5829 6.51184 15.5355 8.46447Z"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M12 3V1M12 23V21M21 12H23M1 12H3M5.63603 5.63604L4.22182 4.22183M19.7782 19.7782L18.364 18.364M18.364 5.63606L19.7782 4.22184M4.22183 19.7782L5.63605 18.364"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}
23 changes: 23 additions & 0 deletions apps/webapp/app/assets/icons/ToggleSwitchIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/** Toggle switch, knob to the left. */
export function ToggleSwitchIcon({ className }: { className?: string }) {
return (
<svg
className={className}
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M15.5 5H8.5C4.63401 5 1.5 8.13401 1.5 12C1.5 15.866 4.63401 19 8.5 19H15.5C19.366 19 22.5 15.866 22.5 12C22.5 8.13401 19.366 5 15.5 5Z"
stroke="currentColor"
strokeWidth="2"
/>
<path
d="M8.5 15C10.1569 15 11.5 13.6569 11.5 12C11.5 10.3431 10.1569 9 8.5 9C6.84315 9 5.5 10.3431 5.5 12C5.5 13.6569 6.84315 15 8.5 15Z"
fill="currentColor"
/>
</svg>
);
}
Binary file removed apps/webapp/app/assets/images/producthunt.png
Binary file not shown.
24 changes: 0 additions & 24 deletions apps/webapp/app/components/ProductHuntBanner.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { Paragraph } from "~/components/primitives/Paragraph";
import { RadioGroup, RadioGroupItem } from "~/components/primitives/RadioButton";
import type { BillingLimitResult } from "~/services/billingLimit.schemas";
import { formatCurrency } from "~/utils/numberFormatter";
import { TextLink } from "~/components/primitives/TextLink";

export const billingLimitFormSchema = z.discriminatedUnion("mode", [
z.object({
Expand Down Expand Up @@ -338,10 +339,7 @@ function LimitReachedCalloutContent({
When this limit is reached, queued runs will be held for {gracePeriodLabel}, then new triggers
will be rejected until you increase or remove the limit. Limits are enforced with a short
delay, so spend may briefly exceed the limit before grace begins. See our{" "}
<a href="https://trigger.dev/terms" className="underline">
terms
</a>{" "}
for refund policy details.
<TextLink href="https://trigger.dev/terms">terms</TextLink> for refund policy details.
{cancelInProgressRuns ? (
<> In-progress runs will be cancelled when the limit is hit.</>
) : null}
Expand Down
3 changes: 2 additions & 1 deletion apps/webapp/app/components/billing/FreePlanUsage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ArrowUpCircleIcon } from "@heroicons/react/24/outline";
import { Link } from "@remix-run/react";
import { motion, useMotionValue, useTransform } from "framer-motion";
import { textLinkClassName } from "~/components/primitives/TextLink";
import { useThemeColor } from "~/hooks/useThemeColor";
import { cn } from "~/utils/cn";

Expand Down Expand Up @@ -31,7 +32,7 @@ export function FreePlanUsage({ to, percentage }: { to: string; percentage: numb
<ArrowUpCircleIcon className="h-5 w-5 shrink-0 text-text-dimmed" />
<span className="truncate text-2sm text-text-bright">Free Plan</span>
</div>
<Link to={to} className="shrink-0 text-2sm text-text-link focus-custom">
<Link to={to} className={cn(textLinkClassName(), "shrink-0 text-2sm")}>
Upgrade
</Link>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Link } from "@remix-run/react";
import { AgentMonoLogo } from "~/components/primitives/AgentDotMatrix";
import { LinkButton } from "~/components/primitives/Buttons";
import { textLinkClassName } from "~/components/primitives/TextLink";
import { useOrganization } from "~/hooks/useOrganizations";
import { v3BillingPath } from "~/utils/pathBuilder";
import { ASK_AGENT_LABEL } from "./agent-identity";
Expand Down Expand Up @@ -48,10 +49,7 @@ export function AgentQuotaNotice({ remaining, limit }: { remaining: number; limi
{remaining} of {limit} free messages left
</span>
<span aria-hidden>·</span>
<Link
to={v3BillingPath(organization)}
className="text-text-link underline-offset-2 hover:underline"
>
<Link to={v3BillingPath(organization)} className={textLinkClassName()}>
Upgrade
</Link>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,13 @@ export function DashboardAgentComposer({
const sendButton = isStreaming ? (
<Button
variant="minimal/small"
className="aspect-square h-7 min-w-0 bg-charcoal-600 p-1 hover:bg-charcoal-550"
className="aspect-square h-7 min-w-0 bg-surface-control p-1 hover:bg-surface-control-hover"
aria-label="Stop generating"
tooltip="Stop generating"
onClick={onStop}
LeadingIcon={<StopIcon className="size-4 text-white" />}
// Not text-white: this button's surface goes light with the theme, unlike
// the indigo Send button below it.
LeadingIcon={<StopIcon className="size-4 text-text-bright" />}
/>
) : (
<Button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
SeverityBadge,
VerdictBadge,
} from "./agent-badges";
import { textLinkClassName } from "~/components/primitives/TextLink";
import { cn } from "~/utils/cn";
import { AgentCard, AgentCardBody, AgentCardHeader } from "./agent-card";
import { ChatActionsRow } from "./chat-layout";
import type { ResolvedUri } from "./ReportView";
Expand Down Expand Up @@ -65,7 +67,7 @@ function EvidenceItem({
{resolved ? (
<a
href={resolved.url}
className="block break-all font-mono text-[10px] text-text-link transition hover:underline"
className={cn(textLinkClassName(), "block break-all font-mono text-[10px]")}
>
{resolved.label}
</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ function RunLink({ runId, className }: { runId: string; className?: string }) {
const to = useRunPath(runId);
if (!to) return <span className={cn("font-mono text-text-dimmed", className)}>{runId}</span>;
return (
<TextLink to={to} variant="token" className={cn("underline", className)}>
<TextLink to={to} className={className}>
{runId}
</TextLink>
);
Expand All @@ -116,10 +116,9 @@ function EvidenceReference({ reference }: { reference: string }) {
return (
<TextLink
href={safeUrl}
variant="token"
target="_blank"
rel="noopener noreferrer"
className="font-mono text-xs underline"
className="font-mono text-xs"
>
{reference}
</TextLink>
Expand Down
Loading