Primary wordmark
Taskktaskk-logo.svgThe canonical visual, interaction and implementation reference for a calm, compact and deliberately premium workspace.
The supplied vector artwork is canonical. The colour artwork belongs on light surfaces; the white artwork belongs on dark surfaces.
Primary wordmark
Taskktaskk-logo.svgInverse wordmark
Taskktaskk-logo-white.svgApp icon
taskk-app-icon.svgFavicon
favicon.svgOpaque OKLCH role tokens keep hierarchy stable across themes. Pure white, fine grey rules and near-black actions do the structural work; blue and warm signals communicate focus or status.
light theme
--color-paperoklch(100% 0 0)--color-paper-2oklch(98.4% 0.002 255)--color-surfaceoklch(100% 0 0)--color-inkoklch(14.5% 0.004 260)--color-ink-2oklch(38% 0.008 254)--color-ruleoklch(90.8% 0.004 254)--color-accentoklch(18% 0.006 260)--color-focusoklch(63.35% 0.122 253.18)dark theme
--color-paperoklch(11.5% 0.012 270)--color-paper-2oklch(16% 0.014 270)--color-surfaceoklch(18.5% 0.015 270)--color-inkoklch(96% 0.004 85)--color-ink-2oklch(76% 0.007 270)--color-ruleoklch(27.5% 0.012 270)--color-accentoklch(68% 0.19 264)--color-focusoklch(72% 0.16 264)--color-success-strong--color-warning-strong--color-danger-strong--color-work-strongSemantic colour is always paired with an icon or text. Use the matching -soft surface and -border token; never tint a whole page.
Inter carries every live interface role through one semantic scale. Geist Mono is reserved for scores, dates and inspectable data; tabular figures prevent metrics from shifting.
--type-display-size--type-page-title-size--type-section-heading-sizeShape the commitment, timing and context before deciding what comes next.
--type-body-size--type-label-size--type-caption-sizefont-variant-numeric: tabular-numsLabels name the field. Placeholder text is an example, not the label.
Buttons name one action on one line. Prefer “Save task” to “Submit”, and keep supporting copy outside the control.
Errors explain recovery. Say what failed, what was saved, and what to do next.
A four-point scale, an 82rem work surface and deliberate separators create density without crowding. Mobile is a first-class layout, not a compressed desktop.
3xs0.25rem--space-3xs2xs0.5rem--space-2xsxs0.75rem--space-xssm1rem--space-smmd1.5rem--space-mdlg2rem--space-lgxl3rem--space-xl2xl4.5rem--space-2xl3xl7rem--space-3xlContent
48remLong-form copy, legal and focused reading.
Workspace
82remTask planning, settings and analytics.
Control
44pxMinimum touch height for buttons and fields.
| Viewport | Layout rule | QA check |
|---|---|---|
| 320–414px | One column, mobile rail, reduced task metadata | No horizontal scroll; actions stay 44px and labels stay on one line |
| 768px | Tablet grid; compact navigation | Button, tab and menu labels do not wrap or clip |
| 900px | Desktop rail begins | Reading order matches visual order |
| 1440px | 82rem maximum work surface | Whitespace grows; content does not over-stretch |
One-pixel rules organise content. Radius follows function, and shadow is reserved for content that genuinely floats above the workspace.
--radius-control · 0.375rem--radius-card · 0.5rem--radius-panel · 0.625rem1px rule, no shadow--shadow-card--shadow-previewDo not nest bordered cards. Group related rows inside one surface and separate them with neutral rules. Cards, controls, callouts, banners and email sections never use accent, gradient, glow or coloured single-edge borders for emphasis. Focus, validation, selection and compact status indicators remain the functional exceptions.
These specimens render production primitives and expose their labels, states and implementation hooks for visual QA.
components/ui/button.tsxPrimary actions are specific and scarce. Every conventional control keeps one concise label on one line; supporting copy sits outside it. Loading buttons keep their label, remain disabled and expose the ongoing action in text.
components/uiPersistent label, 44px target and a shared text inset.
Addons describe units without becoming editable text.
The native control owns keyboard, screen-reader and mobile-picker behaviour.
The error stays beside its field and does not change control geometry.
Longer context starts with a label and a useful character or privacy note.
text + icon + colourcomponents/task-plan-table.tsxSorted by recommended order, ascending.
| 01 | Review the project briefDo first · Impact 5 · Fixed | 5 | 45 min | 26 July 2026Fixed | 86 |
|---|---|---|---|---|---|
| 02 | Prepare the next-step noteSchedule · Impact 4 | 3 | 30 min | 29 July 2026 | 66 |
| 03 | Book the annual appointmentSchedule · Impact 3 | 2 | 10 min | No date | 43 |
Headers remain keyboard-sortable, the rank stays stable, and lower-priority columns progressively hide instead of forcing horizontal scroll. Full task records extend this contract with labelled search and select filters, a compact two-up planning cell, and edit or delete actions on the lower row.
interactive QANavigation
Selection stays visible, Arrow keys move focus, and each trigger names the panel it controls.
The selected state and its result remain clear without colour alone.
Overlay
A native modal dialog owns focus, closes with Escape, and returns focus to the trigger.
Icon labels
Prefer icon plus text. Icon-only controls need a persistent accessible name and a familiar symbol.
Motion
Use opacity and transform with the shared easing. Reduced motion keeps the content and removes travel.
/app/goalsThe pattern pairs a readable outcome with a deterministic rule and observable evidence. The next action is reviewable text, never an automatic instruction.
Charts answer a decision in under three seconds. Every visual keeps a plain-language heading, direct values and an accessible data table or progress label.
Momentum
8 completed in the last 14 days, 8 more than the previous 14 days.
Completion timing uses the latest update on tasks currently marked done.
Workload
Use a doughnut only for a small proportion set.
Comparison
Horizontal bars keep labels and values direct.
AreaChange over time; 7, 14 or 30-day windows.
BarRanked comparison with direct values.
DoughnutThree to five parts of a whole.
ProgressOne bounded completion measure.
A state is part of the component contract. Loading preserves shape, empty states explain the next useful action, and errors say what happened without exposing provider detail.
Loading
Announce the operation once. Reduced motion makes the indicator static.
Empty
Capture the next commitment, or check another view.
Error
Nothing was changed. Check your connection and try again.
Support reference: DS-1042Request IDs are safe to share. Provider payloads, user IDs and task content are not.
Calculating planning health…
Add detail to active tasks to begin measuring planning health.
We couldn’t display planning health. Your task data is still safe.
Motion confirms state and preserves orientation. It never delays access to content or turns routine work into theatre.
--dur-micro--dur-hover--dur-short / medium--dur-reveal--dur-mockupcubic-bezier(0.22, 1, 0.36, 1).Accessibility is implemented with the component, tested at its boundaries and visible in this reference—not deferred to a final audit.
Body copy reaches 4.5:1; large text and essential graphics reach 3:1 in both themes.
Every field and icon control has a persistent, programmatic name. Placeholder text never stands alone.
Keyboard focus is never removed. The shared three-pixel ring uses --color-focus.
Native controls come first. Custom widgets document Arrow, Escape, Enter and Space behaviour.
Colour is supplemented by text, icon, aria-invalid, aria-live or native state.
Content remains complete with prefers-reduced-motion: reduce; motion falls back to ≤100ms opacity.
Design decisions become durable only when the token, component, documentation and QA reference change together.
| Concern | Source | Rule |
|---|---|---|
| Visual tokens | tokens.css | Production values; light and dark remap by role. |
| Design rationale | design.md | Update with any material system change. |
| Primitives | components/ui/* | Expose semantic state through props and data attributes. |
| Application patterns | components/* | Compose primitives; avoid route-specific copies. |
| Motion | lib/motion.ts | Reuse shared variants and reduced-motion behaviour. |
| Visual QA | app/design | Add the real component and all applicable states. |
Prefer button, link, input, select, table and dialog before adding behaviour.
No route-local colour, radius or spacing values when a role token exists.
Use native attributes plus stable data-slot and data-state hooks.
Include default, hover, focus, disabled, loading, empty, error and success where relevant.
Check 320, 375, 414, 768, 900 and 1440px, keyboard flow and reduced motion.
A shared component is not complete until its public API, visible states, keyboard behaviour, responsive rules and failure recovery are represented here.