Skip to content

Commit 45fff88

Browse files
authored
Merge pull request #110 from comnam90/release/1.4.0
chore(release): v1.4.0
2 parents 1d45806 + 5ad26df commit 45fff88

12 files changed

Lines changed: 3189 additions & 825 deletions

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [1.4.0] - 2026-05-25
11+
12+
### Changed
13+
- Mission Control redesign: rebuilt map UI with brand-aligned header, status strip, unified `.ctl` control primitive, restyled legend, and a new typography + theme token system (#103)
14+
- Map markers now render as hybrid POI dots displaying provider brand logos in place of plain provider-coloured circles (#103)
15+
- Cluster badges restyled to match the POI-dot treatment with an inverted brand accent for light/dark contrast; provider-mix strips removed (#103)
16+
- Popup template restructured with service icons, AA-contrast colours, and vault editions stacked as vertical pills on a single row (#103)
17+
- Adopted official Veeam help-center service names across the UI (e.g. "Azure Protection") and matched the providers legend icons to the map markers (#103)
18+
- Initial map view now fits to populated regions via `fitBounds` and tiles wrap so wide viewports no longer show empty edges (#103)
19+
20+
### Added
21+
- Themed CSS tooltip pattern with `aria-label` replacing native `title=` tooltips for tier and control hints (#103)
22+
23+
### Fixed
24+
- Search-click zoom escalates so popups for edge regions fit on screen, and the east map bound is extended so the NZ popup fits on mobile (#103)
25+
- Popup header zero-pads the available services count to stop layout shift between single- and double-digit values (#103)
26+
- Marker SVG `defs` IDs scoped per marker to prevent gradient/clip collisions across markers (#103)
27+
- Mobile header layout: filters stack below search and the multi-select chevron no longer overlaps the reset button (#103)
28+
- Live region count is exposed to assistive tech in the redesigned header (#103)
29+
- Removed lingering "status page" wording from the header and legend (#103)
30+
31+
### Documentation
32+
- Added ADRs covering the Mission Control aesthetic and design tokens, official Veeam service naming, custom CSS tooltip pattern, cluster marker treatment, and initial map view + tile wrap (ADR-003 through ADR-007) (#103)
33+
- Added the Mission Control redesign implementation plan under `plans/mission-control-redesign/` (#103)
34+
1035
## [1.3.0] - 2026-05-20
1136

1237
### Added
@@ -80,6 +105,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
80105
- Dark-mode map with CartoDB Dark Matter tiles
81106
- GitHub Actions CI/CD pipeline
82107

108+
[1.4.0]: https://github.com/comnam90/veeam-data-cloud-services-map/compare/v1.3.0...v1.4.0
109+
[1.3.0]: https://github.com/comnam90/veeam-data-cloud-services-map/compare/v1.2.0...v1.3.0
83110
[1.2.0]: https://github.com/comnam90/veeam-data-cloud-services-map/compare/v1.1.2...v1.2.0
84111
[1.1.2]: https://github.com/comnam90/veeam-data-cloud-services-map/compare/v1.1.1...v1.1.2
85112
[1.1.1]: https://github.com/comnam90/veeam-data-cloud-services-map/compare/v1.1.0...v1.1.1
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# ADR-003: Adopt Official Veeam Help-Center Service Names
2+
3+
**Status**: Accepted
4+
5+
## Context
6+
7+
The UI previously used a mix of ad-hoc service names produced from the YAML keys (`vdc_vault`, `vdc_m365`, `vdc_entra_id`, `vdc_salesforce`, `vdc_azure_backup`). The `serviceDisplayNames` map rendered them as a hybrid of ALL-CAPS brand acronyms and title-case product nouns — e.g. `M365 Protection`, `ENTRA ID Protection`, `SALESFORCE Protection`, `AZURE Protection`. The Vault row used short `Vault` / full `VAULT`.
8+
9+
Two problems emerged from this:
10+
11+
- The names didn’t match the section headings used in the official Veeam Data Cloud help-center user guide. Anyone reading both side-by-side had to mentally translate.
12+
- The service-filter checkbox label `Azure` collided with the Azure cloud provider label in the provider filter directly above it. Users could mistake the service filter for a provider filter.
13+
14+
The names appear in three runtime contexts: the multi-select filter dropdown (short label), the filter-button label when one service is selected (short label), and the popup row per service (full label).
15+
16+
## Decision Drivers
17+
18+
- Vocabulary parity with the official Veeam documentation users are most likely to read alongside the map.
19+
- Unambiguous filter labels — no two top-level controls should share a label.
20+
- A single source of truth (`serviceDisplayNames`) drives every UI surface.
21+
22+
## Decision
23+
24+
Adopt the official help-center section names verbatim as the `full` display names:
25+
26+
| YAML key | `short` (filter UI) | `full` (popup row) |
27+
| --- | --- | --- |
28+
| `vdc_vault` | `Vault` | `Veeam Data Cloud Vault` |
29+
| `vdc_m365` | `M365` | `Microsoft 365 Protection` |
30+
| `vdc_entra_id` | `Entra ID` | `Microsoft Entra ID Protection` |
31+
| `vdc_salesforce` | `Salesforce` | `Salesforce Protection` |
32+
| `vdc_azure_backup` | `Azure Protection` | `Microsoft Azure Protection` |
33+
34+
The `short` for `vdc_azure_backup` is deliberately `Azure Protection` (not `Azure`) to disambiguate from the `Azure` cloud-provider filter that sits next to it in the header.
35+
36+
All UI surfaces — multi-select checkbox labels, multi-select button label, and popup rows — read these strings through `getServiceDisplayName(key, type)`. The Playwright test that filters by the Azure service uses the `Azure Protection` label accordingly.
37+
38+
## Options Considered
39+
40+
### Option A: Keep the ad-hoc names
41+
42+
- Pros: No code change; existing tests pass.
43+
- Cons: Vocabulary divergence from official docs; ongoing collision between the `Azure` service short and the `Azure` provider option.
44+
45+
### Option B: Use only the short brand abbreviations everywhere (`Vault`, `M365`, `Entra`, `SF`, `Azure`)
46+
47+
- Pros: Most compact UI; no wrapping.
48+
- Cons: `SF` is opaque without context; doesn't match any official Veeam naming; the `Azure` collision is unresolved.
49+
50+
### Option C: Adopt the official help-center names (chosen)
51+
52+
- Pros: Direct parity with documentation users already read; the `…Protection` suffix on the Azure service eliminates the provider collision naturally.
53+
- Cons: Long labels — `Microsoft Entra ID Protection` wraps in the popup row on narrow widths. Accepted because the wrapping is benign and the disambiguation gain is worth it.
54+
55+
## Consequences
56+
57+
- Any future service added to the YAML schema MUST register a `{ short, full }` entry in `serviceDisplayNames` using the canonical Veeam help-center heading as `full`. If the official docs ever rename a section, this map is the single place to update.
58+
- The `short` label for a new service MUST NOT collide with any existing provider value in `#providerFilter` (today: `Azure`, `AWS`). Where collision is unavoidable, follow the precedent set here and append `Protection` (or the equivalent product noun) to the `short`.
59+
- Documentation surfaces that mention services (info panel “What is this?” copy, `static/llms*.txt`, future help text) should use the canonical `full` names.
60+
- Tests asserting against service labels (e.g. `getByRole('checkbox', { name: 'Azure Protection' })`, `<input value=vdc_azure_backup> Azure Protection</label>` regex matches) must be updated in lockstep with any future rename.
61+
62+
## Links
63+
64+
- [PR #103](https://github.com/comnam90/veeam-data-cloud-services-map/pull/103) — the redesign that introduced this convention.
65+
- Mission Control Redesign implementation plan: `plans/mission-control-redesign/plan.md`
66+
- Veeam Data Cloud help-center: <https://www.veeam.com/products/veeam-data-cloud.html>
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# ADR-004: Paired Mission Control / Workstation Aesthetic with CSS Design Tokens
2+
3+
**Status**: Accepted
4+
5+
## Context
6+
7+
The SPA shipped initially with a generic Tailwind-driven SaaS dashboard look: system fonts, slate-grey palette with a green accent sprinkled evenly across the chrome, circle markers, and a popup that duplicated the Vault row when a region offered multiple editions. A UX review flagged the design as "competent but indistinguishable from every other cloud-service map" and identified specific issues: an Australia-centric default map view, hidden-on-mobile region count, no provider identity in markers, and amber styling collisions between AWS branding and warning callouts.
8+
9+
A redesign was proposed, brainstormed across two directions ("Mission Control HUD" vs "Cartographic Atlas"), and the Mission Control direction was chosen. To make light mode a first-class peer of dark mode — not a flashlight-inversion of the cockpit aesthetic — a second variant (`Workstation`) was added: same DNA, calmer language. The two themes share the same component anatomy and only swap underlying tokens.
10+
11+
The redesign is a single-file SPA change (`layouts/index.html`) because the project's architecture deliberately keeps the entire frontend in one Hugo template. Every visible component therefore has to pick its colours, fonts, and spacing values from somewhere — a Tailwind utility class, an inline style, or a custom CSS rule. Without a shared vocabulary the redesign would have continued the original pattern of scattering hex values across hundreds of lines and would have made future theme work hard.
12+
13+
## Decision Drivers
14+
15+
- One toggle, one product. Users flipping dark↔light should see the same product wearing different surfaces, not two different apps.
16+
- A small palette that has *meaning*. The accent green was previously decorative everywhere; in the new system it signals "live / available / current selection" specifically.
17+
- Mono-first typography (with a display serif/sans companion) to differentiate from the SaaS-dashboard pack and lean into the data-density of the map.
18+
- Provider identity at the marker level — users shouldn't need to read the legend to know whether a marker is AWS or Azure.
19+
- Theming must work without `.dark` / `.light` selectors on every component. The CSS variable system replaces dozens of paired overrides.
20+
21+
## Decision
22+
23+
### Tokenized theme system
24+
25+
A single `:root` block defines the dark-mode (default) tokens. An `html.light` block re-declares the same token names with light-mode values. Every redesigned component reads colours through `var(--bg)`, `var(--text)`, `var(--accent)`, `var(--azure)`, `var(--aws)`, etc. No component declares hex values directly except where the value is provider-identity (e.g. AWS Squid Ink) and required to render in a context that doesn't inherit CSS variables (e.g. SVG attribute fills are wrapped in `var(--azure)` / `var(--aws)` for the same reason).
26+
27+
Token domains:
28+
- Surface: `--bg`, `--bg-elev`, `--bg-elev-2`
29+
- Hairlines: `--border`, `--border-strong`
30+
- Ink: `--text`, `--text-mute`, `--text-dim`
31+
- Accent: `--accent`, `--accent-soft`, `--accent-glow`
32+
- Brand: `--azure`, `--aws`
33+
34+
Dark accent is the fluorescent `#00ff88`; light accent is the muted `#00805a`. The two are intentionally non-identical — bright green on white reads as highlighter, muted green on black has no presence. Both still read as "Veeam green" emotionally.
35+
36+
### Typography
37+
38+
- `Space Grotesk` (weights 500, 700) for headlines and product nouns.
39+
- `JetBrains Mono` (weights 400, 500, 700) for body text, UI labels, status strip, popup metadata, and coordinate readouts.
40+
41+
Loaded once via Google Fonts CDN with `display=swap` and a system-monospace fallback chain. The mono-first body type is the single biggest visual differentiator from the previous Tailwind-default look.
42+
43+
### Component anatomy
44+
45+
- Header: brand mark (pulsing dot) + live "status strip" telemetry (`Online · Regions X/Y · Providers 02 · Services 05`) + unified `.ctl` control primitive (search, selects, multi-select, icon buttons share one base class with `.ctl-*` modifiers).
46+
- Map: edge-to-edge with a tokenized `.panel-legend` and tokenized Leaflet zoom/attribution chrome. No rounded corners, no green glow.
47+
- Popup: one row per service (no edition-row duplication); each row carries a distinct monochrome service icon in `--accent` — the icon's presence signals "available", its shape signals which service; edition pills aligned right; vault edition pills hover-disclose commercial limits per [ADR-005](ADR-005-custom-css-tooltip-pattern.md); official Veeam service names per [ADR-003](ADR-003-official-veeam-service-naming.md).
48+
- Markers: `L.divIcon` glyphs in provider brand colour (Azure triangle / AWS cube) replacing the prior `L.circleMarker` SVG paths. Keyboard-navigable; the parent marker carries an accessible `alt`.
49+
- Info panel: same tokens, semantic class names (`.info-section`, `.info-link`, `.info-stat`) — no `bg-slate-*` / `bg-amber-500/10` mix.
50+
51+
## Options Considered
52+
53+
### Option A: Polish the existing design
54+
55+
- Pros: Lowest risk; existing tests stay green; small diffs.
56+
- Cons: Doesn't address the "indistinguishable from every SaaS dashboard" feedback; the AWS amber/warning collision remains; mobile header still consumes ~15% of vertical space.
57+
58+
### Option B: Cartographic Atlas direction
59+
60+
- Pros: Genuinely distinctive (serif headlines, parchment palette, atlas vibe); zero competitors in this product space.
61+
- Cons: Stronger departure from Veeam brand voice; the light-mode-first treatment doesn't translate as cleanly to a dark dashboard mode; risk of feeling like a marketing site rather than an operational tool.
62+
63+
### Option C: Mission Control HUD + Workstation light (chosen)
64+
65+
- Pros: Reads as a polished operational tool; live status strip + mono numerals lean into the data-density users care about; the dark/light pair shares one design system rather than being two separate aesthetics; CSS tokens scale to future theme work (e.g. a hypothetical high-contrast mode) without requiring `.theme-x` selectors on every component.
66+
- Cons: Bigger up-front diff; Google Fonts adds a render-blocking stylesheet (mitigated by `display=swap` and a system fallback chain); some popup rows can wrap due to the longer official service names.
67+
68+
## Consequences
69+
70+
- New UI components MUST read colours/spacing through the existing tokens. Adding a new hardcoded hex value is a smell — either a new token is needed (justify in the PR), or the component should pick the closest existing token.
71+
- Theme variants are added by extending `:root` / `html.light` (and potentially a future `html.high-contrast`, `html.print`, etc.). Components should NOT branch on `html.light` directly except where light mode genuinely needs a different *structure* (e.g. drop-shadow vs glow), and even then prefer adjusting tokens.
72+
- Typography is a brand-level choice. If a future redesign wants different fonts, this ADR is the document to supersede; doing it piecemeal will fragment the system.
73+
- The accent green is reserved for "live / active / available / focus". Don't use it as decoration. The provider blue/orange tokens are reserved for provider identity. Don't repurpose them.
74+
- Each service registered in `serviceDisplayNames` MUST also register a corresponding inline SVG in `serviceIcons` (in `layouts/index.html`). Icons are simple monochrome geometric shapes that render crisply at 14px, using `stroke="currentColor"` so they inherit `--accent`. The shape carries service identity; the colour carries the "available" semantic. A service without an icon falls back to a generic checkmark — acceptable as a defensive default, not as a long-lived state.
75+
- Metadata text tokens (`--text-dim`, `--text-mute`) carry a hard floor: both MUST clear WCAG AA against the popup background (`--bg-elev`) at the 9–10px sizes used in the popup header and coordinate readouts. This UI is regularly shown on projectors and screen-shared over compressed video; a token value that looks crisp on the design machine but fades on lossy displays violates the brief. Tune the values, not the font sizes, if a future contrast regression appears.
76+
- Marker primitive: `L.divIcon` is the contract. Reverting to `L.circleMarker` would re-introduce the accessibility regression (no `keyboard: true`, no `alt`) and break the test selectors that target `.leaflet-marker-icon .map-marker-dot`.
77+
- Cluster icons (`.cluster-small`, `.cluster-medium`, `.cluster-large`) were deliberately left on the old colour system in this redesign — a known follow-up, resolved by [ADR-006](ADR-006-cluster-marker-visual-treatment.md). The resolution re-tokenises clusters to `var(--accent)` only; per-provider colouring at cluster level (`--azure` / `--aws`) was considered and rejected because aggregated provider colouring destroyed the cluster/marker visual hierarchy — see ADR-006 §Options Considered.
78+
- Hugo's HTML minifier strips quotes around single-token attribute values. Smoke tests using `curl | grep` should account for this (`class=hud`, not `class="hud"`).
79+
80+
## Links
81+
82+
- [PR #103](https://github.com/comnam90/veeam-data-cloud-services-map/pull/103) — the redesign that introduced this aesthetic.
83+
- Implementation plan: `plans/mission-control-redesign/plan.md`
84+
- [ADR-003](ADR-003-official-veeam-service-naming.md) — service-naming convention used inside the popup component defined by this ADR.
85+
- UX review and mockups (session output): the brainstorming explored Mission Control and Cartographic Atlas directions at desktop + mobile, both themes, before this aesthetic was chosen.

0 commit comments

Comments
 (0)