Skip to content

FE-1705: Add bottom toolbar layouts and a blur fallback for its glass - #9694

Draft
kube wants to merge 1 commit into
mainfrom
claude/bottombar-optimization-variations-7b5e3d
Draft

kube wants to merge 1 commit into
mainfrom
claude/bottombar-optimization-variations-7b5e3d

Conversation

@kube

@kube kube commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Important

Experimental
Adds the Bottom toolbar layout setting. Glass finish by browser ships for everyone.

Summary

Before this PR, the bottom toolbar drew its glass through an SVG backdrop filter that only Chromium renders, so Safari and Firefox showed a flat panel. The bar had one layout, two glass segments, while the design file carries a single-segment version with an Edit / Simulate switch at its end.

Every segment now paints a blurred backdrop first and, on Chromium, fades the refraction in over 0.4s. A Bottom toolbar setting picks between three layouts: the split bar, the design file's mode-switch bar, and a single bar holding every control. All three share the frame that keeps the bar clear of the panels and collapses controls when room runs short.

Links

Changes

Glass finish

  • Every toolbar segment is a GlassSurface with a blur layer under its fill

    Chromium adds the refractive layer, which fades in over 0.4s while the blur fades out and unmounts.
    Safari and Firefox keep a 14px blur.

  • Browser detection reads userAgentData.brands, with the user agent string as fallback

    Only Chromium paints an SVG filter given to backdrop-filter, and CSS.supports cannot tell.
    Chrome on iOS renders with WebKit and gets the blur.

Layouts

  • Bottom toolbar setting under General picks Split, Mode switch or Single

    Persisted values are validated on load, so a layout a build no longer has falls back to Split.

  • BottomBar becomes the frame: lane, placement against the panels, collapse context and layout dispatch

    The three layouts render from the same props and building blocks.

  • Mode-switch layout follows the design file's single segment

    Cursor square tinted blue on the edit face and purple on the simulate face, that face's controls, chart-line panel toggle, Edit / Simulate switch at the end.
    Starting a run turns the bar to the simulate face.
    While the run holds the net, the edit segment is locked and its tooltip says to reset.

  • Single layout holds every control in one segment

    Cursor, AI assistant and add tools, diagnostics, filled Play, scrubber and playback settings, panel toggle at the end.

  • Playback settings can open from the current speed next to Play

    Mode-switch layout uses it; the gear stays the default elsewhere.

  • Toolbar buttons and the cursor trigger take a tone and a filled appearance

Motion

  • Collapse and reveal curves retuned

    Collapse runs 180ms on the standard curve with the opacity leading the width.
    Reveal runs 140ms and decelerates.

Known issues

  • Blur-only finish covered by the detection tests, not checked by eye in Safari or Firefox
  • Collapse and reveal timings have not been measured

Next steps

  • Screenshots of the two new layouts for the user guide

Test coverage

Extraction onto main preserved the complete feature patch without conflicts. All 37 focused glass, Settings keyboard, and preference tests passed. The earlier integrated stack passed package builds, unit tests, types, lint, and architecture checks. Browser recordings and manual checks listed below predate extraction.

  • glass-finish.test.ts:

    Chromium brands, the user agent fallback, and Chrome on iOS taking the blur.

  • Existing @hashintel/petrinaut unit suite.
  • Storybook DOM probes and screenshots:

    All three layouts on the SIR story, including mid-playback; refractive layer active and blur layer unmounted on Chromium.

How to test

  • Open Petrinaut preview on Vercel
  • Menu > Load example > SIR
  • Menu > User settings > General > Bottom toolbar > Mode switch

    Expect one segment, blue cursor square, pencil selected at the right end

  • Press the play segment of the switch

    Expect purple cursor square, Play, speed and chart toggle

  • Press Play

    Expect scrubber and pause, pencil segment disabled

  • Viewport controls > Settings > Viewport > Bottom toolbar > Single

    Expect one segment with a filled blue Play

  • Open the bottom panel

    Expect the bar to lift with the panel

@kube kube self-assigned this Sep 13, 2026
@vercel

vercel Bot commented Sep 13, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
hash Ready Ready Preview Sep 15, 2026 10:17pm UTC
petrinaut Ready Ready Preview Sep 15, 2026 10:17pm UTC
petrinaut-docs Ready Ready Preview Sep 15, 2026 10:17pm UTC
1 Skipped Deployment
Project Deployment Actions Updated
hashdotdesign-tokens Ignored Ignored Preview Sep 15, 2026 10:17pm UTC

Request Review

@github-actions github-actions Bot added area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team labels Sep 13, 2026
Comment on lines +11 to +12
const chromeOnIosUserAgent =
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/128.0.0.0 Mobile/15E148 Safari/604.1";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Semgrep identified an issue in your code:
A hardcoded username in plain text is identified. Store it properly in an environment variable.

To resolve this comment:

🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.

💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by node_username.

You can view more details about this finding in the Semgrep AppSec Platform.

Comment on lines +9 to +10
const firefoxUserAgent =
"Mozilla/5.0 (Macintosh; Intel Mac OS X 14.6; rv:130.0) Gecko/20100101 Firefox/130.0";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Semgrep identified an issue in your code:
A hardcoded username in plain text is identified. Store it properly in an environment variable.

To resolve this comment:

🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.

💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by node_username.

You can view more details about this finding in the Semgrep AppSec Platform.

Comment on lines +7 to +8
const safariUserAgent =
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Safari/605.1.15";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Semgrep identified an issue in your code:
A hardcoded username in plain text is identified. Store it properly in an environment variable.

To resolve this comment:

🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.

💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by node_username.

You can view more details about this finding in the Semgrep AppSec Platform.

Comment on lines +5 to +6
const chromeUserAgent =
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Semgrep identified an issue in your code:
A hardcoded username in plain text is identified. Store it properly in an environment variable.

To resolve this comment:

🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.

💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by node_username.

You can view more details about this finding in the Semgrep AppSec Platform.

Comment on lines +5 to +6
const chromeUserAgent =
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36";
Comment on lines +7 to +8
const safariUserAgent =
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Safari/605.1.15";
Comment on lines +9 to +10
const firefoxUserAgent =
"Mozilla/5.0 (Macintosh; Intel Mac OS X 14.6; rv:130.0) Gecko/20100101 Firefox/130.0";
Comment on lines +11 to +12
const chromeOnIosUserAgent =
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/128.0.0.0 Mobile/15E148 Safari/604.1";
@kube
kube changed the base branch from main to codex/fe-1658-petrinaut-ai-right-sidebar September 13, 2026 22:51
@github-actions github-actions Bot added type/eng > backend Owned by the @backend team area/tests New or updated tests area/apps area/apps > hash.design Affects the `hash.design` design site (app) labels Sep 13, 2026
@kube
kube force-pushed the codex/fe-1658-petrinaut-ai-right-sidebar branch from a137724 to a2ae04a Compare September 13, 2026 22:52
@kube
kube force-pushed the claude/bottombar-optimization-variations-7b5e3d branch from 3ca3c90 to 7c133d9 Compare September 13, 2026 22:52
@github-actions github-actions Bot removed type/eng > backend Owned by the @backend team area/tests New or updated tests area/apps area/apps > hash.design Affects the `hash.design` design site (app) labels Sep 13, 2026
@kube
kube added this pull request to stack #9699 September 13, 2026 22:54
@kube
kube removed this pull request from stack #9731 September 15, 2026 02:30
@kube
kube force-pushed the codex/fe-1601-experimental-defaults branch from 3a9b38d to a588778 Compare September 15, 2026 02:30
@kube
kube force-pushed the claude/bottombar-optimization-variations-7b5e3d branch from 005144e to 2fcab7d Compare September 15, 2026 02:30
@kube
kube added this pull request to stack #9733 September 15, 2026 02:31
@kube
kube removed this pull request from stack #9733 September 15, 2026 14:48
@kube
kube added this pull request to stack #9740 September 15, 2026 14:48
@kube
kube force-pushed the claude/bottombar-optimization-variations-7b5e3d branch from 2fcab7d to 5f61b5c Compare September 15, 2026 20:00
@kube
kube force-pushed the codex/fe-1601-experimental-defaults branch from a588778 to 57f157b Compare September 15, 2026 20:00
@kube
kube force-pushed the claude/bottombar-optimization-variations-7b5e3d branch from 5f61b5c to d105f41 Compare September 15, 2026 20:39
@kube
kube force-pushed the codex/fe-1601-experimental-defaults branch from 57f157b to 7ffaf7e Compare September 15, 2026 20:39
@kube
kube force-pushed the codex/fe-1601-experimental-defaults branch from 7ffaf7e to bc64cc1 Compare September 15, 2026 21:19
@kube
kube force-pushed the claude/bottombar-optimization-variations-7b5e3d branch from d105f41 to dfffea9 Compare September 15, 2026 21:19
@kube
kube removed this pull request from stack #9740 September 15, 2026 22:05
@kube
kube changed the base branch from codex/fe-1601-experimental-defaults to main September 15, 2026 22:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team

Development

Successfully merging this pull request may close these issues.

2 participants