Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
0f2f1f8
refactor(frontend): adapt remaining app surfaces to dark theme
bilalabbad Aug 17, 2026
3b3eb40
chore(frontend): refresh betterer results after dark theme sweep
bilalabbad Aug 17, 2026
f651eb9
fix(frontend): keep white text on the danger button in light theme
bilalabbad Aug 17, 2026
cc76ce1
review
bilalabbad Aug 17, 2026
774059d
docs(specs): add dark theme completion specification
saltas888 Aug 17, 2026
14fbf99
docs(specs): add dark theme completion implementation plan
saltas888 Aug 17, 2026
7ebfc5b
docs(specs): critique dark theme completion and apply must-address fixes
saltas888 Aug 17, 2026
0a06189
docs(specs): add dark theme completion task breakdown
saltas888 Aug 17, 2026
30efa6d
docs(specs): add dark theme completion alignment check
saltas888 Aug 17, 2026
642bb5f
docs(specs): apply edge-case review to dark theme completion
saltas888 Aug 17, 2026
15c195e
docs(specs): keep dark opt-in; production defaults to light
saltas888 Aug 17, 2026
763dec3
docs(specs): gate dark theme behind an experimental flag
saltas888 Aug 17, 2026
e8da3a3
docs(specs): scope the flag to the dev compose file and name the defe…
saltas888 Aug 17, 2026
6055b31
feat(frontend): add theme resolution rule and resolved-theme type
saltas888 Aug 17, 2026
3566d0a
feat(frontend): bind GraphiQL and Mermaid to the active theme
saltas888 Aug 17, 2026
4aab39c
fix(frontend): tokenize always-light surfaces broken in dark mode
saltas888 Aug 17, 2026
4ef12a7
docs(specs): correct SC-004 after implementation found the real defects
saltas888 Aug 17, 2026
38747ed
fix(frontend): actually theme mermaid diagrams
saltas888 Aug 17, 2026
3122a61
docs(frontend): forbid fixed-palette surface classes
saltas888 Aug 17, 2026
946eb0c
fix(frontend): paint native browser UI in the active theme
saltas888 Aug 17, 2026
abf1996
refactor(frontend): drop a redundant dark variant from the gray badge
saltas888 Aug 17, 2026
4739b1a
fix(frontend): tokenize the active-state indigo
saltas888 Aug 17, 2026
e217f33
fix(frontend): give the avatar ramp and the template tile a dark palette
saltas888 Aug 17, 2026
b777823
feat(frontend): default non-production deployments to the dark theme
saltas888 Aug 17, 2026
198e6b2
feat(frontend): offer the dark theme when the backend predates the flag
saltas888 Aug 18, 2026
b46cffd
fix(frontend): paint reloads from the resolved mirror only
saltas888 Aug 18, 2026
d48d55f
fix(frontend): keep the mermaid directive out of quoted fences
saltas888 Aug 18, 2026
c5cb03e
fix(frontend): theme the alert close-button focus ring
saltas888 Aug 18, 2026
207326e
test(frontend): cover the theme's reading hook and its user journeys
saltas888 Aug 18, 2026
c3cca10
docs(dev): explain how theming works
saltas888 Aug 18, 2026
be0e7ee
docs(specs): reconcile spec artifacts with the implemented design
saltas888 Aug 18, 2026
ae77ce4
refactor(frontend): move theming into the design system, let mermaid …
saltas888 Aug 18, 2026
92258d2
fix(frontend): clear the contrast audit in both themes
saltas888 Aug 18, 2026
c3b3e9b
docs: document the dark theme for users
saltas888 Aug 18, 2026
d21affa
chore(frontend): refresh the betterer baseline after the theming move
saltas888 Aug 18, 2026
8eed77b
fix(docs): commit the configuration reference byte-exact with the gen…
saltas888 Aug 18, 2026
f8ac285
fix(ci): let the generator own the dark-theme flag in the root compos…
saltas888 Aug 18, 2026
9f2afe8
refactor(frontend): move the theme provider into the design system
saltas888 Aug 18, 2026
f95baab
bulk action in table dark theme
bilalabbad Aug 18, 2026
313b133
chore: TEMPORARY — default the dark theme on so preview envs serve it
saltas888 Aug 18, 2026
79d891c
chore(spec): tick T059 now that the local CI gate has been run
saltas888 Aug 18, 2026
31c8014
Merge branch 'bab-dark-theme-app' into dark-theme-completion-infp-46
saltas888 Aug 18, 2026
de36a8a
fix(frontend): regenerate the REST types after the OpenAPI default ch…
saltas888 Aug 18, 2026
6a5b79e
color cleanup
bilalabbad Aug 18, 2026
30a8241
Merge branch 'bab-dark-theme-app' into dark-theme-completion-infp-46
saltas888 Aug 18, 2026
441db4a
fix(frontend): theme the date-time picker
saltas888 Aug 18, 2026
7a1d36a
fix(frontend): theme the toasts
saltas888 Aug 18, 2026
4091840
fix(frontend): fade the IPAM header into its real surface, not into w…
saltas888 Aug 18, 2026
a5edf71
fix(frontend): sweep the remaining fixed-light surfaces
saltas888 Aug 18, 2026
48906c0
fix(frontend): retune GraphiQL's dark palette to the app's stone family
saltas888 Aug 18, 2026
489d809
fix: unbreak develop's tree E2E jobs and stop a class-name leak (#10287)
saltas888 Aug 17, 2026
96ea50b
fix(frontend): paint the theme before the first frame, not after it
saltas888 Aug 19, 2026
f454ee7
fix(frontend): tag only the option that switches into the alpha theme
saltas888 Aug 19, 2026
d17a7b1
revert: restore the dark theme's default to off
saltas888 Aug 19, 2026
5f755ab
feat(frontend): theme the schema visualizer with the application's theme
saltas888 Aug 19, 2026
498ce13
Merge pull request #10295 from opsmill/dark-theme-completion-infp-46
saltas888 Aug 19, 2026
b9bc6b4
Merge branch 'develop' into bab-dark-theme-app
saltas888 Aug 19, 2026
e2f2430
chore: drop a comment that narrates the generation pipeline
saltas888 Aug 20, 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
60 changes: 27 additions & 33 deletions frontend/app/.betterer.results

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions frontend/app/src/app/styles/markdown.css
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@
}

.markdown .mermaid-error {
background-color: #fef2f2;
color: #b91c1c;
background-color: var(--danger-surface);
color: var(--danger);
white-space: pre-wrap;
}
4 changes: 2 additions & 2 deletions frontend/app/src/assets/icons/tasks-status.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const LoginMethodPicker = () => {
const [active, setActive] = useLastUsedMethod(methods, preferredDefault(methods));

if (methods.length === 0 || !active) {
return <p className="text-red-500 text-sm">No authentication method available.</p>;
return <p className="text-danger text-sm">No authentication method available.</p>;
}

const others = methods.filter((m) => m.kind !== active.kind);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { LinkButton } from "@infrahub/ui";
import { useLocation, useSearchParams } from "react-router";

import { Icon } from "@/shared/components/display/icon";
Expand Down Expand Up @@ -49,12 +50,9 @@ export const ProviderButton = ({
const authorizeUrl = `${INFRAHUB_API_SERVER_URL + provider.authorize_path}?final_url=${encodeURIComponent(redirectTo)}`;

return (
<a
className="inline-flex h-9 items-center justify-center whitespace-nowrap rounded-md border bg-white px-4 py-2 font-medium text-sm shadow-xs hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-60"
href={authorizeUrl}
>
<LinkButton variant="outline" href={authorizeUrl} className="font-medium">
<Icon icon={provider.icon} />
<span className="ml-2">Continue with {provider.display_label}</span>
</a>
Continue with {provider.display_label}
</LinkButton>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,21 @@ export function BranchWorkingNotice({ branch }: BranchWorkingNoticeProps) {

if (currentBranch.name === branch.name) {
return (
<BranchNotice className="bg-cyan-700/10 text-cyan-800" data-testid="branch-working-notice">
<BranchNotice
className="bg-cyan-700/10 text-cyan-800 dark:bg-cyan-200/10 dark:text-cyan-200"
data-testid="branch-working-notice"
>
<GitBranchIcon className="size-4 shrink-0" aria-hidden="true" />
<p>You're working on this branch.</p>
</BranchNotice>
);
}

return (
<BranchNotice className="bg-amber-50 text-amber-800" data-testid="branch-mismatch-notice">
<BranchNotice
className="bg-amber-50 text-amber-800 dark:bg-amber-200/10 dark:text-amber-200"
data-testid="branch-mismatch-notice"
>
<TriangleAlertIcon className="size-4 shrink-0" aria-hidden="true" />
<p>
You're viewing <span className="font-semibold">{branch.name}</span> but working on{" "}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export function BranchActionsCell({ branch }: BranchActionsCellProps) {
<MenuItem
isDisabled={!isDeleteAllowed}
tooltip={branch.is_default ? "Cannot delete the default branch" : "Login required"}
className="text-red-500"
className="text-danger"
onAction={() => setShowDeleteModal(true)}
>
<Trash2Icon />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { LinkButton, Spinner } from "@infrahub/ui";
import { Spinner } from "@infrahub/ui";
import { Link } from "react-router";

import { Row } from "@/shared/components/container";
import { Icon } from "@/shared/components/display/icon";
import { TableCell } from "@/shared/components/table/table-cell";
import { LinkPill } from "@/shared/components/ui/link-pill";
import { QSP } from "@/shared/config/qsp";

import { getObjectDetailsUrl } from "@/entities/nodes/object/ui/routing/object-urls";
Expand Down Expand Up @@ -55,15 +56,10 @@ export function BranchProposedChangesCell({ branchName }: BranchProposedChangesC
return (
<TableCell className="h-auto min-h-14">
<Row className="flex-wrap">
<LinkButton
variant="outline"
size="sm"
href={detailUrl}
className="max-w-40 rounded-full pr-2.5 data-hovered:border-custom-blue-700 data-hovered:underline"
>
<Icon icon={getSchemaIcon(schema)} className="shrink-0 text-custom-blue-800" />
<LinkPill href={detailUrl} className="max-w-40">
<Icon icon={getSchemaIcon(schema)} className="shrink-0 text-accent" />
<span className="truncate">{firstPC.node.name.value}</span>
</LinkButton>
</LinkPill>

{remainingCount > 0 && (
<Link
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ export function ModalDeleteBranch({
>
<Col className="gap-4 p-3">
<Heading slot="title" className="flex items-center gap-2 p-1 font-semibold">
<div className="flex size-8 shrink-0 items-center justify-center rounded-full bg-red-100">
<Icon icon="mdi:warning-outline" className="text-red-600" />
<div className="flex size-8 shrink-0 items-center justify-center rounded-full bg-danger-surface">
<Icon icon="mdi:warning-outline" className="text-danger" />
</div>
Delete
</Heading>
Expand Down Expand Up @@ -143,7 +143,7 @@ export function ModalDeleteBranch({
</RadioGroup>
</Col>

<Row className="justify-end bg-gray-50 p-3">
<Row className="justify-end bg-gray-50 p-3 dark:bg-white/5">
<Button variant="outline" onPress={() => handleOpenChange(false)} isDisabled={isLoading}>
Cancel
</Button>
Expand Down
8 changes: 4 additions & 4 deletions frontend/app/src/entities/config/ui/about-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Button, Modal } from "@infrahub/ui";
import { Button, Card, Modal } from "@infrahub/ui";
import { XIcon } from "lucide-react";

import { Separator } from "@/shared/components/aria/separator";
import { CopyToClipboardButton } from "@/shared/components/buttons/copy-to-clipboard-button";
import { Col, Row } from "@/shared/components/container";
import { Row } from "@/shared/components/container";
import { Skeleton } from "@/shared/components/loading/skeleton";
import { InfrahubLogo } from "@/shared/components/ui/infrahub-logo";

Expand Down Expand Up @@ -37,13 +37,13 @@ export function AboutModal({ isOpen, onOpenChange }: AboutModalProps) {
</Button>
</Row>

<Col className="rounded-xl bg-stone-100 px-3 py-2.5">
<Card variant="panel" className="gap-2 rounded-xl px-3 py-2.5">
<InfoRow label="Version" value={version} isLoading={isPending} />
<Separator />
<InfoRow label="Edition" value={config.installation_type} />
<Separator />
<InfoRow label="Deployment ID" value={deploymentId} isLoading={isPending} />
</Col>
</Card>
</Modal>
);
}
Expand Down
16 changes: 11 additions & 5 deletions frontend/app/src/entities/diff/ui/checks/check.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,27 @@ const getCheckIcon = (conclusion?: string | null) => {
case "success": {
return (
<Tooltip message="Success" nonInteractiveTrigger>
<Icon icon={"mdi:check-circle-outline"} className="mr-2 text-green-500" />
<Icon
icon={"mdi:check-circle-outline"}
className="mr-2 text-green-500 dark:text-green-400"
/>
</Tooltip>
);
}
case "failure": {
return (
<Tooltip message="Failure" nonInteractiveTrigger>
<Icon icon={"mdi:warning"} className="mr-2 text-red-500" />
<Icon icon={"mdi:warning"} className="mr-2 text-red-500 dark:text-red-400" />
</Tooltip>
);
}
default: {
return (
<Tooltip message="In progress" nonInteractiveTrigger>
<Icon icon={"mdi:warning-circle-outline"} className="mr-2 text-yellow-500" />
<Icon
icon={"mdi:warning-circle-outline"}
className="mr-2 text-yellow-500 dark:text-yellow-400"
/>
</Tooltip>
);
}
Expand Down Expand Up @@ -76,7 +82,7 @@ export const Check = ({ id }: tCheckProps) => {

if (error) {
return (
<div className={"flex flex-col rounded-md border-l-4 bg-white p-2"}>
<div className={"flex flex-col rounded-md border-l-4 bg-white p-2 dark:bg-stone-900"}>
<ErrorScreen message="Something went wrong when fetching the check details" />
</div>
);
Expand Down Expand Up @@ -129,7 +135,7 @@ export const Check = ({ id }: tCheckProps) => {
return (
<div
className={classNames(
"flex min-w-0 flex-col rounded-md border border-l-4 bg-gray-50 p-2",
"flex min-w-0 flex-col rounded-md border border-l-4 bg-gray-50 p-2 dark:bg-white/5",
getCheckBorderColor(severity?.value)
)}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export const ChecksSummary = (props: ChecksSummaryProps) => {
onPress={() => handleRetry("all")}
isDisabled={!isAuthenticated}
variant="ghost"
className="gap-1 data-hovered:bg-neutral-200"
className="gap-1 data-hovered:bg-highlight"
>
Retry all
<Retry isLoading={isPending || isLoading} isDisabled={isPending || isLoading} />
Expand Down
10 changes: 7 additions & 3 deletions frontend/app/src/entities/diff/ui/checks/data-conflict.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export const DataConflict = ({ id, changes, kind, name }: DataConflictProps) =>

<Link to={url}>
<DiffRow
className="group overflow-hidden rounded-sm pl-0 transition-all hover:bg-yellow-100"
className="group overflow-hidden rounded-sm pl-0 transition-all hover:bg-yellow-100 dark:hover:bg-yellow-400/15"
iconClassName="left-4"
hasConflicts
title={
Expand All @@ -75,7 +75,9 @@ export const DataConflict = ({ id, changes, kind, name }: DataConflictProps) =>
</Badge>
</div>
}
leftClassName={classNames("font-normal group-hover:bg-gray-100 transition-all")}
leftClassName={classNames(
"font-normal group-hover:bg-gray-100 dark:group-hover:bg-white/10 transition-all"
)}
right={
<div className="flex items-center gap-2">
{branchChange?.previous}
Expand All @@ -85,7 +87,9 @@ export const DataConflict = ({ id, changes, kind, name }: DataConflictProps) =>
</Badge>
</div>
}
rightClassName={classNames("font-normal group-hover:bg-gray-50 transition-all")}
rightClassName={classNames(
"font-normal group-hover:bg-gray-50 dark:group-hover:bg-white/5 transition-all"
)}
/>
</Link>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const DataIntegrityConflicts = ({ conflicts }: Pick<CoreDataCheck, "confl
const proposedChange = useProposedChange();

return (
<div className="rounded-md border bg-white p-2">
<div className="rounded-md border bg-white p-2 dark:bg-stone-900">
<div className="grid grid-cols-3">
<Badge variant="green" className="col-start-2 col-end-3 bg-transparent">
<Icon icon="mdi:layers-triple" className="mr-1" />{" "}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { SchemaConflict } from "./schema-conflict";

export const SchemaIntegrityConflicts = ({ conflicts }: Pick<CoreDataCheck, "conflicts">) => {
return (
<div className="rounded-md border bg-white p-2">
<div className="rounded-md border bg-white p-2 dark:bg-stone-900">
{conflicts?.value?.map((conflict: any) => {
return <SchemaConflict key={conflict.id} {...conflict} />;
})}
Expand Down
22 changes: 16 additions & 6 deletions frontend/app/src/entities/diff/ui/checks/validator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,17 @@ const getValidatorState = (state?: string, conclusion?: string) => {
case "queued": {
return (
<Tooltip message="Queued" nonInteractiveTrigger>
<Icon icon={"mdi:timer-sand-complete"} className="text-yellow-500" />
<Icon icon={"mdi:timer-sand-complete"} className="text-yellow-500 dark:text-yellow-400" />
</Tooltip>
);
}
case "in_progress": {
return (
<Tooltip message="In progress" nonInteractiveTrigger>
<Icon icon={"mdi:clock-time-four-outline"} className="text-yellow-500" />
<Icon
icon={"mdi:clock-time-four-outline"}
className="text-yellow-500 dark:text-yellow-400"
/>
</Tooltip>
);
}
Expand All @@ -40,7 +43,7 @@ const getValidatorState = (state?: string, conclusion?: string) => {
<Tooltip message="Success" nonInteractiveTrigger>
<Icon
icon={"mdi:check-circle-outline"}
className="text-green-500"
className="text-green-500 dark:text-green-400"
data-testid="validator-success"
/>
</Tooltip>
Expand All @@ -50,14 +53,17 @@ const getValidatorState = (state?: string, conclusion?: string) => {
if (conclusion === "failure") {
return (
<Tooltip message="Failure" nonInteractiveTrigger>
<Icon icon={"mdi:warning"} className="text-red-500" />
<Icon icon={"mdi:warning"} className="text-red-500 dark:text-red-400" />
</Tooltip>
);
}

return (
<Tooltip message="Unknown" nonInteractiveTrigger>
<Icon icon={"mdi:warning-circle-outline"} className="text-yellow-500" />
<Icon
icon={"mdi:warning-circle-outline"}
className="text-yellow-500 dark:text-yellow-400"
/>
</Tooltip>
);
}
Expand Down Expand Up @@ -151,7 +157,11 @@ export const Validator = ({ validator }: tValidatorProps) => {
);

return (
<Accordion title={title} className="rounded-md bg-white p-2" data-testid="validator">
<Accordion
title={title}
className="rounded-md bg-white p-2 dark:bg-stone-900"
data-testid="validator"
>
<ValidatorDetails id={id} />
</Accordion>
);
Expand Down
20 changes: 16 additions & 4 deletions frontend/app/src/entities/diff/ui/diff-badge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ export const BadgeAdded = ({ className, ...props }: DiffBadgeProps) => {
<BadgeUnchanged
{...props}
icon="mdi:plus-circle-outline"
className={classNames("bg-green-200 text-green-800", className)}
className={classNames(
"bg-green-200 text-green-800 dark:bg-green-400/20 dark:text-green-300",
className
)}
/>
);
};
Expand All @@ -53,7 +56,10 @@ export const BadgeRemoved = ({ className, ...props }: DiffBadgeProps) => {
<BadgeUnchanged
{...props}
icon="mdi:minus-circle-outline"
className={classNames("bg-red-200 text-red-800", className)}
className={classNames(
"bg-red-200 text-red-800 dark:bg-red-400/20 dark:text-red-300",
className
)}
/>
);
};
Expand All @@ -63,7 +69,10 @@ export const BadgeConflict = ({ className, ...props }: DiffBadgeProps) => {
<BadgeUnchanged
{...props}
icon="mdi:warning-outline"
className={classNames("bg-yellow-200 text-yellow-800", className)}
className={classNames(
"bg-yellow-200 text-yellow-800 dark:bg-yellow-400/20 dark:text-yellow-300",
className
)}
/>
);
};
Expand All @@ -73,7 +82,10 @@ export const BadgeUpdated = ({ className, ...props }: DiffBadgeProps) => {
<BadgeUnchanged
{...props}
icon="mdi:circle-arrows"
className={classNames("bg-blue-200 text-blue-800", className)}
className={classNames(
"bg-blue-200 text-blue-800 dark:bg-blue-400/20 dark:text-blue-300",
className
)}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export function DiffBranchNotFound({ branchName }: DiffBranchNotFoundProps) {
return (
<div className="my-10 flex flex-col items-center gap-5">
<div className="inline-flex rounded-full bg-white p-3">
<Icon icon="mdi:source-branch-remove" className="text-2xl text-red-400" />
<Icon icon="mdi:source-branch-remove" className="text-2xl text-danger" />
</div>

<h1 className="font-semibold text-lg">Branch not available</h1>
Expand Down
Loading
Loading