Replaces the dark navy palette with a light grouped-background system: - theme.ts: full token set (space/radius/type/shadow) + light+dark palettes - ui.tsx: Screen/Title/SectionHeader/Card/Separator/Pill/Empty primitives - TaskRow: rounded-square checkbox carrying priority colour, inset separators - TaskListScreen: rows grouped into a card, drag lift, refined deferred footer - Icon.tsx: dependency-free geometric icon set (emoji don't take a tint) - home: large title, Next-up card, "needs attention" rows, icon tab bar - Priority/Estimate/Date chips unified on the accent-soft active state Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
116 lines
3.2 KiB
TypeScript
116 lines
3.2 KiB
TypeScript
// Design tokens.
|
|
//
|
|
// The look is modelled on Things 3: a light, calm canvas, generous whitespace,
|
|
// hairline inset separators instead of boxes, and exactly one accent colour
|
|
// used sparingly. Everything visual in the app resolves through this file —
|
|
// no component hard-codes a hex value (priority flags are the one exception,
|
|
// and they live in `priority.ts` alongside their labels).
|
|
|
|
/** Named palette. `dark` is complete and ready to wire to a theme toggle. */
|
|
const light = {
|
|
/** Screen background behind grouped content. */
|
|
bg: "#F7F7F9",
|
|
/** Card / row surface that sits on `bg`. */
|
|
surface: "#FFFFFF",
|
|
/** Inputs, pressed states, subtle fills. */
|
|
surface2: "#EFEFF3",
|
|
/** Card outline. Deliberately barely-there. */
|
|
border: "#E6E6EB",
|
|
/** Inset hairline between rows inside a card. */
|
|
separator: "#ECECF0",
|
|
/** Primary reading colour. Near-black, never pure #000. */
|
|
text: "#16161A",
|
|
/** Supporting copy that should still be comfortably readable. */
|
|
textSecondary: "#6E6E76",
|
|
/** Metadata, placeholders, de-emphasised chrome. */
|
|
muted: "#9A9AA2",
|
|
accent: "#2F6FED",
|
|
/** Tinted accent wash for selected chips and active states. */
|
|
accentSoft: "#E8F0FE",
|
|
done: "#2FA36B",
|
|
danger: "#E5484D",
|
|
warn: "#D98324",
|
|
/** Text that sits on top of `accent`. */
|
|
onAccent: "#FFFFFF",
|
|
} as const;
|
|
|
|
const dark = {
|
|
bg: "#0C0C0F",
|
|
surface: "#17171B",
|
|
surface2: "#212127",
|
|
border: "#2A2A31",
|
|
separator: "#26262C",
|
|
text: "#F2F2F5",
|
|
textSecondary: "#A6A6B0",
|
|
muted: "#7A7A85",
|
|
accent: "#4C86F0",
|
|
accentSoft: "#1B2740",
|
|
done: "#3FBF84",
|
|
danger: "#F0605F",
|
|
warn: "#E0A93E",
|
|
onAccent: "#FFFFFF",
|
|
} as const;
|
|
|
|
export const PALETTES = { light, dark } as const;
|
|
|
|
/**
|
|
* Active palette. Styles are created at module scope (StyleSheet.create) so
|
|
* this is a static choice rather than a hook — switching themes at runtime
|
|
* would mean moving every stylesheet inside its component.
|
|
*/
|
|
export const C = light;
|
|
|
|
/** 4pt spacing grid. Screen gutter is `space.lg`. */
|
|
export const space = {
|
|
xs: 4,
|
|
sm: 8,
|
|
md: 12,
|
|
lg: 16,
|
|
xl: 20,
|
|
xxl: 28,
|
|
} as const;
|
|
|
|
export const radius = {
|
|
sm: 8,
|
|
md: 12,
|
|
/** Cards and grouped lists. */
|
|
lg: 16,
|
|
/** Chips and pills. */
|
|
pill: 999,
|
|
} as const;
|
|
|
|
/**
|
|
* Type scale. `title` is the large in-content screen heading that replaces a
|
|
* cramped nav-bar title; `row` is the task title size — 17pt, matching the
|
|
* platform body size Things and Todoist both settle on.
|
|
*/
|
|
export const type = {
|
|
title: { fontSize: 30, fontWeight: "700", letterSpacing: -0.6 },
|
|
section: { fontSize: 13, fontWeight: "600", letterSpacing: 0.3 },
|
|
row: { fontSize: 17, letterSpacing: -0.2 },
|
|
body: { fontSize: 15 },
|
|
meta: { fontSize: 13 },
|
|
chip: { fontSize: 14, fontWeight: "500" },
|
|
} as const;
|
|
|
|
/**
|
|
* Card elevation. Kept extremely soft — a Things-like surface reads as paper,
|
|
* not as a floating panel.
|
|
*/
|
|
export const shadow = {
|
|
card: {
|
|
shadowColor: "#0B0B12",
|
|
shadowOpacity: 0.05,
|
|
shadowRadius: 10,
|
|
shadowOffset: { width: 0, height: 2 },
|
|
elevation: 1,
|
|
},
|
|
fab: {
|
|
shadowColor: "#0B0B12",
|
|
shadowOpacity: 0.22,
|
|
shadowRadius: 14,
|
|
shadowOffset: { width: 0, height: 6 },
|
|
elevation: 6,
|
|
},
|
|
} as const;
|