Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
28 changes: 28 additions & 0 deletions apps/desktop/e2e/white-theme.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { expect, test } from "@playwright/test";

test("white canvas, sidebar and panels survive system dark mode", async ({ page }, testInfo) => {
await page.emulateMedia({ colorScheme: "dark" });
for (const view of ["today", "chats", "teams", "automations", "apps", "providers", "tokens", "settings"]) {
await page.goto(`/?state=active&view=${view}`);
const surfaces = await page.evaluate(() => ["canvas", "sidebar", "surface", "surface-strong"].map((token) =>
getComputedStyle(document.documentElement).getPropertyValue(`--${token}`).trim()));
expect(surfaces).toEqual(["#ffffff", "#ffffff", "#ffffff", "#ffffff"]);
for (const selector of ["html", "body", ".app-shell", ".sidebar", ".topbar"]) {
await expect(page.locator(selector)).toHaveCSS("background-color", "rgb(255, 255, 255)");
}
if (view === "tokens") await expect(page.locator(".token-query")).toHaveCSS("background-color", "rgb(255, 255, 255)");
expect(await page.evaluate(() => document.documentElement.scrollWidth > document.documentElement.clientWidth)).toBe(false);
}
await page.goto("/?state=active&view=today");
await page.screenshot({ path: testInfo.outputPath("desktop-white-today.png"), fullPage: true });
});

test("sign-in and access-gated pages use the same white background", async ({ page }, testInfo) => {
for (const state of ["signed_out", "inactive", "unknown"]) {
await page.goto(`/?state=${state}`);
const selectors = state === "signed_out" ? [".access-layout", ".access-story", ".access-panel"] : [".locked-layout"];
for (const selector of selectors) await expect(page.locator(selector)).toHaveCSS("background-color", "rgb(255, 255, 255)");
}
await page.goto("/?state=signed_out");
await page.screenshot({ path: testInfo.outputPath("desktop-white-login.png"), fullPage: true });
});
2 changes: 2 additions & 0 deletions apps/desktop/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
{
"label": "main",
"title": "Simplicio",
"theme": "Light",
"backgroundColor": "#ffffff",
"width": 1280,
"height": 820,
"minWidth": 860,
Expand Down
9 changes: 9 additions & 0 deletions apps/desktop/src/design_system.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import { describe, expect, it } from "vitest";
import rawConfig from "../src-tauri/tauri.conf.json?raw";
import { copy, locale, t } from "./i18n";
import { designTokens } from "./design_tokens";

describe("desktop design system", () => {
it("keeps white surfaces consistent in shared tokens and the native window", () => {
const config = JSON.parse(rawConfig);
expect(designTokens.color.canvas).toBe("#ffffff");
expect(designTokens.color.surface).toBe("#ffffff");
expect(config.app.windows[0].backgroundColor).toBe("#ffffff");
expect(config.app.windows[0].theme).toBe("Light");
});

it("keeps the initial locale and UI copy separate from Runtime data", () => {
expect(locale).toBe("pt-BR");
expect(t("nav.settings")).toBe("Configurações");
Expand Down
4 changes: 2 additions & 2 deletions apps/desktop/src/design_tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ export const designTokens = {
color: {
ink: "#25261f",
muted: "#777567",
canvas: "#f3edda",
surface: "#faf7ea",
canvas: "#ffffff",
surface: "#ffffff",
green: "#54a879",
greenDark: "#2f704e",
warning: "#bb7b34",
Expand Down
40 changes: 20 additions & 20 deletions apps/desktop/src/styles.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
:root {
font-family: Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
color: #25261f;
background: #f3edda;
background: #ffffff;
font-synthesis: none;
text-rendering: optimizeLegibility;
--ink: #25261f;
Expand All @@ -13,13 +13,13 @@
--green-pale: #eef5e9;
--yellow: #e7c66a;
--yellow-soft: #f6e9bd;
--canvas: #f3edda;
--sidebar: #ece4cc;
--surface: #faf7ea;
--surface-strong: #fffdf6;
--surface-muted: #f0ead7;
--line: #d8d0b9;
--line-soft: rgba(117, 108, 79, 0.14);
--canvas: #ffffff;
--sidebar: #ffffff;
--surface: #ffffff;
--surface-strong: #ffffff;
--surface-muted: #f5f6f7;
--line: #dfe3e6;
--line-soft: rgba(37, 38, 31, 0.12);
--warning: #bb7b34;
--danger: #bd665d;
--mono: "SFMono-Regular", "IBM Plex Mono", Consolas, monospace;
Expand Down Expand Up @@ -163,11 +163,11 @@ p { margin-top: 0; }
.button-secondary {
color: #4f5148;
border-color: var(--line);
background: rgba(255, 253, 246, 0.68);
background: var(--surface);
}

.button-secondary:hover {
border-color: #bdb49b;
border-color: #b9c1c7;
background: var(--surface-strong);
}

Expand Down Expand Up @@ -255,7 +255,7 @@ p { margin-top: 0; }

.nav-item:hover {
color: #41433b;
background: rgba(255, 253, 246, 0.48);
background: var(--surface-muted);
}

.nav-item.active {
Expand All @@ -281,9 +281,9 @@ p { margin-top: 0; }
.sidebar-runtime {
margin-top: auto;
padding: 11px;
border: 1px solid #d3cab1;
border: 1px solid var(--line);
border-radius: 10px;
background: rgba(255, 253, 246, 0.52);
background: var(--surface);
}

.runtime-row {
Expand Down Expand Up @@ -338,7 +338,7 @@ p { margin-top: 0; }
grid-template-columns: 1fr auto 1fr;
align-items: center;
gap: 16px;
background: rgba(250, 247, 234, 0.82);
background: var(--surface);
backdrop-filter: blur(14px);
}

Expand Down Expand Up @@ -814,7 +814,7 @@ p { margin-top: 0; }
display: flex;
align-items: center;
gap: 18px;
background: rgba(250, 247, 234, 0.72);
background: var(--surface);
}

.provider-summary > div {
Expand Down Expand Up @@ -854,7 +854,7 @@ p { margin-top: 0; }
border: 1px solid var(--line);
border-radius: 9px;
display: inline-flex;
background: rgba(236, 228, 204, 0.56);
background: var(--surface-muted);
}

.segmented-control button {
Expand Down Expand Up @@ -1007,13 +1007,13 @@ p { margin-top: 0; }
min-width: 0;
margin-top: 10px;
padding: 13px 15px;
border: 1px solid #d3cbb3;
border: 1px solid var(--line);
border-radius: 11px;
display: grid;
grid-template-columns: auto minmax(0, 1fr) auto;
align-items: center;
gap: 13px;
background: #eee7d1;
background: var(--surface-muted);
}

.principle-icon {
Expand Down Expand Up @@ -1149,7 +1149,7 @@ p { margin-top: 0; }
border-radius: 20px 0 0 20px;
display: flex;
flex-direction: column;
background: var(--yellow-soft);
background: var(--surface);
}

.access-story > .brand { margin-bottom: 40px; }
Expand Down Expand Up @@ -1183,7 +1183,7 @@ p { margin-top: 0; }
display: inline-flex;
align-items: center;
gap: 6px;
background: rgba(255, 253, 246, 0.42);
background: var(--surface-muted);
}

.access-proof-grid article > span { color: var(--green-dark); font-size: 10px; }
Expand Down
8 changes: 7 additions & 1 deletion docs/desktop/DESIGN.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
# Desktop design system and accessibility baseline

The Desktop uses a small, light-native visual system: butter canvas, ivory
The Desktop uses a small, light-native visual system: white canvas, sidebar and
surfaces, near-black text, soft green for healthy/action states, and amber only
for attention. CSS custom properties in `src/styles.css` are the source of
truth for color, spacing, radius, focus, motion, and target-size tokens.

The native window also starts with a white background and the light theme, so
startup, login and workspace surfaces remain consistent when the operating
system prefers dark mode. Neutral secondary surfaces use a light gray; color
accents communicate status and actions rather than tinting the application
background. Browser theme tests do not certify an installed platform package.

The initial locale is `pt-BR`. `src/i18n.ts` contains UI copy keys only;
Runtime strings and provider IDs remain data and are never used as translation
keys.
Expand Down
Loading