Skip to content

feat(ui): codify map-floating glass, theme-aware shadows, tighter radius - #1764

Merged
giswqs merged 3 commits into
mainfrom
feat/ui-glass-and-motion
Aug 7, 2026
Merged

feat(ui): codify map-floating glass, theme-aware shadows, tighter radius#1764
giswqs merged 3 commits into
mainfrom
feat/ui-glass-and-motion

Conversation

@giswqs

@giswqs giswqs commented Aug 7, 2026

Copy link
Copy Markdown
Member

Follow-up to #1754 (Tier 2 + Tier 3 of the UI modernization). Everything here works through tokens rather than per-component styling, so most of it lands without editing components at all.

1. Map-floating chrome — "instrument glass"

I pitched this as adding a signature effect. That was wrong, and worth correcting: the treatment already existed in 11 components. What was missing was consistency. The recipes had drifted:

axis values found on main
opacity /95, /90, /70
blur backdrop-blur-sm ×8, -md ×1, bare backdrop-blur ×2
shadow shadow-lg, -md, -sm

So this collapses all of them into one .map-glass class, and encodes the rule the app was already half-following:

Chrome docked beside the map (toolbar, status bar, side panels) is opaque. Panels floating over the map are translucent — because translucency is the signal for "this sits above your data."

Where it was deliberately not applied, since the boundary is the interesting part:

  • PixelTimeSeriesControl — that's content (a chart), not chrome. 85% translucency over busy imagery would fight the data it exists to show.
  • Dialogs — they sit on a dimmed overlay, not on the map.
  • DesktopShell's file-drop scrim — a full-cover dim, not a panel; keeps its own /70.

Why a plain class instead of @utility: it's applied next to components that already emit a bg-* utility (MapGrid's Button variant="outline" carries bg-background). As a utility, both would land in the same cascade layer and the winner would depend on Tailwind's internal sort rather than intent. Unlayered CSS beats the utility layer outright. Trade-off: no variants (hover:, md:), which nothing needs.

Also added an @supports fallback to 97% opaque — at 85% with no blur, panels over live imagery are unreadable.

2. Theme-aware shadow scale

Tailwind v4 bakes a 10%-black colour into its shadow utilities. On dark surfaces that's all but invisible — meaning all ~65 shadow sites in the app did nothing in dark mode, and elevation rested entirely on the surface ladder from #1754.

Redefining --shadow-sm/md/lg/xl against per-theme --elev-penumbra/--elev-umbra fixes every one of those sites without touching a single component. Each step now maps to a surface rather than being picked by eye:

shadow-sm   resting control / inline card
shadow-md   popover, dropdown, tooltip
shadow-lg   panel floating over the map
shadow-xl   modal dialog

Two implementation notes worth a reviewer's eye:

  • The elevation tokens are plain custom properties precisely so they inherit. Tailwind registers --tw-shadow-color with inherits: false, so the obvious approach — retinting shadows by setting that on :root — silently does nothing.
  • Colours are written bare; Tailwind wraps them in var(--tw-shadow-color, …) when generating the utility, so shadow-<color> overrides keep working. Writing the wrapper by hand just nests the fallback twice.

3. Radius and reduced motion

  • --radius 0.5rem0.375rem. A dense tool UI reads sharper and the derived md/sm steps stay positive. This is the most subjective change in the PR — easy to drop if you disagree.
  • One global prefers-reduced-motion guard. Two components respected the preference against ~53 transition sites. Motion is reduced to a near-instant cross-fade rather than removed outright, since an abrupt swap is its own accessibility problem.

I also drafted motion tokens (--duration-fast, --ease-out-quart) and removed them before committing: Tailwind only emits utilities actually used in source, so with no consumer they generated zero CSS. Unused tokens that look like a system but aren't are worse than none.

Verification

  • npm run build clean; npm run test:frontend 5473 pass, 0 fail; pre-commit on changed files passes.
  • Driven in the built app with Playwright. In dark mode with a two-column split, 5 .map-glass panels render as rgba(17,21,28,0.85) with blur(12px) saturate(1.4) at radius 4px; shadows resolve to rgba(0,0,0,0.4) / rgba(0,0,0,0.55) instead of the old invisible 10% black. In light mode --elev-umbra switches to the cool-navy value and the toolbar stays rgb(255,255,255) — opaque docked chrome, glass floating chrome, as intended.

Not verified — please check on real hardware

backdrop-filter cost under GPU compositing. I tried to measure it and the measurement is not trustworthy: the test browser runs SwiftShader (software rendering), where blur-on vs blur-off medians came out identical (66.8 vs 66.7 ms) at a software-bound ~15fps. That says nothing about GPU behaviour.

This matters because the blur radius went from backdrop-blur-sm (4px) to 12px plus a saturate(), so the per-frame compositing cost is genuinely higher than on main — the wider blur is what keeps text legible at the lower 85% opacity. Worth a pan/zoom sanity check on a real GPU before merge; if it bites, the radius is a one-line dial in index.css.

Summary by CodeRabbit

  • Style
    • Standardized map overlays, panels, banners, legends, and story map controls with a consistent translucent glass appearance.
    • Refined shadows, corner rounding, and visual elevation across light and dark themes, including dialogs.
    • Improved fallback styling for environments that do not support backdrop effects.
    • Updated map controls with clearer borders and more consistent visual treatment.
  • Accessibility
    • Added reduced-motion support to minimize animations, transitions, and smooth scrolling when requested.

Follow-up to #1754. Three changes, all working through tokens rather than
per-component edits.

Map-floating chrome ("instrument glass")
- The translucent-blur treatment was already in use across 11 components, but
  copy-pasted with drifted values: bg-background/90 vs /95, backdrop-blur-sm vs
  -md vs bare backdrop-blur. Replace all of them with one `.map-glass` class so
  the look has a single home.
- Encodes the rule the app was already half-following: chrome docked BESIDE the
  map (toolbar, status bar, side panels) is opaque; panels floating OVER the map
  are translucent, because translucency is what signals "this sits above your
  data".
- Deliberately a plain unlayered class, not an `@utility`. It is applied next to
  components that already emit a bg-* utility (MapGrid's Button variant="outline"
  carries bg-background); as a utility both would sit in the same cascade layer
  and the winner would depend on Tailwind's internal sort rather than intent.
- Added to MapGrid's pane controls, which float over the map but never had it.
  Deliberately NOT added to PixelTimeSeriesControl or the dialogs: that panel is
  content (a chart) rather than chrome, and dialogs sit on a dimmed overlay, not
  on the map. DesktopShell's file-drop scrim keeps its own bg-background/70,
  being a full-cover dim rather than a panel.
- Falls back to 97% opaque via @supports where backdrop-filter is unavailable;
  at 85% with no blur, panels over live imagery are unreadable.

Theme-aware shadow scale
- Tailwind v4 bakes a 10%-black colour into its shadow utilities, so all ~65
  shadow sites in the app were effectively invisible in dark mode and elevation
  rested entirely on the surface ladder from #1754. Redefine --shadow-sm/md/lg/xl
  against inheritable --elev-penumbra/--elev-umbra tokens that switch per theme.
  Fixes every existing site without touching a component.
- Those tokens are plain custom properties precisely so they inherit: Tailwind
  registers --tw-shadow-color with `inherits: false`, so retinting shadows by
  setting that on :root silently does nothing.
- Colours are written bare; Tailwind adds the var(--tw-shadow-color, …) wrapper
  itself, so `shadow-<color>` overrides keep working.

Other
- --radius 0.5rem -> 0.375rem. A dense tool UI reads sharper, and the derived
  md/sm steps stay positive. This is the most subjective change here.
- One global prefers-reduced-motion guard. Two components respected the
  preference against ~53 transition sites; motion is reduced to a near-instant
  cross-fade rather than removed, since an abrupt swap is its own problem.

Verified in the built app with Playwright: 5 .map-glass panels render as
rgba(17,21,28,0.85) with blur(12px) saturate(1.4) and radius 4px, shadows
resolve to rgba(0,0,0,0.4)/rgba(0,0,0,0.55) in dark instead of the old
invisible 10% black, and the toolbar stays rgb(255,255,255) opaque in light.

Not verified: backdrop-filter cost on real GPU compositing. The test browser
runs SwiftShader, where blur on/off medians were identical (66.8 vs 66.7ms) at a
software-bound ~15fps, so the measurement says nothing useful. Note the blur
radius went from 4px to 12px plus a saturate(), so GPU cost is higher than on
main — worth a look on real hardware.
Copilot AI lite review requested due to automatic review settings August 7, 2026 18:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 052dc389-8ba5-4e20-b14f-5ac7c5f8e5e6

📥 Commits

Reviewing files that changed from the base of the PR and between 8d872ad and fbd0f1b.

📒 Files selected for processing (2)
  • apps/geolibre-desktop/src/index.css
  • packages/ui/src/components/dialog.tsx

📝 Walkthrough

Walkthrough

The desktop map interface now uses shared map-glass surfaces. Theme elevation tokens, corner radius values, fallback styling, reduced-motion rules, and dialog elevation were updated.

Changes

Map glass theme consolidation

Layer / File(s) Summary
Shared theme foundation
packages/ui/src/globals.css, apps/geolibre-desktop/src/index.css, packages/ui/src/components/dialog.tsx
Adds map-glass, theme-aware elevation tokens, a smaller base radius, reduced-motion rules, and stronger dialog elevation.
Map overlay surfaces
apps/geolibre-desktop/src/components/layout/*, apps/geolibre-desktop/src/components/legend/MapLegendPanel.tsx
Replaces repeated background and backdrop-blur utilities with map-glass on map controls, status surfaces, banners, and the legend panel.
Panel and story surfaces
apps/geolibre-desktop/src/components/panels/*, apps/geolibre-desktop/src/components/storymap/*
Applies map-glass to simulator, animation, sun, compose, and chapter navigation surfaces.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: craun718, pythonbass

Poem

A rabbit hops through glassy light,
Map panels shimmer clear and bright.
Cool shadows settle, soft and low,
While gentle motion starts to slow.
Shared styles cross each map-bound space,
And every pane finds matching grace.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main UI changes: shared map-glass styling, theme-aware shadows, and a reduced base radius.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/ui-glass-and-motion

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Biome (2.5.6)
apps/geolibre-desktop/src/index.css

File contains syntax errors that prevent linting: Line 6: Tailwind-specific syntax is disabled.; Line 22: Tailwind-specific syntax is disabled.; Line 59: Tailwind-specific syntax is disabled.; Line 95: Tailwind-specific syntax is disabled.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed: dependency version conflict. Check your lock file or package.json.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

🔍 Cloudflare PR preview

Item Value
Site https://aacdbaa4.geolibre-preview.pages.dev
Demo app https://aacdbaa4.geolibre-preview.pages.dev/demo/
Commit fbd0f1b

Comment thread apps/geolibre-desktop/src/index.css Outdated
Comment thread apps/geolibre-desktop/src/components/layout/MapGrid.tsx
Comment thread apps/geolibre-desktop/src/index.css
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

All four inline comments posted successfully.

Code review

Bugs

  • map-glass (unlayered CSS) silently kills hover:bg-* background fills, not just the bg-background conflict it was designed to solve. Cascade-layer precedence is resolved before specificity, so an unlayered rule beats every layered rule for the same property — including :hover variants, which have higher specificity but are still inside Tailwind's utilities layer. This hits three real elements introduced by this PR: CollaborationStatusBadge.tsx's session-status toggle (hover:bg-accent), and MapGrid.tsx's Cesium 2D/3D toggle, remove-pane button, and the layers Button variant="outline" (all carry hover:bg-accent). Their hover background highlight no longer visually applies. High confidence — this follows directly from documented CSS Cascade Layers semantics. (apps/geolibre-desktop/src/index.css, MapGrid.tsx:168,182,220, CollaborationStatusBadge.tsx:452)
  • The new theme-aware shadow scale doesn't cover shadow-xs, only sm/md/lg/xl. shadow-xs is what @geolibre/ui's core form primitives use (Input, Textarea, Select, ColorField, ColorRampSelect) plus 7 more app-level sites, so effectively every text input/select/color field in the app is still on Tailwind's stock 10%-black shadow — invisible in dark mode, the exact problem this PR set out to fix. Medium-high confidence. (apps/geolibre-desktop/src/index.css:86-91)

Quality

  • NetcdfCubeSetupDialog.tsx's "drawing" banner (fixed inset-x-0 top-4 z-50, rendered in place of the modal while it "steps aside" over the map) is structurally identical to the migrated MapModeBanner banners, but still uses plain bg-background/95 shadow-lg rather than map-glass. It wasn't touched by this PR (not in the diff) so it's likely just missed rather than deliberate, since it doesn't match any of the three documented exclusions (chart content, dialogs, DesktopShell's scrim). Medium confidence, minor.
  • Two separate @theme { ... } blocks in index.css (one for fonts, one for the shadow scale) — Tailwind v4 merges them fine, so this is a pure style nit, not worth blocking on. Low confidence / non-issue.

Security: none found.

Performance: none found beyond what the author already flagged (untested backdrop-filter GPU cost, explicitly called out as unverified in the PR description).

CLAUDE.md adherence: The scoped-override guidance ("add scoped overrides in index.css, never edit node_modules") is followed correctly; no new external tile/map hosts are introduced so the Tauri CSP allowlist doesn't need updates; no i18n strings were added. No violations found.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/geolibre-desktop/src/components/legend/MapLegendPanel.tsx (1)

467-473: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Keep the legend panel at the stronger opacity.

The comment documents that /90 text washed out in dark theme over bright map content, but map-glass applies 0.85 alpha behind the backdrop filter. Add/keep a stronger legend-specific glass opacity or preserve the previous opacity while retaining the blur and saturation, then update the comment to describe the final rule.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/geolibre-desktop/src/components/legend/MapLegendPanel.tsx` around lines
467 - 473, Update the legend panel element identified by panelRef and its
surrounding opacity comment so the panel uses a stronger legend-specific glass
opacity than map-glass’s 0.85 alpha, while retaining the existing blur and
saturation behavior. Preserve the intended dark-theme text contrast and revise
the comment to accurately describe the final opacity rule.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/geolibre-desktop/src/components/layout/CollaborationStatusBadge.tsx`:
- Line 452: Preserve hover feedback for the glass controls by adding a stronger
interactive glass hover variant or moving the hover surface to a child element.
Apply the fix at CollaborationStatusBadge.tsx:452, MapGrid.tsx:168,
MapGrid.tsx:182, and MapGrid.tsx:220, ensuring each control’s hover appearance
remains visible.

In `@apps/geolibre-desktop/src/index.css`:
- Around line 54-66: Verify the performance of the .map-glass backdrop-filter on
target hardware, including several visible migrated map panels on low-end
integrated GPUs, and address any unacceptable rendering or interaction
degradation before release.

---

Outside diff comments:
In `@apps/geolibre-desktop/src/components/legend/MapLegendPanel.tsx`:
- Around line 467-473: Update the legend panel element identified by panelRef
and its surrounding opacity comment so the panel uses a stronger legend-specific
glass opacity than map-glass’s 0.85 alpha, while retaining the existing blur and
saturation behavior. Preserve the intended dark-theme text contrast and revise
the comment to accurately describe the final opacity rule.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5eff4dcb-c4bb-4ea8-87af-96d6320fc73a

📥 Commits

Reviewing files that changed from the base of the PR and between 556589f and ed3ffb5.

📒 Files selected for processing (13)
  • apps/geolibre-desktop/src/components/layout/BoundsRestrictionIndicator.tsx
  • apps/geolibre-desktop/src/components/layout/CollaborationStatusBadge.tsx
  • apps/geolibre-desktop/src/components/layout/MapGrid.tsx
  • apps/geolibre-desktop/src/components/layout/MapModeBanner.tsx
  • apps/geolibre-desktop/src/components/layout/QuickAnalysisBanner.tsx
  • apps/geolibre-desktop/src/components/legend/MapLegendPanel.tsx
  • apps/geolibre-desktop/src/components/panels/FlightSimulatorPanel.tsx
  • apps/geolibre-desktop/src/components/panels/RouteAnimationPanel.tsx
  • apps/geolibre-desktop/src/components/panels/SunPanel.tsx
  • apps/geolibre-desktop/src/components/storymap/StoryMapComposeBar.tsx
  • apps/geolibre-desktop/src/components/storymap/StoryMapPresenter.tsx
  • apps/geolibre-desktop/src/index.css
  • packages/ui/src/globals.css

Comment thread apps/geolibre-desktop/src/index.css Outdated
- Move .map-glass into Tailwind's utilities layer (@Utility) instead of leaving
  it unlayered. Unlayered CSS beats every layered declaration for the same
  property, and cascade-layer precedence resolves before specificity, so the
  unlayered rule also beat `hover:bg-accent` — killing the hover fill on
  MapGrid's two pane buttons and the CollaborationStatusBadge toggle. Confirmed
  dead in the built app before the fix (idle == hovered on all three), and
  restored after (idle rgba(17,21,28,0.85) -> hover rgb(46,53,66) = --accent).
  The @supports fallback is nested inside the utility so it stays in the layer;
  hoisting it out would reintroduce the same bug where backdrop-filter is
  unsupported.

- Switch MapGrid's layers trigger from Button variant="outline" to "ghost".
  Inside the utilities layer, outline's own bg-background ties with map-glass on
  specificity and won on order, so that button rendered opaque beside its glass
  siblings. ghost sets no base background and still supplies hover:bg-accent;
  the border is restored explicitly. (bg-transparent was tried first and is
  worse — tailwind-merge drops bg-background, but bg-transparent then beats
  map-glass and the button renders fully see-through.)

- Add --shadow-xs and bare --shadow to the elevation scale. Only sm/md/lg/xl
  were redefined, but shadow-xs is what @geolibre/ui's form primitives use
  (input, textarea, select, color-field, color-ramp-select) plus 7 app sites, so
  every input, textarea, select and colour field in the app was still on the
  invisible-in-dark 10% black this scale exists to fix. Verified: a real input's
  shadow now resolves to rgba(0,0,0,0.4) in dark mode. shadow-2xl and
  shadow-inner are unused and left out, with a note to extend if that changes.
Comment thread apps/geolibre-desktop/src/index.css
Comment thread apps/geolibre-desktop/src/index.css
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Code review

Bugs

  • None found in the changed lines themselves — the map-glass utility, the ghost-variant swap in MapGrid.tsx, and the shadow-token redefinitions all behave as documented when checked against how they're consumed (Tailwind cascade-layer/specificity rules, --background's raw-HSL-triplet format, twMerge behavior in Button). Confidence: medium-high.

Security

  • No issues found — this PR only touches CSS custom properties, a Tailwind @utility, and className strings; no new user input, network calls, or dynamic values. Confidence: high.

Performance

  • The backdrop-filter: blur(12px) saturate(140%) cost under real GPU compositing is explicitly called out by the author as unverified (only measured on software rendering); not re-verifiable from static review, but worth taking seriously before merge. Confidence: low (matches the author's own caveat, no new evidence either way).

Quality

  • apps/geolibre-desktop/src/index.css (reduced-motion block, ~line 109-118): the blanket animation-iteration-count: 1 !important also freezes the ~70 animate-spin loading indicators used throughout processing dialogs/panels for users with prefers-reduced-motion set — they'll render as a static frozen icon instead of continuing to signal progress during genuinely long operations. Confidence: medium.
  • apps/geolibre-desktop/src/components/layout/NetcdfCubeSetupDialog.tsx:100-103 — the "drawing an extent" banner (fixed inset-x-0 top-4 z-50 wrapper, bg-background/95 ... shadow-lg, no blur) is functionally the same "floating info banner while interacting with the map" pattern that this PR consolidates elsewhere (e.g. MapModeBanner's directionsActive/reverseGeocodeActive banners), but it wasn't migrated to map-glass. It looks like a 12th component that fits the stated consolidation goal but was missed — not commentable inline since this file isn't part of the diff. Confidence: medium-high.

CLAUDE.md

  • No violations found. The change stays within token-driven CSS as described, doesn't touch node_modules, and the guidance around RTL/logical utilities and Tailwind CSP hosts isn't implicated by any of the changed lines. Confidence: high.

Inline comments posted:

  1. apps/geolibre-desktop/src/index.css:76 — the documented shadow-scale mapping claims shadow-xl is for "modal dialog," but the shared Dialog/DialogContent primitive (unchanged by this PR) still uses shadow-lg, so actual modals don't get the step this comment says they do.
  2. apps/geolibre-desktop/src/index.css:109-118 — the reduced-motion guard's effect on indeterminate loading spinners (see Quality above).

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

🔍 GitHub Pages PR preview

Item Value
Site Deploy failed. See the job log.
Demo app Unavailable
Commit fbd0f1b

- Exempt indeterminate progress indicators from the reduced-motion guard. The
  blanket `animation-iteration-count: 1` gave every spinner a single 0.01ms
  iteration and then froze it mid-rotation, so during a long raster/segmentation/
  conversion job the UI would read as hung — a worse outcome for the same user
  than the abrupt transitions the guard exists to fix. 70 animate-spin sites and
  6 animate-pulse were affected. Slowed rather than stopped (1.5s / 3s, still
  infinite): the preference targets large vestibular-triggering motion, which a
  small in-place spinner is not, so this keeps the "still working" signal while
  calming it. Verified under emulated prefers-reduced-motion: animate-spin
  resolves to 1.5s/infinite and animate-pulse to 3s/infinite, while a decorative
  `animate-in fade-in-0` is still suppressed to 0.00001s/1.

- Bump Dialog from shadow-lg to shadow-xl. The scale documents shadow-xl as
  "modal dialog", but the shared primitive every modal renders through was still
  on shadow-lg — the same step as "panel floating over the map" — so the
  ladder's one-step-per-surface invariant was false for the one component that
  most literally is a modal dialog. Bumping the primitive makes the documented
  mapping true rather than aspirational.
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Good, self-contained. I've reviewed all 14 changed files (component class-name migrations to map-glass, the new @utility/@theme blocks in index.css, the elevation tokens and radius change in globals.css, and the dialog shadow bump), checked the CSS cascade-layer/specificity reasoning against Tailwind v4 semantics, verified the ghost+explicit-border substitution in MapGrid.tsx against cn/twMerge behavior, and confirmed the claims in the PR body (unused shadow-2xs/shadow-2xl/shadow-inner, single shadow bare usage in slider.tsx, shadow-xs consumers, positive derived radius values) against the actual source. No test asserts on the touched class strings. I found no inline-comment-worthy issues, so I'm not posting any inline comments.

Code review

Bugs: None found. The map-glass@utility layering, the MapGrid.tsx outlineghost + explicit border swap (needed because twMerge/cascade-layer precedence made the old outline variant's bg-background beat map-glass), and the derived --radius calc (0.375rem - 2px/4px stay positive) all check out against the surrounding code. (Confidence: high)

Security: No user input, no injection surface — this is CSS/className-only churn. (Confidence: high)

Performance: The PR itself flags the untested backdrop-filter: blur(12px) saturate(140%) GPU compositing cost as a follow-up to verify on real hardware; I can't evaluate that without a GPU, so flagging it here as inherited risk rather than a new finding. (Confidence: n/a — can't verify statically)

Quality: Pre-existing dropdown-menu.tsx SubContent (shadow-lg) and a few untouched floating panels (e.g. AssistantPanel.tsx, NetcdfCubeSetupDialog.tsx) don't follow the new elevation-mapping table (popover/dropdown → shadow-md, map-floating → map-glass), but none of these files are part of this diff, so this is pre-existing drift, not a regression introduced here. (Confidence: low — cosmetic, out of scope)

CLAUDE.md: No violations — no i18n strings added, no RTL-sensitive physical positioning introduced, no node_modules edits, and the MapLibre-control-styling change goes through index.css as required. (Confidence: high)

Overall this is a clean, well-reasoned, self-documenting CSS/design-token refactor; I don't have findings that warrant inline comments.

@giswqs
giswqs merged commit 6d54b35 into main Aug 7, 2026
34 checks passed
@giswqs
giswqs deleted the feat/ui-glass-and-motion branch August 7, 2026 19:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants