Skip to content

[rebrand] Migrate blockly workspace to design-system semantic tokens#73785

Merged
alex-m-brown merged 5 commits into
stagingfrom
alex/workspace-chrome-semantic-tokens
Jul 15, 2026
Merged

[rebrand] Migrate blockly workspace to design-system semantic tokens#73785
alex-m-brown merged 5 commits into
stagingfrom
alex/workspace-chrome-semantic-tokens

Conversation

@alex-m-brown

@alex-m-brown alex-m-brown commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Migrate the shared workspace chrome that renders around Blockly in every Blockly-using lab to design-system semantic tokens - so once the rebrand shifts the neutral palette, these surfaces follow instead of sticking out at legacy values. Also folds in a tiny stray raw-white cleanup in Sprite Lab's ListItemThumbnail.

Scope: four files. Only color values change. Block styles themselves are untouched

Surface Legacy Semantic token Match
.darkHeader / .darkHeaderUnfocused bg $neutral_dark (#292F36) var(--background-neutral-primary-inverse) exact (default theme)
.darkHeader / .darkHeaderUnfocused color $neutral_white (#FFFFFF) var(--text-neutral-white-fixed) exact
.darkHeaderUnfocused button span color $neutral_dark (#292F36) var(--text-neutral-primary) exact (default theme)
.headerButton (Settings / Version History / Show Code) color $neutral_dark (#292F36) var(--text-neutral-primary) exact
.headerButton bg $neutral_white (#FFFFFF) var(--background-neutral-primary) exact
.headerButton:hover bg $neutral_dark10 (#EAECEF) var(--background-neutral-tertiary) near-exact (#eaeef2)
.headerButton:disabled bg $light_gray (#949ca2) var(--background-neutral-disabled) close, semantic role match (~#d4dae1, visibly lighter)
.headerButtonPressed bg / color $white / $purple var(--background-neutral-white-fixed) / var(--text-brand-purple-primary) exact
.blocklyToolbox sidebar bg #DDDDDD (from cdoTheme.js) var(--background-neutral-tertiary) close, semantic-by-intent
.blocklyToolboxCategoryLabel (category text) Blockly-default #333 inherited from body var(--text-neutral-primary) (#292F36) close (~1% RGB shift)
.blocklyFlyoutBackground (flyout panel fill) Blockly-default #DDDDDD var(--background-neutral-tertiary) matches toolbox bg by design
.blocklyScrollbarHandle fill Blockly-default #cccccc var(--background-neutral-quinary) (#c6ced6) near-exact
.blocklyDropDownDiv bg Blockly-default white var(--background-neutral-primary) exact
.blocklyDropDownDiv border #dadce0 var(--borders-neutral-primary) (#d4dae1) very close
ListItemThumbnail.jsx:14 root bg raw 'white' var(--background-neutral-white-fixed) exact

Not touched (deliberate):

  • Blockly block colors themselves (per design's "avoid the blocky area for now")
  • .blocklyMainBackground (workspace SVG grid pattern) - fills via <pattern> cells, not a solid color; needs a deeper grid-cell change - follow-up chip
  • .headerButtonMinecraft variants (#606060 / #bfbfbf) - intentional Minecraft aesthetic, not generic neutrals
  • .legacyHeaderButton (marked TODO for removal, Javalab-only)
  • cdoTheme.js's toolboxBackgroundColour: '#DDDDDD' (the .blocklyToolbox CSS override wins via !important)
  • Toolbox category hover state (rgba(255,255,255,0.2) translucent overlay - adapts to any bg)

Why !important on the Blockly overrides: .blocklyToolbox, .blocklyToolboxCategoryLabel, .blocklyFlyoutBackground, .blocklyScrollbarHandle, and .blocklyDropDownDiv are styled by Blockly's own default stylesheet (and for the category label, body { color: #333 } from application.css). Without !important, our rules lose to specificity/inheritance. Same pattern as the existing cdoCss.ts rules.

Blast radius: every Blockly-using lab in the repo - Sprite Lab, Game Lab, App Lab, Web Lab, Dance, Studio, Maze, Turtle, Flappy, Bounce, Craft, Music, Jigsaw, Java Lab, Python Lab. .darkHeader and .headerButton render on the pane header in most of these; the Blockly toolbox / flyout / scrollbar / dropdown overrides apply wherever Blockly is injected.

Links

Testing story

Before / After (default theme) — pane header, header buttons, sidebar, category text, flyout panel, workspace scrollbar, and field dropdown popup should look visually close to staging. Sidebar bg shifts about two shades lighter (#DDDDDD#eaeef2); the disabled header-button bg goes noticeably lighter (#949ca2#d4dae1); everything else is near-exact hex.

Screenshot 2026-07-13 at 3 47 01 PM Screenshot 2026-07-13 at 3 49 29 PM Screenshot 2026-07-13 at 3 49 05 PM

Manual QA — please walk through:

Pane header + header buttons

  • Dark pane header ("Blocks" / "Workspace" bar): dark charcoal in default theme, deep magenta under ?brand=codeai-next.
  • Header buttons (Settings / Version History / Show Code): white bg + dark text in default; light pink bg + pink text under ?brand=codeai-next.
  • Hover a header button: bg goes light gray in default, light pink in pink test.
Screenshot 2026-07-13 at 3 52 17 PM
  • If any header button is disabled (e.g., Version History with no saved history): bg is a lighter, more subdued gray than staging — this is the semantic --background-neutral-disabled (#d4dae1 in default, was #949ca2). Design ask if the lighter disabled state is acceptable.
Screenshot 2026-07-13 at 3 57 47 PM

Blockly toolbox + flyout

  • Toolbox sidebar bg (behind "World / Sprites / Locations / ..." category list): light gray in default, light pink in pink test.
  • Category text: near-black in default, hot pink in pink test.
  • Click a category — flyout panel opens with the block palette. Flyout bg matches the toolbox (both --background-neutral-tertiary).
  • Blocks themselves render at their normal colors — deliberately unchanged.

Blockly workspace chrome

  • Add enough blocks to trigger horizontal or vertical scrollbars on the workspace. Scrollbar handle: mid-gray in default (#c6ced6, was #cccccc), pink under ?brand=codeai-next.
Screenshot 2026-07-13 at 4 00 43 PM
  • Click a block field dropdown (e.g., the sprite selector dropdown on a make new sprite at block). Popup bg: white in default, light pink in pink test. Border: subtle light gray in default, pink in pink test.
Screenshot 2026-07-13 at 4 01 16 PM

Sprite Lab Costumes / Backgrounds

  • Open the Costumes tab. Sprite thumbnails render on white background as before (ListItemThumbnail root uses --background-neutral-white-fixed).
Screenshot 2026-07-13 at 4 01 50 PM

Cross-lab spot check

  • Game Lab default theme: same surfaces render correctly. Block styles unchanged.
Screenshot 2026-07-13 at 4 02 38 PM
  • App Lab default theme: dark header + header buttons render correctly. App Lab has additional workspace chrome (phone frame) — confirm nothing else breaks.
Screenshot 2026-07-13 at 4 03 00 PM
  • Dance / Music / Studio / Maze / Turtle / Flappy / Craft / Jigsaw / Java Lab / Python Lab: spot-check
Screenshot 2026-07-13 at 4 03 32 PM Screenshot 2026-07-13 at 4 04 36 PM

Browsers + a11y

  • Firefox and Safari.
  • Keyboard nav through toolbox categories: focus outlines still visible.
  • Screen reader: category names still announced correctly.

Make sure you ask @moshebaricdo :

  • Sidebar bg / flyout bg move from #DDDDDD to --background-neutral-tertiary (#eaeef2 in default). About two shades lighter. Fine, or swap to --background-neutral-secondary (even lighter), or drop to primitive --neutral-gray-20 (#d4dae1, closer to legacy)?
  • Disabled header-button bg moves from #949ca2 (mid gray) to --background-neutral-disabled (#d4dae1, visibly lighter). OK as the semantic value, or should we pick a darker disabled token?
  • Field-dropdown popup border moves from #dadce0 to --borders-neutral-primary (#d4dae1). Practically indistinguishable — flagging for completeness.
  • Category text goes from Blockly-default #333 to --text-neutral-primary (#292F36). Barely visible — both are near-black.

alex-m-brown and others added 5 commits July 10, 2026 14:51
Per design guidance on the Sprite Lab rebrand: the shared workspace
chrome (dark "Blocks / Workspace" pane header, Blockly toolbox sidebar
background, and Blockly toolbox category text) is hard-coded to legacy
neutral values and will visibly stick out once the rebrand ships new
neutral colors. Migrate these three surfaces to semantic tokens so they
follow the rebrand automatically.

Changes:
- apps/src/common-styles.module.scss: .darkHeader and .darkHeaderUnfocused
  swap $neutral_dark -> var(--background-neutral-primary-inverse),
  $neutral_white -> var(--text-neutral-white-fixed). The button-span dark
  text in the unfocused state uses --text-neutral-primary.
- apps/src/blockly/addons/cdoCss.ts: add !important rules for
  .blocklyToolbox background and .blocklyToolboxCategoryLabel color, so
  the semantic tokens override Blockly's default stylesheet and the
  body-level inherited color.
- apps/src/p5lab/AnimationTab/ListItemThumbnail.jsx: swap the raw
  backgroundColor: 'white' to var(--background-neutral-white-fixed).

Not touched: block colors themselves (per design's "avoid the blocky
area for now"), Blockly workspace SVG background (it uses a grid pattern
fill, not a solid color - separate follow-up), and cdoTheme.js's legacy
toolboxBackgroundColour: '#DDDDDD' (the CSS override wins via specificity
+ !important, keeping this diff tighter).

Blast radius: every Blockly-using lab in the repo (Sprite/Game/App/Web/
Dance/Studio/Maze/Turtle/Flappy/Bounce/Craft/Music/Jigsaw/Java/Python).
Cross-lab QA sweep required.

Verified live via pink-test theme: dark header renders --neutral-black
inverse (deep magenta in pink theme), toolbox background resolves to
--background-neutral-tertiary (light pink), category labels to
--text-neutral-primary (hot pink). Semantic wiring proven; the rebrand
sweep will pick up whatever the neutral tokens become.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Per design guidance, the Settings / Version History / Show Code header
buttons (which live inside the .darkHeader dark bar migrated in the prior
commit) were still hardcoded to legacy $neutral_dark / $neutral_white /
$neutral_dark10 / $light_gray / $white / $purple.

Migrate .headerButton (the current button style) to semantic tokens:
- color/bg default -> --text-neutral-primary / --background-neutral-primary
- hover bg -> --background-neutral-tertiary (was $neutral_dark10 #EAECEF,
  new resolves to #eaeef2 in default - near-exact hex match)
- :disabled + &Disabled bg -> --background-neutral-disabled (was $light_gray
  #949ca2, new resolves to #d4dae1 in default - visibly lighter, semantic
  role matches). Design ask if the lighter disabled state is acceptable.
- span color -> --text-neutral-primary
- &Unfocused bg -> --background-neutral-primary
- &Pressed: bg -> --background-neutral-white-fixed, color ->
  --text-brand-purple-primary, hover color -> --text-neutral-white-fixed

Deliberately left alone:
- .headerButtonMinecraft (intentional Minecraft-lab aesthetic with
  #606060 / #bfbfbf hardcoded values, not generic neutrals)
- .legacyHeaderButton (marked with TODO for removal, Javalab-only)

Verified in pink-test: Settings / Version History / Show Code buttons all
resolve to --background-neutral-primary (#fff8fc light pink) with
--text-neutral-primary (#d63384 pink). Semantic wiring proven.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The Blockly flyout panel (opens when a toolbox category is selected,
shows the actual draggable blocks) was still filled with Blockly's
legacy #DDDDDD default. Matches the same visual weight as the toolbox
sidebar today, so use the same --background-neutral-tertiary token for
both surfaces to keep them visually paired through the rebrand.

.blocklyFlyoutBackground is an SVG rect where Blockly sets the fill as
an attribute; a CSS fill: var(...) rule wins here with !important, same
pattern as the .blocklyToolbox override.

Verified live via pink-test: fill resolves to #ffe0ef (--background-
neutral-tertiary in pink theme), consistent with the toolbox background.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two more shared Blockly chrome surfaces still on legacy hex under the
pink-test audit:

- .blocklyScrollbarHandle: fill was Blockly-default #cccccc (mid-light
  gray). Mapped to var(--background-neutral-quinary) which resolves to
  #c6ced6 in default theme (near-exact hex match; the closest DS neutral
  primitive to the legacy value).
- .blocklyDropDownDiv: bg was white, border was #dadce0 (Blockly-default
  popup shown for field dropdowns like variable pickers). Mapped bg to
  var(--background-neutral-primary) (exact white in default) and border
  to var(--borders-neutral-primary) (#d4dae1 in default, very close to
  legacy #dadce0).

Both use !important to override Blockly's default stylesheet (same
pattern as the .blocklyToolbox / .blocklyFlyoutBackground overrides
earlier in this PR).

Verified live in pink-test:
- scrollbar handle: fill rgb(255, 179, 220) = --background-neutral-quinary
- dropdown bg: rgb(255, 248, 252) = --background-neutral-primary
- dropdown border: rgb(255, 214, 236) = --borders-neutral-primary

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@alex-m-brown alex-m-brown changed the title Migrate shared workspace chrome to design-system semantic tokens [rebrand] Migrate blockly workspace to design-system semantic tokens Jul 13, 2026
@alex-m-brown
alex-m-brown requested review from a team and moshebaricdo July 13, 2026 20:55
@alex-m-brown
alex-m-brown marked this pull request as ready for review July 13, 2026 20:55

@moshebaricdo moshebaricdo 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.

🥳🥳

@alex-m-brown
alex-m-brown merged commit 7ffe553 into staging Jul 15, 2026
8 checks passed
@alex-m-brown
alex-m-brown deleted the alex/workspace-chrome-semantic-tokens branch July 15, 2026 19:08
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.

3 participants