This document defines the UI design language for OpenCRHTracker and replaces the earlier prompt-style draft. It is intended for:
- page design and refactor
- shared component design
- AI-assisted component generation
- visual consistency review
This document follows the current implementation in pages/auth.vue, pages/index.vue, pages/emu/[code].vue, components/lookup/*, components/ui/*, and assets/css/tailwind.css.
If a future implementation conflicts with this document, either:
- update the implementation to match this document, or
- update this document together with the implementation change
Do not introduce a parallel visual language.
The product should feel like a modern CRH information terminal:
- precise
- calm
- airy
- structured
- highly legible
This is not a flashy dashboard and not a consumer entertainment interface.
The overall tone is:
- light industrial
- data-oriented
- clean and spacious
- brand-aware but restrained
The UI should suggest railway operations, dispatch systems, and ticket-like information panels without becoming skeuomorphic.
The core expression of the system is:
- light blue-grey atmospheric background
- white or near-white information cards
- CRH blue as the single primary accent
- strong information hierarchy
- restrained motion
- large rounded geometry for panels and controls
The interface must always prioritize scanability over decoration. Users should be able to quickly identify:
- what to input
- what is the primary action
- what the current state is
- where the result appears
Use crh-blue as the primary accent across:
- buttons
- focus states
- accent bars
- highlighted codes
- active emphasis
Avoid introducing extra brand colors for parallel emphasis.
Most important content should live inside cards. Cards are the main visual container for:
- search
- forms
- result tables
- empty states
- supporting panels
Motion is allowed only when it improves orientation:
- page transition
- panel switch
- suggestion reveal
- sticky header collapse
- skeleton loading
Do not add decorative motion that does not help comprehension.
Desktop and mobile layouts are both first-class. A component is not complete until both are considered.
Use the following semantic palette:
| Token | Value | Usage |
|---|---|---|
crh-white |
#FFFFFF |
cards, elevated surfaces |
crh-blue |
#00529B |
primary action, active state, focus, accent |
crh-silver |
#A9AFB6 |
low-emphasis UI details |
crh-slate |
#F8FAFC |
page background |
crh-grey-dark |
#334155 |
headings, primary text |
status-running |
#10B981 |
success, active running state |
status-delayed |
#EF4444 |
error, danger, failed state |
Additional neutral values already used in the codebase such as slate-400, slate-500, and slate-600 are valid supporting colors for secondary text and borders.
- Use
crh-grey-darkfor most readable text. - Use muted slate tones for descriptions, labels, and supporting metadata.
- Use red only for error or failure.
- Use green only for success or running-state semantics.
- Do not use purple, neon gradients, or overly saturated secondary accents.
Primary fonts:
- sans-serif:
Inter,Source Han Sans SC,SF Pro Display,Segoe UI,PingFang SC,Microsoft YaHei UI,system-ui,sans-serif - mono:
JetBrains Mono,SFMono-Regular,Roboto Mono,Cascadia Mono,ui-monospace,monospace
Usage rules:
- page titles and card headings use sans-serif
- train codes, EMU codes, timestamps, and system-like values use mono where emphasis helps scanning
- eyebrow labels use uppercase with expanded tracking
- large text should be semibold rather than bold-heavy
- Chinese labels and helper headings should prefer medium before semibold
- eyebrow:
text-xs, uppercase, semibold, tracking around0.24em - 0.3em - section title:
text-2xl, semibold - large hero title:
text-2xltotext-3xl - body description:
text-smtotext-base, muted color, comfortable line-height - data values:
text-smwith mono when needed - helper and validation text:
text-xs
This system does not use sharp rectangles and does not rely on full pill geometry everywhere.
Preferred radius system:
- major card:
1.25rem - nested container:
1rem - button:
rounded-2xl - input:
1rem - chips and badges:
rounded-full
Do not force all inputs and buttons to rounded-full. The current product language uses large soft corners, not strict pills.
Shadows should stay soft and low-contrast. They should suggest elevation without heavy floating.
Preferred behavior:
- base card shadow is subtle
- hover shadow slightly increases depth
- strong shadows are reserved for overlays such as suggestion menus
Use light borders to define structure:
- regular cards and tables: subtle solid borders
- helper/status containers: dashed borders are allowed
- focus and active states should not rely on border alone; combine with glow or ring where appropriate
Preferred motion ranges:
- micro transitions:
180ms - 220ms - layout or panel transitions: up to
320ms - easing: mostly
ease-out
Use small movement only:
translateY(8px - 12px)translateX(6px)- opacity fade
Always keep prefers-reduced-motion compatibility for meaningful animated transitions.
Pages should not use a flat solid background alone. The base shell should combine:
- a very light page gradient
- a top radial glow
- optional soft horizontal glow layer
The effect must remain subtle and low-opacity.
Main content should be centered using a shared content width similar to max-w-7xl.
Common shell behavior:
- horizontally centered
- generous horizontal padding
- enough vertical breathing room
- consistent gap rhythm between sections
Pages should be built as min-h-screen vertical shells so the footer sits naturally at the bottom.
Use for focused tasks such as auth:
- vertically centered or near-centered main content
- one dominant action card
- minimal supporting content
Use for detail pages:
- left column for search or navigation
- right column for results
- on wide landscape screens, the left side can become sticky
The homepage supports a transitional split behavior on wider screens:
- initial state centers the hero search
- after submit, a preview panel can appear
- the user is then routed into full details
This behavior should remain lightweight and should not become a heavy multi-step wizard.
On smaller screens with enough scrollable content:
- the search card may become sticky
- the card may collapse into a denser form
- the result list should remain visually primary
This is an approved pattern for lookup pages.
Cards are the main structural unit. Every important block should feel like it belongs to the same family.
Common card properties:
- light background
- soft border
- large radius
- subtle shadow
- smooth hover shadow increase
Use for neutral content blocks.
Use for:
- hero search
- auth panel
- primary feature entry
Visual behavior:
- slightly richer background treatment
- more visual prominence
- allowed to carry accent atmosphere and richer gradients
Use for:
- secondary content
- mobile result cards
- quick links
- lightweight support panels
Accent bars are part of the system language. Use them to imply importance, identity, or active framing.
Rules:
- use a vertical blue accent bar on appropriate cards
- implement it as a refined inset treatment, not a crude default border
- do not place accent bars on every card
Typical card content structure:
- eyebrow
- title
- optional description
- divider
- main action or data
- optional supporting text
Preferred divider styles:
- a soft 1px border for dense structural separation
- a horizontal blue-tinted gradient divider for section emphasis
Do not overuse heavy separators.
All text inputs should follow the shared harmony-input language:
- white or near-white background
- soft border
- large radius
- subtle inset shadow
- clear blue focus ring
- text-entry controls should use at least
16pxfont size to avoid iOS Safari focus zoom
Focused inputs should:
- change border to blue
- slightly brighten background
- show a soft outer ring
- remain visually calm and precise
Avoid harsh native focus outlines unless needed as fallback.
Input errors should be communicated inline and locally:
- red border override where necessary
- concise helper text below input
- keep the layout stable
Labels should be visible in standard forms. In compact collapsed layouts, labels may be visually hidden if context remains obvious.
Default input density should feel spacious. Compact forms may reduce vertical padding slightly, but should preserve the same geometry and hierarchy.
The primary button is:
- blue gradient background
- white text
- medium emphasis shadow
- large rounded geometry
Use it for the main page action only.
The secondary button is:
- white background
- blue text
- subtle border
- light hover tint
Use for the lowest emphasis actions:
- transparent background
- blue text
- gentle hover background
Buttons should support:
- loading spinner inline
- disabled opacity reduction
- disabled pointer lock
Do not replace the button with a skeleton for standard action loading.
The lookup search card is the signature component of the product. It may include:
- eyebrow
- title
- description
- large input
- strong submit action
- optional type hinting
- suggestions dropdown
The hero lookup card may use:
- richer gradients than ordinary cards
- subtle image-backed atmosphere
- masked overlays for readability
This treatment is allowed only on the primary search card and should remain restrained.
The suggestion dropdown should feel elevated but attached:
- rounded corners
- clear border
- stronger shadow than base cards
- soft blur is acceptable
- active item uses blue-tinted highlight
Suggestion items may contain:
- code
- subtitle
- tags
The code is the strongest datum. Tags should stay lightweight and compact.
Desktop result tables should be:
- horizontally stable
- lightly bordered
- minimal vertical noise
- generously padded
- visually readable at a glance
Header rules:
- muted text
- smaller size than body data
- uppercase when appropriate
Hover should gently tint the row background. The effect should support scanning, not dominate the table.
The same dataset should be re-expressed on mobile as cards rather than forcing a compressed table.
Mobile result cards should:
- preserve date and code prominence
- present route information in paired blocks
- preserve time data with mono styling
Active or running records may receive stronger highlight styling:
- slightly richer blue-cyan surface
- more pronounced border
- subtle visual distinction from standard records
This is an approved exception to the otherwise restrained palette.
Prefer skeleton loading for structured result areas.
Loading indicators should:
- keep the future layout recognizable
- avoid jumpy reflow
- feel lightweight
Empty states should be shown inside the same content surface rather than replacing the entire page shell.
They should include:
- small eyebrow
- clear title
- short explanation
Errors should be specific and local when possible:
- inline validation for form issues
- card-contained error states for result failures
- local retry action when additional data can be fetched again
Success should be calm and brief. Use green sparingly and avoid celebratory visuals.
The design is not just scaled down desktop UI. Components may change structure between desktop and mobile.
Allowed transformations include:
- two-column to one-column layout
- sticky search module
- collapsed search header
- table to stacked card conversion
- shorter descriptions on compact surfaces
When screen space becomes limited, preserve in this order:
- primary action
- user input
- result identity
- key timestamps and station data
- secondary description
Use motion for:
- route/page transition
- auth mode switch
- preview reveal
- sticky header collapse
- suggestion menu appearance
Motion should feel:
- quick
- smooth
- subtle
- non-bouncy
Avoid spring-heavy or playful animation styles.
Whenever a custom transition is introduced, provide a reduced-motion fallback that removes spatial movement where possible.
Eyebrows should be short, categorical, and scannable, such as:
ACCESSOpenCRHTrackerRECENT RECORDSQuick Lookup
Product copy should be:
- concise
- operational
- informative
- non-promotional
When layout becomes tight, preserve concrete data before descriptive prose.
- use large, soft-rounded cards
- keep backgrounds bright and airy
- use CRH blue as the primary emphasis color
- use mono for train codes and times where it improves scanning
- design mobile layouts intentionally
- keep visual density controlled
- use local states instead of global intrusive overlays
- do not introduce a second strong brand color
- do not switch to dark mode styling by default for new pages
- do not use flat pure-white-on-pure-white layouts without atmospheric depth
- do not replace the card system with bare panels or generic admin tables
- do not use overly sharp corners
- do not use oversized shadows or glassmorphism-heavy effects
- do not force all controls into pill shape if the existing system uses rounded rectangles
- do not add decorative motion that slows task completion
When implementing new UI in this project:
- prefer existing shared components first
- prefer existing design tokens and utility classes
- extend
UiCard,UiButton, and shared lookup patterns before inventing new primitives - keep new pages visually compatible with
auth,index, and lookup detail pages
If a new visual pattern is necessary, add it deliberately and update this document in the same change.