Commit d3bbbf7
feat: integrate Nexus Kinetic Light design system from Stitch (#84)
* feat: integrate Nexus Kinetic Light design system from Stitch (closes #83)
Establishes a CSS variable bridge so the Stitch design tokens become the
single source of truth for both Angular Material M3 and Tailwind utilities.
Changes:
- Add apps/web-app/src/styles/_tokens.css with all --md-sys-color-* tokens
for light and dark modes (Nexus Kinetic palette from Stitch)
- Update material.scss to use use-system-variables: true so Material
components read colors from the token layer; update typography to
Manrope (brand) + Inter (plain); remove hardcoded rgb() overrides
- Extend Tailwind @theme in styles.css to map token vars to semantic
utility classes (bg-primary, text-on-surface, bg-surface-container, etc.)
- Update index.html: load Manrope + Inter fonts; update theme-color
meta tags to match Nexus Kinetic surface values
- Migrate components from hardcoded neutrals to semantic token classes:
bg-white/95 dark:bg-neutral-700 -> bg-surface-container
bg-white dark:bg-neutral-800 -> bg-surface-container-low
dark:text-neutral-100 -> text-on-surface
text-neutral-500 -> text-on-surface-variant
border-neutral-200 dark:border-neutral-600 -> border-outline-variant
bg-blue-500 / border-l-blue-500 -> bg-primary / border-l-primary
text-sky-300 (dark links) -> text-primary
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: dark mode text color and add theme toggle
- Add color/background-color to html in @layer base so body
text is always readable (was defaulting to browser black)
- Update _tokens.css: dark tokens respond to both OS preference
(prefers-color-scheme) and html[data-theme=dark] attribute
- Override Tailwind dark: variant via @custom-variant so utility
classes respect both system preference and manual data-theme
- Create ThemeService (light/dark/system, persists to localStorage)
- Add theme toggle button to MainToolbar (cycles system/light/dark)
- Migrate remaining dark: utility classes in home, login,
forecast-table to semantic token classes
- Update markdown media queries to use dark: variant
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: apply dark Material theme for correct button contrast
- Add dark-type Material theme applied via @media and data-theme
so state-layer opacities, ripple colors and overlay colors are
all computed for dark backgrounds (fixes washed-out buttons)
- Fix light mode outline: #858d91 → #737c7f (more contrast,
matches Stitch exactly)
- Fix light mode outline-variant: #c2cbcf → #abb3b7 (matches
Stitch design token values)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: bridge --mat-sys-* to --md-sys-color-* tokens; use mat-flat-button
Angular Material sets --mat-sys-on-surface to 'initial' when
use-system-variables: true is set, but never maps those variables
to actual values. Add a :root block (specificity 0,1,0 > html's 0,0,1)
that bridges all 26 --mat-sys-* variables used by Material components
to the corresponding --md-sys-color-* tokens from _tokens.css.
Since _tokens.css already switches between light/dark values via
@media and [data-theme] selectors, a single :root mapping handles
both themes automatically — no duplication needed.
Also migrate the login button from the M2 mat-raised-button to
mat-flat-button (the M3 equivalent of a filled/primary CTA button).
mat-raised-button maps to an elevated (shadowed) button in M3,
not a filled one.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: correct surface container hierarchy for light/dark modes
In MD3, light-mode containers get DARKER as level increases
(lowest=#fff, highest=#dbe4e7 on #f8f9fa background). Using
bg-surface-container for cards made them darker than the page
background — the 'backwards' appearance reported by the user.
Changes per Stitch design reference:
- Toolbar: surface-container-high → surface
(light #f8f9fa near-white / dark #131313 matches design)
- Sidenav: surface → surface-container-lowest
(light #ffffff / dark #0e0e0e — darker sidebar matches Stitch)
- Content cards: bg-surface-container → lowest + dark:surface-container
(light #ffffff lifts above bg / dark #201f1f correct MD3 lift)
- Page sub-toolbars: surface-container → low + dark:surface-container
- Loading skeletons: surface-container-high → low + dark:high
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: hide toolbar on login page via LayoutStore.hideToolbar flag
- Add hideToolbar state + setHideToolbar() method to LayoutStore
- Login component sets hideToolbar=true on init, clears on destroy
- app.ts conditionally renders toolbar and adjusts sidenav margin
- Login page restyled: full-screen centered single-column card
matching Nexus Kinetic DS tokens (bg-surface-container-low,
on-surface, on-surface-variant, rounded-2xl, design-system shadow)
- Remove PageContainer/PageToolbar from Login (no longer needed)
- Update integration test to reflect new login page structure
- Add LayoutStore hideToolbar unit test
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: login page vertical centering and custom input styling
- Host changed to h-full block so inner div can be h-full and
flex-center vertically
- Replace mat-form-field/mat-label/matInput with custom label+input
pairs styled to match Nexus Kinetic DS: static label above,
bg-surface-container-lowest pill inputs, subtle border,
primary focus ring, no floating labels, no uppercase
- Remove unused OnInit, MatFormField, MatLabel, MatInput imports
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: remove input borders and add password visibility toggle on login
- Remove border from inputs; rely on bg contrast + focus ring only
- Focus ring changed to focus:ring-2 focus:ring-primary/60 for clarity
- Add showPassword signal and mat-icon-button toggle on password field
- Imports: add MatIconButton, MatIcon, signal
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: password toggle positioned as natural suffix via flex wrapper
Replace absolute-positioned button with a flex row container:
input takes flex-1, icon button sits at the end naturally.
Focus ring moved to the wrapper using focus-within: so it still
lights up when the input is focused.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: global Material form field styling + restore matSuffix on login
material.scss — global form field overrides (appearance=outline):
- --mdc-outlined-text-field-container-shape: 0.75rem (pill shape)
- idle/hover outline: transparent (no border at rest)
- focus outline: --md-sys-color-primary at 2px width
- background: surface-container-lowest via CSS rule on wrapper
login.ts:
- Restore mat-form-field + matInput (appearance=outline, subscriptSizing=dynamic)
- Keep custom <label> above each field (no mat-label = no floating label)
- Password field uses matSuffix on the visibility toggle button
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: spruce up home page doc with prose typography and hero section
- Install @tailwindcss/typography plugin
- Replace manual markdown styles with prose class + design token colors
- Map --tw-prose-* variables to --md-sys-color-* tokens (auto dark/light)
- Style code blocks, inline code, blockquotes with surface-container tokens
- Add hero title band to home page matching Document Page - No Sidebar design
- Hide redundant H1 from rendered markdown (.doc-prose h1:first-of-type)
- Closes part of #83
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: card-style list items on doc page matching design
- Unordered list items in .doc-prose rendered as stacked card rows
- primary-container icon box (::before) on left of each item
- Adjacent items share borders and collapse border-radius so they read
as a grouped list block (same aesthetic as 'Technology of Light and Motion')
- Removed generic ul > li margin tweak from .prose block (not needed with card layout)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: card list items now target only tech-stack sub-lists
Two bugs fixed:
- Selector was .doc-prose .prose (descendant) but both classes are on the
same element — changed to compound .doc-prose.prose
- Swapped broad 'ul > li' for 'p:has(> strong) + ul > li' so only lists
that follow a bold section label (**Frontend**, **Backend**, **Tooling**)
get card treatment; the Features list (follows <h2>) is unaffected
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* style: borderless surface-container list items
Remove all borders and border-radius juggling from tech-stack list items.
The <ul> clips its children via overflow:hidden + border-radius so the whole
group reads as a single rounded container filled with surface-container color.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: feature cards in home.md with HTML grid
- Decouple home.md from README.md (remove lint-staged sync rule)
- Add @source '../assets/*.md' so Tailwind scans home.md for utility classes
- Replace Features bullet list with a 3-col responsive card grid:
each card has a surface-container top band with a primary-container
emoji badge, plus a title and description below (not-prose scoped)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: add Theme support as sixth feature card
Gives an even 2x3 grid on desktop. Theme support (light/dark/system via
MD3 colour tokens) is a genuine user-facing feature worth highlighting.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: nav active underline sits just below text
Wrap nav link labels in <span>; apply border-bottom to the span via
a.nav-active span rule instead of the full-height <a> element, so the
indicator hugs the text rather than sitting at the bottom of the button.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: restyle functional pages to match Data Table design
- Redesign lib-page-toolbar: remove background, display-font h2 title,
generous px-6 pt-6 pb-4 padding to match in-page header design
- Align lib-page-container padding to px-6 pb-6 for consistent gutters
- Add MatPaginator to forecast-table (MatTableDataSource + signalMethod
sync + viewChild + afterNextRender connection)
- Wrap table + paginator in rounded-2xl card container
- Add Material CSS token overrides in material.scss:
table background, header/row text colours, outline-variant row borders,
paginator background, paginator text/icon colours
- Add elevated header row and subtle hover tint via global CSS rules
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: paginator + data table page styling to match design
- Fix paginator: replace afterNextRender with signalMethod watching
this.paginator() so it connects after the @if(loading()) resolves
- Increase page-toolbar title to text-4xl font-black tracking-tight
and padding to px-8 pt-8 pb-5
- Restructure weather-forecast to match design's 3-part layout:
header → filter-bar card → table card
- Move form field + button out of lib-page-toolbar into a
.forecast-filter-bar div inside lib-page-container
- Update page-container padding to px-8 pb-8
- Add editorial shadow to table card (subtle in light, deep in dark)
- Fix --mat-table-background-color to surface-container-low
- Set --mat-table-row-item-outline-color: transparent (no-line rule)
- Increase row/header heights for more spacious rows
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: remove remaining table cell borders and add page max-width
- Force-remove all MDC table cell border-bottom via direct CSS override
(the token alone doesn't cover all Material border sources)
- Add max-w-[1440px] mx-auto w-full to lib-page-toolbar and lib-page-container
so page content is constrained to a readable width on large displays
- Default paginator page size changed from 10 to 5 so pagination is
immediately visible with the default forecast count
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: style forecast filter bar to match Data Table design
- Card container: bg-surface-container rounded-2xl p-4 with editorial shadow
- Left section: primary-dot status indicator + 'Active Forecast' label
- Right section: forecast days input + filled primary 'Get Forecasts' button
- Replace PageToolbarButton (icon-only) with mat-flat-button for the action
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: form field heights and button consistency
- Remove compact py-1 min-h-[34px] infix override from .forecast-filter-bar
(leftover from old toolbar placement; was breaking floating labels)
- Keep only the subscript-wrapper: hidden rule for the filter bar
- Counter Submit: mat-button → mat-flat-button color='primary' to match
the style of the login and forecasts page action buttons
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* docs: add DESIGN.md
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* refactor: simplify UI — remove header labels, strip home hero, hide forecast button text on mobile
- Remove 'Active Forecast' label from weather forecast filter bar
- Remove 'Current Value' header strip from counter component
- Remove hero band from home page, render markdown directly
- Hide 'Get Forecasts' button text on mobile (sm:inline)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: remove icon right margin on mobile forecast button
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: use BreakpointStore and @if to swap icon/text button on mobile
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: scale counter buttons and text for mobile
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: remove Increment button from counter page toolbar
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: align filter bar bottom margin with page container bottom padding
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: fill remaining height with forecast table, paginator anchored at bottom; fix tests
- weather-forecast host: min-h-full flex flex-col
- lib-page-container gets flex-1 to fill after toolbar
- lib-forecast-table gets flex-1 to fill after filter bar
- forecast-table host: flex flex-col; wrapper: flex-col flex-1
- spacer div pushes paginator to bottom
- revert page-container pb back to pb-8
- fix counter test: use aria-label instead of removed icon text
- fix forecast-table test: expect paginated row count (5) not total
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* chore: simplify home.md features list and fix readme typo
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent 8aa406f commit d3bbbf7
30 files changed
Lines changed: 1230 additions & 325 deletions
File tree
- apps/web-app/src
- app
- assets
- styles
- libs
- counter/src/lib/components
- counter-container
- counter
- home/src/lib/home
- login/src/lib/login
- weather-forecast/src/lib/components
- forecast-table
- weather-forecast
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
5 | | - | |
6 | | - | |
7 | | - | |
8 | 4 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
10 | | - | |
| 10 | + | |
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
55 | | - | |
56 | 55 | | |
57 | | - | |
58 | | - | |
| 56 | + | |
| 57 | + | |
59 | 58 | | |
60 | 59 | | |
61 | | - | |
62 | | - | |
63 | | - | |
64 | | - | |
65 | | - | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
66 | 63 | | |
67 | 64 | | |
68 | 65 | | |
| |||
94 | 91 | | |
95 | 92 | | |
96 | 93 | | |
97 | | - | |
98 | | - | |
99 | | - | |
100 | | - | |
101 | 94 | | |
102 | 95 | | |
103 | 96 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
37 | 42 | | |
38 | 43 | | |
39 | 44 | | |
| |||
56 | 61 | | |
57 | 62 | | |
58 | 63 | | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
59 | 67 | | |
60 | 68 | | |
61 | 69 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
21 | | - | |
| 21 | + | |
22 | 22 | | |
23 | 23 | | |
24 | | - | |
| 24 | + | |
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| |||
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
55 | | - | |
| 55 | + | |
56 | 56 | | |
57 | 57 | | |
58 | 58 | | |
| |||
0 commit comments