Skip to content

UI Foundation

  • Status: STABLE TECHNICAL STANDARD
  • Packages: @ctc/design-tokens, @ctc/ui
  • Density: FIXED_COMPACT
  • Restriction delta: RD-000 / NONE
  • Visual direction: DESIGN.md owns approved visual replacements and remaining Legacy continuity
  • Legacy continuity contract: PHASE_3_LEGACY_FAITHFUL
  • Phase-3 visual evidence: VISUAL_PARITY_MANIFEST.json
  • Secondary reference: B+ operational UI reference

Portal Boundary

Per ADR 0023, PortalKind is Office/Mobile/Deferred via exact-screen classification; no device or user flag participates.

Phase-3 Visual Authority And B+ Fallback

DESIGN.md is the sole current visual-decision owner. Its Sections 11, 12.1 and 12.2 separate approved popup/table appearance from Legacy field, action, data and recovery continuity. Approved shared popup and collection recipes take precedence over older appearance descriptions in this technical standard. Inbound/Outbound lists and ordinary popups are the two reference surfaces; Booking/Transload specialized popup composition is not the generic form template. DESIGN 12.3 binds all current/future consumers: remove local visual overrides and use the shared selection action with Edit (count), without a separate selected-count label. Only explicit user direction grants a visual exception. DESIGN Section 11 is the current cohort boundary: CTC restores Legacy business columns/action placement/process; Client 2 preserves its current New-System UI/process and is not a CTC Legacy reconstruction target. Common toolbar defaults yield to that business composition; shared spacing/control sizes remain common. Cohorts do not authorize client-ID code forks.

Review uses the same operator role, representative data or disposable fixture, viewport and state. Compare appearance to the applicable approved visual target and behavior to its executable contract. B+ references and UI Catalog examples fill only gaps not covered by either authority. Do not copy mockup sample values, invent business rules or change an approved design during structural cleanup.

The shared B+ contract remains a fallback for net-new surfaces and unresolved Legacy gaps:

  • stable dark shell and light neutral Office work surfaces;
  • compact, full-width operational tables and forms as the primary canvas;
  • one dominant work hierarchy with contextual inspector, exceptions and related state;
  • restrained one-pixel borders, quiet surface steps and bounded elevation;
  • contemporary sans hierarchy, readable compact weights and tabular operational numbers;
  • H/Cobalt and K/Indigo vary semantic colors only;
  • no sample/profile/density selectors, explanatory subtext or page-local visual system;
  • reference images supply composition and quality direction only. Pictured fields, statuses, actions and data require their own Process/page authority.

Visual Authority And Token Layers

The ownership chain is singular:

@ctc/design-tokens
-> @ctc/ui/surfaces
-> @ctc/ui shared components and interaction patterns
-> App Shell / Product module composition
-> approved non-KJ third-party control adapter where needed

@ctc/design-tokens owns literal values. @ctc/ui/surfaces owns application-wide page canvas, structural kind and scrolling. Shared components own visual and interaction semantics. Product modules own records, labels, commands, validation, permissions and data flow.

Booking is one consumer and, where selected by DESIGN.md, an approved appearance reference. It is not the owner of shared component behavior. No shared export may encode Booking, Purchase, Inventory, Sales, tenant, client or profile business rules.

The token contract has three layers:

Layer Purpose Examples
Primitive Literal palette and numeric scale --ctc-slate-200, --ctc-space-3
Semantic Product role independent of module or theme --ctc-bg-surface, --ctc-action-primary, --ctc-border-default
Component Reusable geometry and chrome --ctc-context-bar-height, --ctc-selection-column-width, --ctc-dialog-header-height

Theme scopes replace semantic colors only. Primitive values are private inputs and component geometry is theme-invariant. Existing --ctc-color-* and Web aliases are transitional compatibility inputs; new code consumes semantic or component roles. An alias name does not authorize KJ runtime reuse. Remove obsolete aliases only after checking actual consumers and fallback dependencies.

Semantic color roles

Category Roles Rule
Surface canvas, surface, muted, inset, hover, strong Nested work areas step through shared surfaces
Foreground default, subtle, muted, disabled, on-strong, link Text follows information hierarchy
Border muted, default, strong, focus Boundaries strengthen only for structure or interaction
Action primary, hover, active, soft, danger Primary color is reserved for action and selection
Status info, success, warning, danger plus soft surfaces Status color is not decoration
Selection background and accent Tables, chips and selected controls use one language
Shell background, hover, control, foreground and border Structural chrome remains separate from Product surfaces
Control/Table/Dialog semantic aliases Components resolve appearance without reading module identity

Application Surface Taxonomy

@ctc/ui/surfaces defines the root contract for every Product page.

Kind Intended structure Consumer / template example (not acceptance proof)
collection searchable, filterable or pageable records Booking List
record create, edit, read or account-style forms Account and Entity Workspace template
dashboard metrics, queues, exceptions and summaries Operating Home template
planning schedules, assignments and board-like work Planner / Board template
tabbed administration and settings Admin template
split master/detail or main/inspector composition List / Detail template
field focused operator execution Field Task template

A surface kind controls canvas and scrolling only. It does not select fields, actions, data source, permissions, save behavior, tenant behavior or workflow. New modules select the nearest existing kind; a new kind requires a genuinely different structural contract and an immediate Product consumer.

Expected composition guide:

Product area Primary kinds
MK purchase and sales collection + record
Inventory and allocation collection + split
Cost, rate and settlement collection + record
CTC assignment and execution planning + field
Yard, scale and trucking planning + collection + field
Management and exception views dashboard + split
Administration and settings tabbed + record

This is a composition guide, not authorization to invent unused screens or business rules.

Legacy-Informed Continuity — Legacy-Faithful Phase-3 Continuity

Phase 3 preserves the approved operator workflow while replacing its technical implementation. Executable Legacy supplies unreconciled fields, actions, data, recovery and the visual baseline for surfaces without an approved replacement. DESIGN.md owns approved popup/table appearance changes. Legacy DOM ownership, public numeric identity and direct SQL/API coupling are technical evidence, not target architecture.

Source precedence

It follows the CTC/Client 2 comparison baseline of DESIGN §11 and the document authority rules. Retained items and measured values are recorded in review form §4–6. Columns, behaviour, selection, required values, state and recovery are compared against the applicable business contract, and colour, spacing, font and control appearance against the approved shared baseline in DESIGN. It is written after confirming the real targets and baseline of the existing Task. React ownership, typed contracts, public UUIDs and shared component reuse are internal implementation changes. Accessibility and responsive changes preserve content and task reachability. A business change or an unapproved appearance change is confirmed with the existing decision owner. UI_CONTINUITY_REVIEW_TEMPLATE.md exists to record a comparison and is not a separate design standard. Only the real review scope is written there, in the existing Task or the relevant evidence document. Operational results are preserved from LEGACY_PARITY_MANIFEST.json and visual results from VISUAL_PARITY_MANIFEST.json, with their existing data and consumers. The former Booking comparison table is evidence from the scope it covered and does not replace the current shared UI rules.

Each observed item receives one disposition:

Disposition Meaning
PRESERVE retain the visible operator result, including meaning, order, density and treatment
MODERNIZE replace implementation while minimizing visible change
ACCESSIBILITY_EXCEPTION make the smallest visible change required for accessible operation and record it
RESPONSIVE_EXCEPTION adapt only the supported narrow viewport while preserving content and action reachability
REPLACE replace an obsolete technical owner while preserving the approved visible outcome
RETIRE remove only with explicit Product-owner evidence that the behavior is superseded
DEFER do not implement, remove or visually reinterpret until the conflict is resolved

What remains familiar in Phase 3

What may change without becoming a redesign

Page-Local CSS Boundary

Feature CSS may define responsive composition, domain column widths, business-specific visibility and bounded placement. It may not introduce:

  • another palette, spacing scale, radius or control metric;
  • another button, form, dialog, table, selection, filter, pagination or status system;
  • shared selectors containing a module, tenant, client or profile name;
  • raw visual values outside @ctc/design-tokens or an approved compatibility adapter.

A new visual role is added to @ctc/design-tokens first and consumed through @ctc/ui in the same bounded slice. Media and container query thresholds are the only numeric values retained outside the token package because custom properties cannot govern query conditions.

packages/ui/src/styles.css owns the shared import order only. Its current order is Tom Select's vendor baseline, ui.css, contract.css, data-display.css, surfaces.css, operations.css, and field-task.css. Preserve that order until the exact cascade migration has been verified.

File Responsibility Cleanup boundary
packages/design-tokens/src/styles.css shared literal/semantic values and theme inputs reuse existing roles; preserve approved exceptions
packages/ui/src/styles.css shared stylesheet composition no selectors, business rules or page imports
packages/ui/src/ui.css residual base mechanics not owned elsewhere remove superseded declarations incrementally; do not delete unique controls or vendor adaptations
packages/ui/src/contract.css shared primitive/dialog/form invariants and approved shared recipes no page-specific geometry or tenant policy
packages/ui/src/data-display.css semantic column alignment and value presentation no duplicate toolbar, paging or domain rules
packages/ui/src/surfaces.css Product surface canvas, structural kinds and scrolling no domain fields or save behavior
packages/ui/src/operations.css reusable collection/record pattern composition do not redefine primitive declarations already owned by the contract
packages/ui/src/field-task.css reusable field-task layout and controls no individual yard/scale workflow policy
apps/web/app/globals.css reset, shell and bounded compatibility migrate feature blocks with their consumers; retain approved login appearance
apps/web/src/composition/operational-pages.css temporary mixed feature styles still imported today move each live block to its real feature owner; delete only after migration
owner-local *.module.css one screen's unique geometry and responsive composition no parallel button/form/table/dialog visual system

For a shared selector/property under the same cascade conditions, name one declaration owner. Different states, media/supports conditions, layers, vendor fallbacks and intentional variants are not duplicates merely because their selectors overlap. A consolidation must remove the superseded declaration rather than add a later override. Compare Web and UI Catalog, theme variants, desktop/ narrow layouts, focus, disabled/error states, nested dialogs and print output when applicable. Use the existing Task to record source -> target and checks; this table does not assert migration is complete or authorize a wholesale stylesheet deletion.

Every component retains its base ctc-* class when a consumer adds a layout modifier.

Motion Contract

Token Duration Shared use
micro 80ms press, toggle and icon acknowledgement
fast 120ms hover and row affordance
state 160ms selection, tab, filter and live-value acknowledgement
standard 220ms inspector and bounded layout transition
enter 260ms modal, panel and command-surface entrance
emphasis 320ms rare completion or exception acknowledgement

Motion never implies success before authoritative readback, blocks frequent commands, reorders dense rows without an explicit contract or becomes the only status signal. Reduced-motion mode removes spatial movement and continuous effects while preserving focus, announcements, information and actions.

Fixed Metrics

Read current metric values from @ctc/design-tokens and the approved recipes in DESIGN.md. This technical standard does not maintain a second numeric snapshot of font sizes, row heights, section gaps or corner radii. Shared geometry remains theme-invariant unless the current approved contract explicitly says otherwise. A historical metric must not override an approved popup/table recipe. Keep any required compatibility exception bounded and documented in its existing owner.

Public Contracts

@ctc/design-tokens exports compact metrics and styles.css.

@ctc/ui exports:

primitives    Button, IconButton and variants
feedback      StatusBadge, InlineNotice, StateNotice and SaveState
forms         text/select/textarea, checkbox, autocomplete, temporal and file controls
data-display  DataTable, semantic column kinds, CompactTable, Queue and Timeline
layout        PageHeader, Panel and PageFrame
surfaces      ProductSurface and structural kinds
operations    command, context, pagination and record-workspace patterns
overlays      Dialog and WorkspaceDialog
patterns      executable surface templates
icons         approved Lucide icons with named imports and currentColor

New date, date-time and time controls must use the shared TemporalInput owner rather than a raw native input, preserving the native ISO value while fixing the visible English presentation.

New navigation and shared-action icons must use the bounded @ctc/ui/icons export, named imports, the shared icon-size tokens and currentColor; do not add page-local icon libraries or literal SVG variants. The shared card elevation is 0 4px 12px rgb(15 23 42 / 12%); the login hero keeps its stronger direct shadow as an intentional composition exception.

User-facing copy is English and has no descriptive subtext by default. Required fields use * plus accessible required semantics. Operational error/recovery text appears only when the corresponding state exists.

Collection And Table Contract

A collection uses only the commands required by its workflow. A collection without dates does not render a date command; a non-paged collection does not render pagination.

DataTableColumnKind expresses domain-neutral column meaning:

identifier  text  relation  date  datetime  time  boolean  status
number      quantity  weight  currency  percentage  usage  actions

The shared table derives default alignment and tabular-number treatment from the kind while retaining an explicit alignment override. A module still owns labels, order, visibility, values, sorting, filtering and permissions. Preserve the applicable column meaning, ordering, visibility and operational behavior under DESIGN.md Section 11. Apply Section 12.2 for shared table appearance; remaining visual exceptions use the established comparison contract. Shared tokens and components own the implementation.

DataTable always retains ctc-table and ctc-table-wrap. Consumer classes add layout without replacing the shared owner. Header, row, selection, hover, focus and selected state remain common.

Use the approved shared collection recipe through existing CollectionToolbar, DataTable and pagination owners. Preserve each screen's real commands, filters, columns and selection scope; never add nonfunctional mockup actions or page-local copies of the shared toolbar.

Record And Popup Contract

A record page or popup preserves proven field-group order, defaults, dependencies, related child flows and command hierarchy. Popup appearance follows DESIGN.md Section 12.1 through the existing Dialog/WorkspaceDialog recipe, not an obsolete Legacy color/spacing rule. Retain actual business cancellation commands; remove only close-only Cancel actions in the owning composition.

An action is disabled and shows pending feedback only for its own in-flight command. Opening a follow-up popup clears the originating action's pending state; it does not establish that the follow-up business command completed. Closing a popup remains distinct from business cancellation.

The existing shared components provide this composition without creating another form engine:

ProductSurface kind="record" or WorkspaceDialog
-> identity / title
-> optional status flags, tabs or notice
-> SummaryCard + SummaryGrid when read-first identity is needed
-> CollapsibleSection
   -> FormSection in reconciled operator scan order
-> DocumentPreview or related region when applicable
-> fixed command footer for modal work

WorkspaceDialog owns title bar, focus/close behavior, optional tabs, scrolling body and fixed footer. Business modules supply fields, labels, validation, commands and child workflows. Technical screen IDs are not user-facing titles. Opening, saving, conflict recovery, unknown-result readback and nested child close behavior are verified separately; a screenshot cannot establish those contracts.

The shared Dialog reuses the existing 1180px workspace width as size="workspace", alongside default760/wide960. Company selects this preset. Shared form-table styling in @ctc/ui uses the Create Inbound Purchase Line item reference for Dialog, native form, and record surfaces, including retained ctc-table-core markup; ordinary list and print-template geometry remain separate. See DESIGN12.3.

Operational Pattern Library

@ctc/ui/operations is one reusable interaction-pattern family inside the wider system. It is not the application root and it is not a Booking toolkit.

Collection components include CommandBar, CommandGroup, DateRangeCommand, FilterToggle, PageSizeSelect, SelectionBar, ActiveFilterBar, FilterChip, TableLink, ActionMenu and PaginationBar.

Record components include CollapsibleSection, FormSection, SummaryCard, SummaryGrid, SummaryItem, DocumentPreview and CommandGroup.

Dashboard, planning, tabbed, split and field surfaces reuse shared primitives and regions. They do not inherit collection pagination or record form anatomy unless the actual workflow requires it.

Workspace Tabs And Split Layout

Each open shell tab is an independent page instance. Page-local filters, selection, scroll and draft UI state use the tab instance identity and must not leak across duplicate tabs. The shell retains one tab bar. Each tab may own collection, record, dashboard, planning, tabbed, split or field content.

Dragging pages into split content, extracting them back to the top bar, keyboard movement, renamed tabs, shortcuts and user-local saved pages remain shell contracts. Surface kind does not change route, permission, record or save ownership.

Current Consumers

  • Booking uses the collection surface plus shared collection commands, contextual bars and DataTable.
  • Booking Workspace uses the shared dialog, field, summary, disclosure, form-section and document-preview components while preserving the reconciled Legacy cognitive order for its current typed subset.
  • Account uses the record surface plus shared form controls.
  • executable templates cover dashboard, record, split, planning, field and tabbed surfaces.
  • Administration and later MK/CTC pages adopt the same contracts as their bounded operator slices run.
  • Administration and UI Catalog also use Native shared controls; KJ runtime reuse is prohibited.

No current consumer may redefine the shared visual system for later modules.

Legacy Modernization Reuse Matrix

Legacy is a behavior/comparison source, not a New-System runtime dependency.

Legacy capability New-System implementation owner
table lifecycle, filters, sorting, paging, selection and keyboard existing Native @ctc/ui/data-display and @ctc/ui/operations
modal focus, close and confirmation existing @ctc/ui/overlays lifecycle and caller-owned business actions
forms, autocomplete and choices existing shared forms and approved Tom Select adapter
CRUD, related records and Booking editor existing page composition and registered command/query owners
uploads, photos and previews existing file/provider adapters plus shared Native controls and domain relation owners

Do not import, copy, dynamically load, wrap, iframe or revive KJTable, KJModal, KJView or LegacyKjView in Web or UI Catalog. Unrelated root Legacy assets are not deletion targets of this New-System rule. Numeric DB compatibility, historical route aliases, licensed non-KJ controls and runtime-generated third-party classes require their own consumer analysis; their names alone do not make them obsolete. Remove a retired implementation only after replacement preserves the real flow.

Copy And Field Contract

This section is the current shared owner for the former copy/field standard. Product surfaces use English labels and no default explanatory subtext. Secondary text is limited to validation, error or recovery, safety, current status, disambiguation, accessibility, explicit user requests or an approved page contract.

  • Required fields use an adjacent * (or equivalent compact mark), aria-required="true" and screen-reader text; requiredness comes from the Process/page contract.
  • TemporalField is the shared Date/Time family. Date and time segments share one border, focus, error, readonly and disabled contract; page code does not select another visual system.
  • AppointmentField is the status-aware DatePicker plus TimeBlockPicker composition and exposes block status, capacity, selectability and blocking reason.
  • Theme changes replace semantic colors only. File and photo attachments keep explicit ownership, ordering and grouped-lightbox behavior from the approved Process/page contract.
  • Autocomplete uses concise labels and only operationally necessary disambiguation; it never adds generic helper prose or business rules to shared components.

The initial copy/field direction evidence and initial UI direction evidence remain historical references while their decision rationale is preserved in the linked ADRs.

Validation

  • scripts/tests/architecture/ui-foundation.test.mjs checks token layers, surface taxonomy, semantic column kinds, stylesheet ownership, continuity documentation and domain-neutral shared source/CSS.
  • scripts/tests/architecture/booking-table-composition.test.mjs protects Booking list behavior, exact column continuity and the current popup group order without making Booking the shared UI authority.
  • scripts/tests/architecture/phase3-visual-parity-authority.test.mjs must protect the applicable approved visual target, Legacy behavior continuity, evidence fields and completion boundary. Reconcile any obsolete expectation with DESIGN.md; never weaken a runtime/visual assertion simply to pass cleanup.
  • scripts/quality/phase3-visual-parity.mjs reports the independent visual-parity axis and blocks a strict/final claim while registered pages remain unverified.

  • Visual acceptance links the applied baseline, the identical role, data, viewport and state, both revisions, desktop and narrow captures, an independent review, the comparison result and any approved exception in the review form. The CTC/Client 2 baseline is DESIGN §11.

  • focused Product tests verify each module's actual business behavior separately and do not prove visual parity.

  • Source Registry ID: source.new-system.ui-foundation.

Source: new-system/docs/architecture/UI_FOUNDATION.md — ctc repository · This page is an English translation of the source document. Identifiers, file paths and code symbols are unchanged. A user instruction quoted inside the text is kept in its original language.