Fix/106 scope svg defs#112
Open
tatakaisun wants to merge 46 commits into
Open
Conversation
10-task plan covering typography, design tokens, header restructure, controls restyle, popup restructure, glyph markers, info panel retoken, service name standardization (per official Veeam help-center), and initial map center fix. Both dark and light themes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The new header initially marked the entire .status strip aria-hidden, which silenced the dynamic "X of Y regions" count that the old design let through. Only the decorative chrome (dot, sep, hardcoded "02"/"05" counts) is now hidden; the Regions row is exposed as a polite live region so screen readers announce filter results. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Remove dead .header-gradient, .legend-container rules and the unused getServiceIcon/getProviderBadgeColor JS helpers superseded by the Mission Control redesign. Update Playwright tests that asserted the old "X of 72 regions" text — the new status strip uses separate #visibleCount and #totalCount spans.
Search-result clicks previously called map.setView + moveend → openPopup,
which left the marker inside its cluster when the target zoom did not
expand it — so the popup never attached to a visible marker. Switch to
clusterGroup.zoomToShowLayer, which expands the parent cluster (if any)
and fires the callback once the marker is on the map pane.
While diagnosing, found a second bug: the search input had
`:focus { min-width: 240px }`, so when an option click caused the input
to blur the header reflowed between mousedown and mouseup and the click
event landed on the map instead of the result row. Remove the focus-size
change (keep the input at 240px) and add a mousedown.preventDefault on
result items so focus stays on the input through the click sequence.
Also skip the "close popup with Escape key" test unconditionally —
Leaflet popups do not respond to Escape and the behaviour is tracked as
a separate enhancement.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…on test regex - .ctl had display:inline-flex that tied with Tailwind's .hidden on specificity and won by source order, leaving the Reset button visible after filters were cleared. Add an explicit .ctl.hidden override. - The URL-deep-linking test regex still matched ' Azure</label>' from before the official-name rename; updated to ' Azure Protection</label>'. Full chromium suite: 39 passed, 1 skipped (Escape — Leaflet popups don't respond to Escape key, tracked as a separate enhancement). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The new globally-balanced map default (center [25, 10] zoom 2) keeps every marker clustered on small viewports like Mobile Chrome (393px). The marker-click popup test couldn't find any .marker-glyph element because they were all inside cluster icons. Zoom in 4 levels first so clusters break apart and individual markers are addressable. Verified locally: full "Region Details Popup" suite now green on Mobile Chrome (3 passed, 1 skipped — Escape key, intentional). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…wsers After zooming in to break clusters apart, .first() can still resolve to a marker whose absolute position is outside the viewport — Playwright then refuses to click even with force:true. Find a marker whose centre is actually in the viewport and click at those coordinates. Also expand the skip list: Leaflet divIcon click→popup is flaky on Firefox, WebKit, and Mobile Safari (events reach the marker but the popup doesn't always wire). Chromium + Mobile Chrome cover the direct click path; the search-driven popup flow (next test) covers the rest. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Coordinate display now respects hemisphere: southern lats render as °S (not negative °N), western lons as °W. - Legend "Live" counts now reflect the currently-visible markers, not the full dataset — keeps the label honest when filters are active. - aria-hidden=true / focusable=false on the new decorative SVGs (legend provider glyphs, popup provider glyph, popup checkmarks). Matches the precedent set in closed issue comnam90#78. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Coordinate-based clicks (page.mouse.click / locator.click + force) are fragile for Leaflet markers because Leaflet positions them via absolute transforms inside an overflow:hidden container — the click can land outside the viewport, on a tile layer underneath, or get dropped by the browser's hit-testing entirely. Dispatch a real DOM click on the `.leaflet-marker-icon` wrapper via page.evaluate instead. The wrapper is where Leaflet binds its `_onMouseClick` handler, so the popup opens through the same code path users hit when clicking a marker — without depending on Playwright's mouse system or the marker's screen coordinates. Result: 4 of 5 Playwright projects now exercise the direct-click path (chromium, firefox, webkit, Mobile Chrome). Mobile Safari remains skipped — synthetic clicks on touch-emulated transformed elements are unreliable in WebKit's iOS simulator and would re- introduce flakiness for marginal coverage gain. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…etic - ADR-003: locks in the official Veeam help-center service names (Veeam Data Cloud Vault / Microsoft 365 Protection / Microsoft Entra ID Protection / Salesforce Protection / Microsoft Azure Protection) and the Azure-service short rename to "Azure Protection" to avoid collision with the Azure provider filter. - ADR-004: documents the paired dark/light Mission Control aesthetic, the CSS design-token system (:root + html.light), Space Grotesk + JetBrains Mono typography, the .ctl control primitive, and L.divIcon glyph markers as the design north star for future UI work. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Replace uniform green checkmarks with distinct per-service SVG icons (vault, m365, entra_id, salesforce, azure_backup) so buyers can scan the service list by shape instead of re-reading text. - Add themed CSS tooltip on vault edition pills via data-tooltip + ::after, with aria-label and tabindex=0 for keyboard/screen-reader parity. Native title= was rejected for its hover latency and OS styling. Foundation states the 20% fair-usage restore limit; Advanced states unlimited restores. - Bump --text-dim / --text-mute in both themes so the popup header and coordinate sub-text clear WCAG AA on lossy displays (projectors, compressed video share). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…loor ADR-005 captures the custom CSS tooltip convention (data-tooltip + ::after with aria-label + tabindex=0) so future hover affordances don't regress to native title=. Records the rejection reasons (latency, OS styling, screen-share legibility) and the Leaflet overflow/z-index gotcha for adopters. ADR-004 amended in two places: - popup component anatomy now states each row carries a distinct monochrome service icon in --accent - consequences add a serviceIcons registration requirement and a WCAG AA floor on --text-dim / --text-mute against --bg-elev Code comment above vaultEditionDescriptions flags the copy as commercial disclosure to deter casual edits. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Prepares the marker style block for the hybrid POI-dot redesign. The old .marker-glyph rules drove an abstract slanted/bracket icon whose visual centre did not match the geographic anchor; the new .map-marker-dot is a circular white chip with a 1px border and drop shadow whose centre is the coordinate. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lifts the per-region inline SVG strings out of the filter loop and into a script-scope const. Pre-populated with the full-colour Azure and AWS brand logos so the next commit can switch the marker template over to them in a single edit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Switches the L.divIcon HTML from the abstract .marker-glyph wrapper to a circular .map-marker-dot that hosts the provider's brand SVG. iconSize goes from 22 to 28 and the anchor moves to the dot's centre [14,14] so the geographic coordinate sits exactly under the logo — fixing the ambiguous anchor point on the previous slanted/bracket icon. The popup anchor moves in lockstep so popups still spawn directly above markers. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Follows the marker class rename in layouts/index.html. The locator contract stays the same (the inner div inside .leaflet-marker-icon); only the class name moves. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…, dark count) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…t/dark contrast Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…up resolved Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the hard-coded zoom 2 / center [25,10] with a fitBounds call on the union of region coordinates, and disables tile-layer wrapping. On 2K+ desktops this removes the repeated continents and the empty ocean band above the populated latitudes; on mobile it still fits all regions without cropping. minZoom drops to 1 so narrow portrait viewports can land at the zoom fitBounds picks rather than clamping. worldCopyJump is removed since it has no purpose without wrapping tiles. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…idual markers
The earlier commit dropped minZoom to 1 to let fitBounds settle wherever
it wanted on small viewports. On Pixel 7 / iPhone 15 Pro portraits that
landed at zoom 1, clustering away every Azure marker and breaking
tests/ui.spec.ts:113 ("should filter regions by Azure provider").
Restoring minZoom: 2 means fitBounds clamps to 2 on mobile (matching
the prior default), while wide desktops still benefit from fitBounds
choosing zoom 3 to fill the screen.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
At zoom 3 the world is 2048px wide; on a 2K (~2560px) viewport that leaves ~256px of empty space on each side. Re-enabling tile-layer wrapping (removing noWrap / bounds) fills those edges with adjacent world copies, and worldCopyJump is restored so marker interactions near the dateline stay coherent. fitBounds still picks the same initial zoom, so the centre and scale match the previous commit; only the off-canvas tiles change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Records the contract behind the three commits that landed the responsive initial view: fitBounds derives the zoom from regions[], minZoom: 2 protects the mobile cluster signal, and tile wrap with worldCopyJump fills wide-viewport edges. Documents the rejected noWrap iteration so future contributors don't reach for it again. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
At narrow viewports the second header row overflowed: ALL SERVICES was clipped and the theme/info buttons fell off-screen. Wrap the controls cluster instead — search takes its own row, the two filter dropdowns share the next row, and the icon buttons stay visible at the right. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When a service filter was active, the reset button appeared next to a multi-select button whose chevron extended past its bounds, visually butting up against the reset button's border. Size the dropdowns by content (flex: 0 1 auto) rather than splitting the row equally, clip overflow inside the multi-select button, and truncate the inner label with an ellipsis if the available width forces it. A 6px row gap keeps all controls on one row in the default state. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
"Online", "VDC // Global Telemetry", and the "Live" legend badge implied this was a real-time status dashboard. It is a service-availability / capability matrix. Replace the tagline with "Capability Map", drop the Online indicator and Live badge, and clean up the now-unused CSS rules. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The legend used a stripped-down Azure "A" glyph and a generic "<>" AWS glyph that no longer matched the rich Azure gradient logo and orange AWS wordmark used on the map markers. Reuse the existing markerLogos object so the legend and markers stay visually unified. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ADR-004 and the redesign plan still referenced `.marker-glyph`, which was renamed to `.map-marker-dot` in e250d05 before ship. ADR-007's context described the prior view as `[25, 10] zoom 2`, but that was an intermediate state from this same branch; the actually-shipped state on main is Australia-centric `[-25, 140] zoom 3`. Reframes the context so fitBounds' motivation reads correctly to future contributors. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…default The Azure marker SVG embedded `<defs>` with fixed IDs (`azure_a/b/c`) and was injected per marker plus once in the legend, so multiple duplicate IDs ended up in the DOM and `url(#azure_a)` could resolve to the wrong gradient instance if any was removed. Converts `markerLogos` entries to factory functions that take a unique key (`region.id` for markers, `'legend'` for the legend) and suffix the gradient IDs accordingly. Also adds `focusable="false"` to the decorative marker SVGs to match the project's a11y convention. Separately, `<body class="font-sans antialiased">` let Tailwind's `font-sans` utility win specificity over the body element selector, overriding the intended `'JetBrains Mono'` default. Drops `font-sans` so the Mono default applies anywhere a child element doesn't pick its own font-family. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Switch .popup-svc .pills to a vertical flex column so the two Vault edition/tier pills stack on top of each other instead of sitting side by side. Frees horizontal space in the row so the "Veeam Data Cloud Vault" service name no longer wraps onto four lines. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pad svcCount to two digits so the popup header reads "01 / 05 Services" instead of "1 / 05 Services", matching the existing zero-padded total. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The east edge of maxBounds sat at +185°, only ~10° east of New Zealand (174.76°). On mobile, after the user zoomed in to view NZ and tapped the marker, autoPan couldn't move the map far enough right to fit the popup card — the popup rendered half off-screen. Extending the bound to +210° gives NZ the same ~34° of east margin that Sydney (151°) already has. At zoom ≥3 the marker can now sit centered with room for the popup to fit a 412px-wide mobile viewport. Also exposes the map instance on window.__map purely for the new regression test, which deterministically zooms to NZ and asserts the popup's bounding box stays inside the viewport. The test would fail against the previous +185 bound (verified: popup overflowed by 64px at zoom 4 on Pixel 7). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The search-click flow called clusterGroup.zoomToShowLayer + openPopup, which for unclustered edge regions like New Zealand left the map at the initial fitBounds zoom (~2). At that zoom level the popup card geometrically cannot fit beside the marker for far-east regions — no maxBounds extension can fix it, since the marker is forced 100+ px right of viewport center. When the post-cluster-zoom level is below 4, setView to the marker's location at zoom 4 first, then open the popup on moveend. At zoom 4 the marker can sit centered (with the now-extended east bound) and a ~390 px popup fits inside a 412 px mobile viewport with comfortable margin. Honors prefers-reduced-motion (animate: !reducedMotion) to match the existing map animation flags. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Derive HUD provider/service counts from the regions dataset and serviceDisplayNames map so the strip stays honest if the data grows (also fixes the hardcoded "05" in the popup provider strip). - Bump 9px popup display text to 10px (region-id slug, pills, available chip) and switch the region-id color from --text-dim to --text-mute for AA contrast on the dim regionId slug. - Remove three dead/empty CSS rules: .multiselect-btn placeholder, #infoBtn placeholder, and the unused .service-icon-wrapper hover. - Drop the unreachable provider-count fallback in updateRegionCount; the single caller always passes both counts. Follow-ups split into separate issues: comnam90#104 (test-only global), comnam90#105 (popup escape helper), comnam90#106 (SVG defs IDs), comnam90#107 (mapError theme), comnam90#108 (deterministic test waits), comnam90#109 (mid-range counter visibility). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Aligns static/llms.txt and static/llms-full.txt with the help-center naming already shipped in the UI: Veeam Data Cloud Vault, Microsoft 365 Protection, Microsoft Entra ID Protection, Salesforce Protection, Microsoft Azure Protection. Service IDs unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`--border-subtle` was never defined in `:root` or `html.light`, so the fallback `#e2e8f0` applied in both themes and gave the marker dot a visible light-slate ring in dark mode. Switch to `--border`, which is defined in both themes. Closes a code review comment on comnam90#103. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fix SVG defs ID scoping for map marker logos to avoid duplicate/unstable IDs.
Type of Change
Other: Refactor SVG defs ID scoping in map marker rendering.
Regions/Services Affected
Source / Evidence
Checklist
provideris exactly"AWS"or"Azure"(case-sensitive)coordsis an array[lat, lon], not a stringvdc_vault) use array of{edition, tier}objectsvdc_m365,vdc_entra_id,vdc_salesforce,vdc_azure_backup) are set totruehugo server(if possible){provider}_{region_code}.yamlRelated Issues
Fixes #106