Skip to content

Commit d3bbbf7

Browse files
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

.lintstagedrc.cjs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
module.exports = {
22
'*.{ts,js}': 'eslint --cache --cache-location=.husky/_ --fix',
33
'*.{ts,js,css,scss,md,mdx}': 'prettier --write',
4-
'README.md': () => [
5-
'pnpm nx run web-app:update-readme',
6-
'git add apps/web-app/src/assets/home.md',
7-
],
84
};

DESIGN.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# Design System Specification: High-End Editorial SaaS
2+
3+
## 1. Overview & Creative North Star
4+
5+
The Creative North Star for this design system is **"The Kinetic Curator."**
6+
7+
We are moving away from the rigid, boxy constraints of traditional SaaS dashboards toward a digital experience that feels like a high-end editorial gallery. The goal is to balance the efficiency of a professional tool with the aesthetic soul of a premium publication.
8+
9+
By utilizing intentional asymmetry, overlapping layers, and a rigorous adherence to tonal depth over structural lines, we create a workspace that feels breathing and alive. We don't just "display" data; we curate it. This system prioritizes whitespace as a functional element, using it to guide the eye through complex workflows with sophisticated ease.
10+
11+
---
12+
13+
## 2. Colors & Surface Philosophy
14+
15+
The palette is a transition from high-vibrancy digital tones to a "muted-luxury" spectrum, now adapted for a dark mode experience. We utilize slate blues, soft plums, and terracotta reds to signify action without causing cognitive fatigue, appearing richer and more saturated against the dark background.
16+
17+
### The "No-Line" Rule
18+
19+
**Explicit Instruction:** Designers are prohibited from using 1px solid borders for sectioning or containment.
20+
Boundaries must be defined solely through:
21+
22+
- **Background Shifts:** Placing a `surface-container-low` component against a `surface` background.
23+
- **Tonal Transitions:** Using the `outline-variant` at 10-15% opacity only when absolutely necessary for accessibility.
24+
25+
### Surface Hierarchy & Nesting
26+
27+
Treat the UI as a physical stack of fine paper. Use the following tiers to define depth:
28+
29+
- **Base Layer:** `surface` (#1B1C1E) – The canvas, providing a rich, dark foundation.
30+
- **Secondary Areas:** `surface-container-low` (#252629) – Used for sidebars or secondary utilities.
31+
- **Interactive Components:** `surface-container-lowest` (#303134) – Used for cards or high-priority inputs to make them "pop" against the darker base.
32+
- **Elevated Modals:** `surface-bright` (#1B1C1E) – Combined with glassmorphism.
33+
34+
### The "Glass & Signature" Rule
35+
36+
To break the "flat" SaaS aesthetic, floating elements (menus, tooltips, navigation bars) should utilize **Glassmorphism**:
37+
38+
- **Background:** Semi-transparent `surface` or `primary-container`.
39+
- **Effect:** `backdrop-filter: blur(20px)`.
40+
- **Signature Polish:** Use a subtle linear gradient on primary CTAs transitioning from `primary` (#4A628A) to `primary-dim` (#3B537A) to give buttons a tactile, "pressed-ink" quality.
41+
42+
---
43+
44+
## 3. Typography
45+
46+
We use **Manrope** exclusively. Its geometric yet humanist qualities allow it to scale from aggressive editorial headlines to micro-labeling without losing character.
47+
48+
- **Display (LG/MD/SM):** Set with tight letter-spacing (-0.02em). Use these for high-impact data points or "Kinetic Gallery" hero moments.
49+
- **Headlines:** The "Anchor." High contrast is mandatory. Use `on-surface` (#E3E2E6) for all headlines to ensure a bold, authoritative hierarchy against the dark background.
50+
- **Body (LG/MD/SM):** Optimized for readability. Use `on-surface-variant` (#C4C6CA) for long-form text to reduce visual weight while maintaining WCAG AA contrast.
51+
- **Labels:** Always uppercase with +0.05em letter-spacing. Labels should feel like architectural annotations on a blueprint.
52+
53+
---
54+
55+
## 4. Elevation & Depth
56+
57+
Depth in this system is achieved through **Tonal Layering**, not shadows.
58+
59+
- **The Layering Principle:** Place a `surface-container-lowest` (#303134) card on top of a `surface-container` (#2C2D30) section. This creates a natural, soft lift that feels integrated into the environment.
60+
- **Ambient Shadows:** For floating elements only.
61+
- **Blur:** 40px – 60px.
62+
- **Opacity:** 4% – 8%.
63+
- **Color:** Use a tinted shadow based on `on-surface` (e.g., a deep slate tint) rather than pure black.
64+
- **The "Ghost Border" Fallback:** If a container lacks sufficient contrast against its parent, use the `outline-variant` token at **15% opacity**. This provides a "suggestion" of a boundary without the harshness of a traditional border.
65+
66+
---
67+
68+
## 5. Components
69+
70+
### Buttons
71+
72+
- **Primary:** Gradient fill (`primary` to `primary-dim`). White text (`on-primary`). Roundedness: Maximum, pill-shaped (reflecting `roundedness: 3`).
73+
- **Secondary:** Surface-based. `surface-container-high` background with `on-primary-container` text. No border.
74+
- **Tertiary:** Text-only. Uses `primary` color with a subtle `surface-container` hover state.
75+
76+
### Cards & Lists
77+
78+
- **The Divider Ban:** Do not use `
79+
` tags or border-bottoms to separate list items. Use **Vertical White Space** (spacing `4` or `5`) or alternating tonal shifts between `surface-container-low` and `surface-container-lowest`.
80+
81+
- **Interactive State:** On hover, a card should transition from `surface-container-lowest` to `surface-bright` with a 4% ambient shadow.
82+
83+
### Input Fields
84+
85+
- **Styling:** Use `surface-container-low` as the field background.
86+
- **Focus State:** Transition the background to `surface-container-lowest` and add a 1px "Ghost Border" using the `primary` token at 40% opacity.
87+
- **Error State:** Use `error` (#9f403d) for the label and an `error-container` (#601410) tint for the field background to signify a "warning glow."
88+
89+
### Chips
90+
91+
- **Selection Chips:** Use `secondary-container` (#90708f) with `on-secondary-container` (#FFDBF3) text. The soft plum tone provides a professional, sophisticated distinction from the primary blue actions.
92+
93+
---
94+
95+
## 6. Do's and Don'ts
96+
97+
### Do
98+
99+
- **Do** embrace asymmetry. In a gallery layout, allow some columns to be wider than others or offset images/data-viz.
100+
- **Do** use the Spacing Scale rigorously. Use large gaps (`spacing-12` or `spacing-16`) to separate major conceptual groups.
101+
- **Do** use `tertiary` (#A65D52) for "Human" or "Organic" touchpoints—notifications, user feedback, or celebratory states.
102+
103+
### Don't
104+
105+
- **Don't** use 100% opaque borders. They clutter the "Kinetic" flow and make the UI feel like a legacy spreadsheet.
106+
- **Don't** use pure black (#000000) for text. Use `on-background` (#E3E2E6) to maintain the "premium ink" feel.
107+
- **Don't** overcrowd the viewport. If a screen feels busy, increase the background-to-component ratio using the `surface` color.
108+
109+
---
110+
111+
## 7. Key Design Tokens Reference
112+
113+
| Role | Token | Hex |
114+
| :---------------------- | :------------------------- | :----------------------- |
115+
| **Primary Action** | `primary` | #4A628A |
116+
| **Secondary (Plum)** | `secondary` | #765B75 |
117+
| **Accent (Terracotta)** | `tertiary` | #A65D52 |
118+
| **Main Canvas** | `surface` | #1B1C1E |
119+
| **High-Priority Card** | `surface-container-lowest` | #303134 |
120+
| **Text (Primary)** | `on-surface` | #E3E2E6 |
121+
| **Text (Secondary)** | `on-surface-variant` | #C4C6CA |
122+
| **Border Fallback** | `outline-variant` | #7E909B (at 15% opacity) |

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ A full-stack demo using an [Nx monorepo](https://nx.dev) with [Angular](https://
77
## Features
88

99
- **Authentication** — register, login, and logout with JWT bearer tokens backed by ASP.NET Core Identity
10-
- **Notification centre** — persistent notification panel with unread count, mark-as-read, dismiss, and action support (e.g. one-click reload on SW update)
10+
- **Notification center** — persistent notification panel with unread count, mark-as-read, dismiss, and action support (e.g. one-click reload on SW update)
1111
- **PWA / service worker** — offline support; notifies users when a new app version is available with an in-app prompt to reload
1212
- **Debug page** (`/debug`) — trigger test notifications and inspect service worker update state during development
1313
- **PR preview deployments** — every pull request gets a live preview URL via Azure Static Web Apps

apps/web-app/src/app/app.integration.spec.ts

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,14 @@ describe('App Integration', () => {
5252
fixture.detectChanges();
5353
const router = TestBed.inject(Router);
5454
router.initialNavigation();
55-
// Wait for the home feature to load
5655
const compiled = fixture.nativeElement as HTMLElement;
57-
const pageToolbar = await waitForElement(
58-
() => compiled.querySelector('[data-testid="lib-page-toolbar"]'),
56+
const homeComponent = await waitForElement(
57+
() => compiled.querySelector('[data-testid="lib-home"]'),
5958
applicationRef,
6059
);
61-
expect(pageToolbar.textContent?.toLowerCase()).toContain('home');
62-
const pageContainer = compiled.querySelector(
63-
'[data-testid="lib-page-container"]',
64-
);
65-
expect(pageContainer).toBeTruthy();
60+
expect(homeComponent).toBeTruthy();
61+
const markdown = compiled.querySelector('[data-testid="page-markdown"]');
62+
expect(markdown).toBeTruthy();
6663
});
6764

6865
it('should navigate to /weather-forecast and load the feature', async () => {
@@ -94,10 +91,6 @@ describe('App Integration', () => {
9491
applicationRef,
9592
);
9693
expect(loginComponent).toBeTruthy();
97-
const pageContainer = compiled.querySelector(
98-
'[data-testid="lib-page-container"]',
99-
);
100-
expect(pageContainer).toBeTruthy();
10194
});
10295

10396
it('should navigate to /feature and load the counter feature', async () => {

apps/web-app/src/app/app.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,17 @@ import { filter, pipe, tap } from 'rxjs';
2828
href="#main-content"
2929
>Skip to main content</a
3030
>
31-
<lib-main-toolbar
32-
(toggleSidenav)="store.toggleSidenav()"
33-
(logout)="authStore.logout(authStore.pageRequiresLogin())"
34-
[loggedIn]="authStore.loggedIn()"
35-
/>
36-
<mat-sidenav-container fullscreen>
31+
@if (!store.hideToolbar()) {
32+
<lib-main-toolbar
33+
(toggleSidenav)="store.toggleSidenav()"
34+
(logout)="authStore.logout(authStore.pageRequiresLogin())"
35+
[loggedIn]="authStore.loggedIn()"
36+
/>
37+
}
38+
<mat-sidenav-container
39+
fullscreen
40+
[class.has-toolbar]="!store.hideToolbar()"
41+
>
3742
<mat-sidenav
3843
mode="over"
3944
[opened]="store.showSidenav()"
@@ -56,6 +61,9 @@ import { filter, pipe, tap } from 'rxjs';
5661
styles: [
5762
`
5863
.mat-drawer-container {
64+
height: 100%;
65+
}
66+
.mat-drawer-container.has-toolbar {
5967
margin-top: var(--mat-toolbar-standard-height);
6068
height: calc(100% - var(--mat-toolbar-standard-height));
6169
}

apps/web-app/src/assets/home.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ A full-stack demo using an [Nx monorepo](https://nx.dev) with [Angular](https://
55
## Features
66

77
- **Authentication** — register, login, and logout with JWT bearer tokens backed by ASP.NET Core Identity
8-
- **Notification centre** — persistent notification panel with unread count, mark-as-read, dismiss, and action support (e.g. one-click reload on SW update)
8+
- **Notification center** — persistent notification panel with unread count, mark-as-read, dismiss, and action support (e.g. one-click reload on SW update)
99
- **PWA / service worker** — offline support; notifies users when a new app version is available with an in-app prompt to reload
1010
- **Debug page** (`/debug`) — trigger test notifications and inspect service worker update state during development
1111
- **PR preview deployments** — every pull request gets a live preview URL via Azure Static Web Apps

apps/web-app/src/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818
<meta name="apple-mobile-web-app-title"
1919
content="Demo App" />
2020
<meta name="theme-color"
21-
content="#fafafa"
21+
content="#f8f9fa"
2222
media="(prefers-color-scheme: light)" />
2323
<meta name="theme-color"
24-
content="#171717"
24+
content="#131313"
2525
media="(prefers-color-scheme: dark)" />
2626
<meta name="msapplication-navbutton-color"
2727
content="#fafafa" />
@@ -52,7 +52,7 @@
5252
<link rel="preconnect"
5353
href="https://fonts.gstatic.com"
5454
crossorigin />
55-
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap"
55+
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;600;700;800&family=Inter:wght@400;500&display=swap"
5656
rel="stylesheet" />
5757
<link href="https://fonts.googleapis.com/icon?family=Material+Icons&display=swap"
5858
rel="stylesheet" />

0 commit comments

Comments
 (0)