Skip to content

[feat] 38 R11: one look from the tokens, no native scrollbars, flowbite out (38-cleanup) - #339

Open
AlexZ005 wants to merge 107 commits into
feat/ui-bfrom
feat/38-cleanup
Open

AlexZ005 wants to merge 107 commits into
feat/ui-bfrom
feat/38-cleanup

Conversation

@AlexZ005

@AlexZ005 AlexZ005 commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator

38 R11: one look from the tokens, no native scrollbars, flowbite out (38-cleanup)

Done when (ROADMAP R11): CI enforces the tokens. npm run check:tokens is now a hard fail in ci.yml, and two new lints guard the rest of R11.

This branch also merges the other 1.28 lanes first, as the brief asks: feat/38-int-a (tokens, lock, inspector, windows), then 38-icons, 38-modals, 38-hud and 38-mobile. 6ece8b21 removes the six duplicate Icon imports those merges produced.

Phases

  1. Gates (ef6e19a4)
    • scripts/check-tokens.cjs hard-fails by default (--warn only reports).
    • Data colours are exempted with a tokens-ok: <reason> line pragma, or a tokens-ok-begin … tokens-ok-end block.
    • The five colliding tokens move from .tp-ui to :root, so light and custom themes reach every surface (NOTES-38 Feature/save-load #8).
    • app.css hides every platform scrollbar.
    • New lint tests/unit/noNativeScrollbars.test.js: every scroller must use use:minimalScroll or tp-noscrollbar, and no stylesheet may style a native bar (NOTES-38 Feature/sidebar-menu #1).
  2. Migration (7f5ea5d4, 219 files)
    • Every component paints from the tokens.
    • The last orange selection and armed states become the one blue accent; orange (--live) stays for Play and recording.
    • Every scroller uses the minimal bar.
    • flowbite is removed from everything except the pending Settings files (see below). Users becomes a ModalDialog plus a native popover; Recording and ReplaceModel become ModalDialogs; Controls' Listgroup becomes a plain div.
    • New lint tests/unit/noFlowbite.test.js.
  3. Dead CSS (dddf1ee4)
    • 38 theme.css remap selectors that no component uses any more are removed. The 20 that flowbite's own Modal, Button, Toggle and Checkbox themes still emit are kept, because the Settings window still uses flowbite.
    • hud.css .hud-dot and phone.css .resize-grip are removed.
  4. Battery fixes (38ee96e5, d68a9f2e, d8ec45d5)
    • Profile menu closed the instant it opened (a regression from this branch). The menu's own avatar circle sits in the top layer over the trigger, so the opening click was counted as outside. "Outside" is now decided by where the press started.
    • Light theme:
      • The logo tile was transparent: a scoped .burger rule painted an undefined --color-form, and theme.css's !important remap used to hide that.
      • The default avatar silhouette vanished into the 3D scene; the circle over the viewport now has an opaque fill.
      • The colour-picker hex text inherited --border as its colour (1.1:1 contrast).
    • HUD editor:
      • The selected screen row now uses --accent-soft; --surface-active put the red ✕ at 2.3–2.9:1 in the exotic themes.
      • The stage stays dark in every theme, because it stands in for the 3D viewport (exempted with tokens-ok).
    • Notification sheet 44 px wide on phones (from the merges). 38-hud's .hud-tr glass uses backdrop-filter, which made the group the containing block for its fixed #notif-panel sheet and for #peers-popover. The glass moves to a ::before.
    • Lock fixture: fixtures/lock/shortcuts.json gains the help.palette row (38-hud's Ctrl+K, NOTES-38 Feature/connected-peers #14), added by hand rather than re-recorded. It was the only red in lock-shortcuts on the union.
  5. svelte-check floor ratcheted from 318/47 to 312/41 (5855f25a).

Gates on the head

  • check:tokens clean: 277 files, 13 pending another branch
  • vitest 138 files / 1597 tests
  • svelte-check 312/41 = the baseline
  • vite build green

Behaviour lock and battery

  • Lock suites on the head 5855f25a: all 8 green. lock-settings 263, lock-settings-b 345, lock-dragrow 383, lock-dragrow-sync 15, lock-shortcuts 154, lock-panels 126, lock-search 11, lock-objectlist 18. Also green on the head: mobile-map 81, mobile-ui-fixes 28, peers-popover 21.
  • Colour and marker suites: 31 run. The reds were re-run as an A/B against the union snapshot 6ece8b21.
    • Fixed (they also failed on the union snapshot, but with fewer failures): mobile-ui-fixes, theme-text-sweep.
    • Fixed (green on the union snapshot, so introduced here): menu-keyboard-tab.
    • Fixed although it was already red on the union: mobile-map (the notification sheet above).
    • Already red on the union, identically, and not this lane's surface:
      • editor-ui-33 E3, the corner pixels beside Play (38-hud's well).
      • panel-shortcuts 3b.1, a stale premise: Animation has been on the default bar since 1.19.
      • file-preview "dragging really resizes": height +14 px only.
      • animation-curves "right-clicking a graph KEY cancels the browser menu": no contextmenu event is recorded at all.

Screenshots

Before/after pairs for 46 surfaces × 1440×900 and 390×844 × dark, light and custom are in lanes-30/after-38/38-cleanup/gallery/, named <surface>-<size>-<theme>-{before,after}.png.

Left for 38-int-b (QUESTIONS-38-cleanup Q1)

The 13 Settings files belong to 37-settings (core #335, 1.26). The gates skip them through one list, scripts/redesign-pending.json. When 1.26 merges:

  1. Empty that list.
  2. Swap Settings.svelte's <Modal> for ui/ModalDialog.
  3. Fix the 5 raw colours 37-settings left.
  4. Drop flowbite and flowbite-svelte from package.json, plus the @plugin/@source lines in app.css.
  5. Re-run the gates.

Follow-ups / design calls

  • VR panels keep their old orange hover/selection (three.js data). Reading a VR palette from the tokens at mount would finish them.
  • Token wishes:
    • --on-scene / --scene-halo (would replace the HUD stage literal)
    • --shadow-color
    • --playhead
    • --on-warn
    • a success fill
    • role-badge hues
  • Design calls the user may want to see:
    • the Explorer anchor and picked cards are both blue
    • 3D preview backgrounds follow the theme
    • timeline selected keys stay amber
    • the armed tp-seg uses accent-fill
    • the Users profile popover lost flowbite's 100 ms close fade

NOTES-38 applied: #1, #8, #9, plus #14 in the lock fixture.

🤖 Generated with Claude Code

AlexZ005 and others added 30 commits October 6, 2026 00:32
…con-through-Icon.svelte note (38-tokens R0)

- the CLAUDE-snippet from the redesign handoff, path adjusted to the cloud checkout
  (../cloud/docs/design/redesign/)
- icons note: SPEC 7 routes every icon (static ones too) through ui/Icon.svelte, sizes
  16/20; direct @lucide/svelte imports are legacy until R10

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…theme.json mapping, light values, check:tokens (38-tokens R2)

- src/styles/tokens.css: bg-app / surface-1/2/inset / border(-strong/-input) / text(-2/-muted/
  -faint) / accent(-soft/-muted/-text) / live / warn-text / danger / badge + control metrics,
  4px spacing, rem type scale (mobile < 640px: 16/14/16, 44px targets, 51x31 toggles)
- the five names the legacy themes already own (--text --text-2 --border --accent --surface-2)
  carry SPEC values only inside .tp-ui: dark leaves them undefined and ~400 call sites render
  their per-site fallbacks, so the default theme is unchanged
- light: its own block; green / 8-bit / contrast / custom .theme.json DERIVE every token from
  the legacy keys they already carry; old dark exports get the dark values
- app.css: @theme inline colour + type utilities (bg-surface-2, text-text-muted, text-body …),
  @theme static radii + font-ui / font-ui-mono (IBM Plex, self-hosted, OFL)
- themes.js: REDESIGN_TOKENS in THEME_TOKENS; export leaves DERIVED tokens derived
- scripts/check-tokens.cjs (npm run check:tokens, CI warning step): hex / rgb / Tailwind
  palette in src/components, --strict for R11, a CLEAN list that fails even now; unit test

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…(38-tokens R3)

- SPEC 2 primitives, every root in the .tp-ui token scope: WindowChrome (modal / panel / tool,
  mobile nav bar, footer; chrome only - open/pin/dock stay the caller's), Tabs (tablist,
  automatic activation, panel wiring), Segmented (radiogroup, one tab stop), Chips (single /
  multi), Toggle (aria-pressed, 40x24 / 51x31), Button (primary on --accent-fill = #2f6fe0,
  secondary, outline, ghost, warn-text, danger, icon + count/dot, live), Badge (scope / status
  dot / count / live), SettingRow (keeps .setting-row + .sr-name for Settings search; wide /
  stack), PropRow (wraps DragRow UNCHANGED: props + events pass through, restyled via the vars
  DragRow reads), NavRow, EmptyState, Sheet (peek / half / full, flick, drag to dismiss)
- Section grows variant=card (Settings; off the Inspector filter + deep links) and
  variant=panel (collapsible chevron); the default legacy markup is byte-identical
- from the design review page's kit: Menu, Toast, Checkbox (list pick only), SearchField,
  Slider; tokens --segment-on --axis-x/y/z --on-live --shadow-thumb; light values = the page's
- $lib/ui/roving.js + $lib/ui/sheetSnap.js (pure) with unit tests; Icon map + 13 names
- routes/kit: dev or VITE_UI_KIT=1 builds only (the import is dropped otherwise); every
  primitive in every state, ?theme=dark|light|custom|green|bit8|contrast, live token readout
  and a contrast table (all pairs >= 4.5:1 in dark, light, custom)
- e2e ui-kit (51 checks): tokens per theme, Toggle, Segmented, Tabs, Chips, Sheet detents /
  flick / dismiss, PropRow -> DragRow scrub / Shift / type / arrows / Esc; check:tokens CLEAN
  list covers every new primitive; svelte-check unchanged (318 / 47)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- lockHelpers.cjs: GPU launch (SwiftShader starved the page: 271 ms vs 2 ms per CDP round
  trip), the side-effect fingerprint (localStorage, debug-hook stores, html/body attributes,
  dialogs, broadcasts), idle-noise sampling, a new-undo-entry counter, record/verify fixtures
- lock-settings (+ -b, split for the 8-minute runner cap): every row of the handoff's
  settings-inventory.json — storage key + default, scope (broadcasts = shared), side effects,
  the choices offered, put-back round trip; rows compared by MEANING so a checkbox->Toggle or
  select->Segmented redesign passes; plus a 390x844 pass (rows + defaults)
- fixtures/lock/settings.json recorded on v1.24.0 (two passes, intersected)
- lock.json manifest + npm run e2e:lock (= npm run e2e -- @lock), README section

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- lock-dragrow: scrub (live, no snap-back), Shift fine, Ctrl snap, dead zone, click-to-type
  live + select-all, Enter/Escape/Tab, arrow steps x1/x10/x100, wheel does nothing, undo
  steps, broadcast while scrubbing, min/max clamp — on transforms (+ Settings units and
  typed suffixes), render order, light intensity, shader vec2, Animation length/speed/fps/
  step/key time/key value
- KNOWN Q1-Q4 (QUESTIONS-38-lock): Escape after typing re-commits, stale transform fields
  after Ctrl+Z, per-change/no undo on some fields, label-wrapped fields keep focus — locked
  as they behave today
- lock-dragrow-sync: two peers on local signaling; the peer sees a scrub mid-drag, typed
  values and undo replicate, plus light/shader/Animation fields

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- the keymap registry (= the ? sheet): ids, keys, scope, group, kind
- the sheet: lists every row, focused scope first, filter, Esc, Ctrl+/, works over a modal
- the routing table, recorded: which command each key fires in the viewport, node editor,
  UV / Animation / Shader / HUD editors, a text field and an open modal (actions swapped for
  recorders, so nothing is executed)
- Edit Mesh key mapping, G arms Move in the timeline, hold-W flies only from the viewport,
  the active-mode key toggles the selection away and back, and real effects (gizmo modes,
  duplicate/undo/redo/delete, panels, chat, snapping)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- lockSurfaces.cjs: every window, drawer, dock view, modal, menu and Settings section, opened
  the way the app opens it
- lock-panels: each opens/shows/closes (own control, Escape) as recorded; the Properties pin;
  every toolbar cell's effect; dock tabs
- lock-search: Settings search (every row name + ~100 words) and the Inspector filter
  (object, light, scene) find the same rows/sections
- tools/lock-baselines.cjs: every surface at 1440x900 and 390x844 in dark, light and a custom
  .theme.json, named <surface>-<size>-<theme>-before.png, with an index.html contact sheet

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…troke (38-icons R10)

- Icon.svelte maps 192 lucide names (was 75): the static icons of 69 components moved
  in, plus 18 names menus and the HUD palette were already passing as data and that
  silently drew a box (clipboard-copy/paste, scissors, mountain, the HUD kind glyphs).
- $lib/ui/icons.js: iconSize snaps to 16/20 (UI) or 24/32/48 (placeholder art),
  ICON_STROKE 1.75 (SPEC 7); lucideName for the kebab names. Unit test icons.test.js.
- `tool:<name>` renders the custom domain glyphs (ToolIcon.svelte) through the same
  component, size and stroke; MeshEditPopup/SculptToolbar use it.
- snap={false} only for authored game-HUD content (HudElement) and the checkbox tick.
- Icon sizing by Tailwind class (h-3/w-3) removed; kit primitives drop the redundant
  strokeWidth and use 16/20 (WindowChrome tool/panel, close button).
- tests/unit/iconLint.test.js: no @lucide/svelte or ToolIcon import in components,
  every literal name exists, literal sizes on the scale, data names exist; each guard
  proven by planting a violation.
- svelte-check message list identical to feat/38-tokens (318/47); vitest 131/1572;
  build green, JS total +13 KB raw, main chunk 2.98 -> 2.95 MB.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ud R8, phase 1)

- styles/hud.css: the shared HUD look (hud-glass container, hud-cell icon button,
  hud-fab corner button, hud-count/hud-dot, hud-sep) from tokens only; 38/34 px
  cells on a fine pointer, 44 px on touch
- Controls toolbar: one glass bar, armed cell = accent-soft fill (the glyph keeps
  text-primary-500 only as the marker the dock/controls suites read), Play a 44 px
  --live circle inside the bar; ids, titles, roster, drag and handlers unchanged
- corner buttons (Add, AI, mic, chat, sim transport): the hud-fab look; mic-on and
  open chat/AI use the accent state instead of green/orange; sim Stop = warn ink
- svelte-check 318/47 unchanged

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…orms (WIP)

- InspectorHead: WindowChrome panel header (icon, title, kind badge, pin, close)
  + the SearchField filter; #drawer-label / #inspector-pin / #inspector-search kept
- WindowChrome gains pinId/pinTitle/pinLabel (additive)
- the Inspector is a .tp-ui surface (surface-2, border, window radius, 14px gutter)
- every Inspector Section uses variant="panel"; the panel title also wears
  ui-section-label as the hook the filter, deep links and the lock read
- SliderRow is drawn as PropRow with the same DragRow arguments (step, snap = step x 10)
- transforms / origin / intensity / render order are PropRows; axis fields restyled
  from outside (tokens, mono), axis colours from --axis-x/y/z
- light theme: the !important section-label ink skips .tp-ui surfaces

svelte-check 318/47 (unchanged). Chips, + Light menu, badges, toggles still to do.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…sh/Export off flowbite

- ui/ModalDialog.svelte: native <dialog> + WindowChrome size="modal" header, optional
  bar strip (tabs), one scrolling body, footer. Behaviour copied from flowbite-svelte
  1.33 Dialog/Modal: show()/showModal(), focus-on-open rule (first non-Close control,
  header skipped), cancel/outside-click/toggle handling, 100ms fade, close button
  named "Close", .tp-modal-frame kept for the z-tier + mobile full-screen.
- ConfirmModal / ImportDuplicatesModal: chrome title, answers in the footer with one
  emphasised button (danger for destructive, else the first plain choice primary),
  kit Checkbox (real <input>, ids kept), tokens only; DOM order of answers unchanged.
- PublishExportModal: kit Tabs in the bar (ids publish-export-tab-<id> unchanged),
  id/data-tab on the dialog. ExportPanel: kit Button primary (Build), Toggles for
  Cover image / CDN packs, preset cards with the accent selection, tokens.
- Icon.svelte: + bookmark, columns-2, folder-open, import, loader-circle,
  triangle-alert, upload.
- svelte-check 318/47 (unchanged).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…centre, Objects

WindowChrome gains bare / headerClass / heading / closeAttrs so an existing window keeps
its root (dragWindow, dockable, tabbable, focusStack) and takes only the header; header
action classes (.wc-act, .wc-act-text, .wc-label). New src/styles/windows.css: the one
window surface (.tp-window) and plain field (.tp-field). Objects keeps its header ranking
(search, then label -> icon) and every id/title suites use. Icon map: app-window,
folder-tree, message-square, panel-bottom, settings-2, cog, mic, square.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…iconLint test) (38-icons)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Node editor, Flow Code, Animation, UV editor, Shader editor, HUD editor, Profiler: floating
header = WindowChrome tool (bare), Dock = text action with icon (same titles/ids/aria),
docked views on .tp-dock-panel with .tp-dock-title and icon Undock/Close (.tp-dock-btn).
TabStrips: 40px (56 on a phone) so the strip still covers the tool header, kit tab look.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…irst in the object menu

#1: windows.css replaces the always-on themed bar with a thin thumb on a clear track that
shows only while the pointer is over the scroller (--scrollbar-* tokens still colour it;
high contrast keeps it visible); ContextMenu drops its own visible bar; the burger menu
keeps no bar at all. #5: Properties (opens the Inspector) is the first object action.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…(NOTES-38 #1)

- ModulesManager: ModalDialog (WindowChrome size="modal"), "Install from file…" in the
  header (the one #install-module-zip picker is now always mounted), kit Tabs with counts
  (ids modules-tab-<id>) + a filter field in the strip, modules as LIST ROWS in one card
  (name, mono version, 2-line description, actions, separator, kit Toggle
  enable-module-<id> / enable-user-module-<id>), Badges for reload-to-disable / source /
  gallery tags, EmptyState for an empty User tab, gallery chips with the accent selection
  (data-gal-* hooks kept). Flowbite removed. The User-tab pulse rides a data attribute.
- $lib/ui/minimalScroll.js: one action that hides the native scrollbar on a scroller and
  draws a thin auto-hiding, draggable overlay thumb from tokens; scrolling itself is still
  native (wheel/keys/touch unchanged). Used by every ModalDialog body and the duplicates
  list. tests/unit/minimalScroll.test.js covers the thumb geometry.
- tests: modules-manager / user-modules / perf-stale-modules address the kit Toggle ids
  and the Tabs' aria-selected instead of flowbite's hidden checkbox / .mod-tab.active.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e accent

- environment presets are Chips (onpress re-applies the selected preset, as before);
  Chips gains per-option `id` and `onpress` (additive)
- "+ Hemisphere / + Directional / + Point" -> one "+ Light" menu, Save / Export /
  Import -> "Presets" (MenuButton: the shared Menu under a kit Button; item ids kept)
- Shared / This device badges on Environment, Scene look, Background, Fog, Grid, Snapping
- swatch rows (Sky / ground, Sun color), env-light cards, saved-preset chips in tokens
- every legacy chip in the Inspector loses the orange selected fill (ins-chip-on =
  accent-soft + accent border); quiet buttons, inputs, the multi-selection banner via tokens
- flowbite Buttons in the Inspector -> ui/Button (outline / primary / warn-text, ids kept)
- WindowChrome pin: pinAttrs (spread on the pin button) instead of three props, matching
  38-windows' closeAttrs; transform label column 56px + mono 11px so -0.80 fits
- tests: inspector (badge hook), shader-inspector + physics-colliders (section head hook)

svelte-check 318/47 (unchanged).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…tab strip

Code workspace and Explorer floating headers on WindowChrome (Explorer keeps its R22
ranking via an attachment: search, then label -> folder-tree icon; #explorer-dock and
#explorer-close kept); docked rows use .tp-dock-title / .tp-dock-btn. ContextMenu (so the
object, viewport, toolbar and dock menus) and the Add search box share the .tp-menu box and
32px token rows (44 on a phone), mono shortcuts, faint uppercase sections, one accent for
the checked row. DockTabs recoloured in the tokens, its 22px band untouched.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ratchet

File/model/text previews, Stats and live Profiler keep their own header markup (measured
rankings + suites pin it) and take the WindowChrome tool look via .tp-window > .ui-panel-header;
✕ glyphs -> x icon on the text/model previews. CLEAN += ContextMenu, ContextMenuItems,
DockTabs, AddMenu, AiAssistant, Chat, Objects, TabStrips.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…S-38 #2)

- CharacterPanel on the kit: WindowChrome size="modal" header (#character-close kept as
  its action), chips with the accent selection (role=radio + data-character/head/hat
  kept), "Show my name above me" is a Toggle, colour/ping rows in one card, Cancel /
  Apply (primary) footer, the minimal scrollbar on the body. Tokens only.
- NOTES-38 #2: the drawer resizes by dragging its inner edge (#character-resize, a
  focusable role=separator; arrows step 16/64 px) — the left edge on desktop, the sheet's
  top edge on a phone; the size is a LOCAL pref (characterDrawer:size). The camera frames
  the character in the part of the viewport the drawer leaves free and re-frames when a
  resize ends.
- NOTES-38 #2: Apply AND Cancel return the viewport EXACTLY (position + orbit target):
  after the return flight the pose is written once more with damping briefly off, so a
  hand orbit's momentum cannot carry it past (skipped if anything else took the camera).
- avatar-customise: exact-pose checks after Escape / Apply / an orbit drag + Cancel, and
  the edge resize (width, persistence, re-frame, reopen).
- check-tokens: the migrated modal files join the CLEAN ratchet.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…an list

- every flowbite Checkbox in the Inspector and its sub-panels (sim sections, post stack,
  scene settings) is an InsToggle: label left, kit Toggle right, the SAME props
  (checked / bind:checked / id / onchange) and an event-shaped onchange, so no handler
  changed; the id lands on the Toggle button (aria-pressed)
- raw grey / amber / yellow utilities in the Inspector and its sub-panels mapped onto the
  token utilities (text-text-muted / -faint / -2, border-border(-strong), text-warn-text,
  bg-surface-inset); 10/11px hint text -> text-badge (11px). Inspector raw colours 172 -> 37
- check:tokens CLEAN: InsToggle, InspectorHead, MenuButton, SliderRow
- tests that read these as checkboxes now read aria-pressed: knock-node, play-reach-jump,
  select-through (click, not check), scene-default-material, select-inside-36

svelte-check 318/47 (unchanged).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- PlayBanner: while playing, a glass bar top-centre: the Playing badge (--live),
  "Press Esc to stop" and a Stop button (exitPlay, what Esc does). In a game the
  hint reads "Press Esc for the menu" and the game shell's corner Menu · Esc stays
  the way out; touch shows the badge alone (its own exit button); not in VR, embeds
  or while a HUD menu has the cursor
- scene setting (NOTES-38 #4): Configure Scene > Physics > Play mode > Top banner:
  Show hint / Hide / Custom text — the play block's `banner`, present only when not
  the default, so existing scenes stay byte-identical (vitest playBanner)
- toolbar at <= 520 px: the bar takes the screen width and the cells share it
  (44 px tall); the phone bottom bar itself is 38-mobile's R9
- svelte-check 318/47 unchanged

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…alog

- SessionsManager: both dialogs on ModalDialog (WindowChrome size="modal"); kit Buttons
  with ONE primary per view (Save current scene / Save / Import N …), the rest outline;
  kit Checkbox in the picker rows; EmptyState for no sessions; the row buttons, inputs and
  the grid/list + filter segments restyled from tokens (ss-*), selection = accent-soft +
  accent border; the picker's nested lists use the minimal scrollbar. Every session-* /
  picker-* id and class the suites address is kept. Flowbite removed.
- The import picker closes on cancel (outside click / the close button) the way Escape
  already did — flowbite's unbound open={true} left a closed dialog with the picker alive.
- check-tokens: SessionsManager joins CLEAN.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…Dialog

- CheckpointTimeline: ModalDialog (WindowChrome size="modal"); "Save checkpoint…" is the
  one primary, Close (footer) outline; "Automatic" is a kit Toggle (SPEC §2,
  #checkpoint-show-auto kept); All / This scene as a token segmented control; row
  buttons, rename/note fields and the compare picks from tokens; every cp-* class and
  checkpoint-* id kept. Escape still steps out of compare before closing.
- CheckpointSaveDialog: ModalDialog (sm), Cancel + Save checkpoint (primary) in the
  footer, token fields, ids kept.
- check-tokens: both join CLEAN.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s to the accent tokens

SPEC §1: orange is Play/live only. Inside .tp-window / .tp-dock-panel / .tp-menu the
Flowbite primary scale resolves to --accent-fill / --accent / --accent-text / --accent-soft,
so the Explorer's active folder, view toggles, selected cards and drop targets turn blue
without touching their classes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- TemplatesModal: ModalDialog (WindowChrome size="modal") carrying id="templates-modal";
  the General / Examples / Games / Community tabs are the kit Tabs in the strip under the
  header (ids templates-tab-<id> unchanged, arrow keys now move between them); the tag
  chips and the template cards use the accent selection (accent-soft + accent border,
  accent border on hover/focus); the "needs a module" pill, notice, save corner button
  and links from tokens. data-chip / data-scene-slug / data-scene-save / .tpl-* hooks
  kept. Flowbite removed.
- check-tokens: TemplatesModal joins CLEAN.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- StorageModal: ModalDialog (WindowChrome size="modal"); Rescan outline, Reclaim the one
  emphasised (danger) answer, Close outline; the user's disabled-paint rule kept on the kit
  Button (neutral cursor; Rescan full strength while a scan runs, Reclaim faded while
  nothing is ticked); section header, group cards, rows and links from tokens; the rows'
  own scroller uses the minimal scrollbar. Every storage-* hook (incl. input.tp-check) kept.
- check-tokens: StorageModal joins CLEAN.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
AlexZ005 and others added 30 commits October 6, 2026 22:12
…solved to a COLOUR)

Tailwind 4 has both --color-badge and --text-badge, and `text-badge` emitted the colour, so
every 10/11px hint in the Inspector fell back to 16px (seen in the after shots). Use
text-[length:var(--fs-badge)] — the same token, unambiguous.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…heir own action

- typing "scale" ranks the Scale tool first; Enter sets transformMode
- "Explorer" toggles explorerClose; "Theme" opens Settings with its search seeded
- arrows, Esc, scrim click, empty result, Ctrl+K over an open modal

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- ConnectInfoDrawer: one surface with the pill, the Tabs look (underline, accent),
  kv rows, kit buttons; every class/testid kept (cxd-tab, cxd-knock, drawer-*-row);
  refresh glyph through ui/Icon; 44 px targets on touch
- connection-request card buttons on the kit Button look (grant = filled primary,
  Reject = outlined danger); watching/preview banners take the PlayBanner glass look
- the "no light" prompt moves from a red flowbite Toast to the shared card (Fix and
  the dismiss-and-remember behave as before)
- object-list drop-to-share highlight uses the accent tokens
- Connect/ConnectInfoDrawer/CommandPalette/PlayBanner/AiHudButton/MobileAddButton/
  SimControls/VoiceChat/Toasts token-clean (Controls/Users: only the object list
  and the peers popover remain, 38-windows)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…sition")

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
# Conflicts:
#	src/components/ui/WindowChrome.svelte
…8-mobile R9)

- phone.css re-seats the hud-tr glass group (bell, peers) beside the avatar
  with 44 px cells; the old `> .flex` selector matched nothing after 38-hud
- the Connect sheet: the pill grows (height auto), the invite id takes its
  own row, hud separators + the collapse button hidden
- Connect never collapses to its chip on the phone shell: the bar only shows
  inside the Connect sheet, which is the expanded form (the shell draws its
  own chip)
- mobile-map 75/75; svelte-check 318/47

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e Add list (38-mobile R9)

- every ContextMenu on the phone shell (viewport, Add, object, node editor)
  opens as a bottom sheet at one fixed height; a submenu is a second sheet
  laid exactly over its parent (drill in place) with a Back row on top
  (`.ctx-back`, hidden off the phone shell)
- the bar's Add tab opens the viewport menu rooted at its Add list
  (`viewportMenu.only = 'add'`, additive): the same children as the Add
  submenu, so devices, effects, water and every catalog entry stay one tap
  away; the full viewport menu stays on the long press and More > Viewport tools
- touch: a TAP on a submenu row opens it at once and keeps it open until Back
  or another tap (a finger has no hover; mouse hover-intent unchanged)
- a touch click on a menu row counts only when its press also landed in the
  menu - a long press low on the screen opens the sheet under the finger and
  the lift used to run whatever row was there (the backdrop's own rule)
- mobile-map 81/81: Add list rooted, sheet geometry, drill in place + Back,
  tap Cube adds one and closes; rest() clears menus between rows

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ists inside it); palette field drops the forms focus ring

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…pper it looked for is gone since #14; red on base too)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… sheet below 640px, the floating-window drag runs at 700px (38-mobile R9)

- 24 pass; the 4 desktop profile-circle FAILs are identical on pristine 1.25.0
  (logs/mobile-ui-fixes-AB-125.log, which also fails the 670px mobile pair)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…d is reached by typing

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- a decided dialog stayed on screen for its 100 ms outro after the store that owns it
  moved on; import-duplicates' Reveal check read it as still open
- the fade IN is kept

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
# Conflicts:
#	src/components/DockTabs.svelte
#	src/components/editors/Explorer.svelte
#	src/components/editors/ModelPreviewWindow.svelte
#	src/components/editors/TextEditorWindow.svelte
#	src/components/menu/AiAssistant.svelte
#	src/components/menu/Chat.svelte
#	src/components/menu/Controls.svelte
#	src/components/menu/Inspector.svelte
#	src/components/menu/NotesDrawer.svelte
#	src/components/menu/NotificationCenter.svelte
#	src/components/menu/Objects.svelte
#	src/components/ui/Icon.svelte
#	src/components/ui/Section.svelte
#	src/components/ui/WindowChrome.svelte
…anup

# Conflicts:
#	scripts/check-tokens.cjs
# Conflicts:
#	scripts/check-tokens.cjs
#	src/app.css
#	src/components/menu/AiHudButton.svelte
#	src/components/menu/Connect.svelte
#	src/components/menu/ConnectInfoDrawer.svelte
#	src/components/menu/Controls.svelte
#	src/components/menu/Inspector.svelte
#	src/components/menu/MobileAddButton.svelte
#	src/components/menu/NotificationCenter.svelte
#	src/components/menu/SimControls.svelte
#	src/components/menu/Users.svelte
#	src/components/menu/VoiceChat.svelte
…anup

# Conflicts:
#	src/components/ContextMenuItems.svelte
#	src/components/menu/Connect.svelte
#	src/components/ui/Icon.svelte
…ons/lock merges added (svelte parse errors)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…rs, tokens on :root (38-cleanup)

- tokens.css: the five colliding names (--text/-2, --border, --accent, --surface-2) move from
  .tp-ui to :root in dark and light (R11 removes the last legacy fallbacks); app.css @theme
  inline gains the rest of the semantic set as utilities (on-accent, accent-fill, ink-*,
  surface-active, scrim, control-off, speaking, axis-*, icon-* ...)
- check-tokens.cjs: hard fail by default (--warn reports only), scans src/components +
  src/routes + src/styles minus the token definitions, `tokens-ok: <reason>` line pragma and
  tokens-ok-begin/-end blocks (a bare pragma is itself a violation); CLEAN list retired
- scripts/redesign-pending.json: the 37-settings files the gates skip until that branch merges
- tests/unit/noNativeScrollbars.test.js (NOTES-38 #1): every scroller draws minimalScroll or
  tp-noscrollbar; no stylesheet styles a native bar; app.css hides the platform bar
- theme.css: the 148 native-scrollbar style removed; dark code-editor tokens defined
- minimalScroll thumb reads --text-faint without a fallback

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…minimal bar, flowbite out (38-cleanup)

- ~210 components, the shared stylesheets (ui.css, ui.utilities.css, flow/hud/phone/windows.css)
  and the core modules' node cards moved off raw hex/rgb and the Tailwind gray/primary palette
  onto the semantic tokens: grays -> surface/border/text tokens, the orange selection/armed/
  primary states -> the ONE blue accent (SPEC §1), Play/record/live -> --live, status -> ink-*,
  destructive confirm -> danger; legacy fallbacks (`var(--accent, #ef562f)` ...) dropped
- colours that are DATA keep a `tokens-ok: <reason>` line or block: picker defaults, three.js /
  troika materials (VR panels, pins, measure labels), canvas pixels (UV editor, profiler,
  minimap), node-category hue tables, authored game-HUD looks, the /kit demo data
- NOTES-38 #1: every scroller wears `use:minimalScroll` (context menus, window/sheet bodies,
  lists, CodeMirror's .cm-scroller) or `tp-noscrollbar` (chip/tab/crumb strips, the burger menu)
- flowbite-svelte gone from everything but the 37-settings files: Users (Modal -> ModalDialog,
  Dropdown -> a native top-layer popover keeping #avatar-dropdown, Avatar/Input -> plain),
  RecordingDialog + ReplaceModelModal -> ModalDialog, Controls' Listgroup -> div.obj-scroller,
  WaterPanel/PourPanel -> ui/Button, Tooltips -> title, Toasts' Progressbar -> a token bar,
  Menu's hidden DarkMode removed (themes.js owns the dark class); tests/unit/noFlowbite.test.js
- check:tokens also covers src/modules/**/*.svelte; ci.yml runs it as a hard fail
- e2e selectors that read a palette class as a STATE marker follow the new class (ICON_ON
  text-accent, armed bg-accent-fill, cursor border-accent, error bg-ink-bad/15, ...); the three
  suites that pinned an old literal colour (snap-advanced, notes-v2, flow-background) now
  resolve the token instead

Gates: check:tokens clean (277 files, 13 pending 37-settings), vitest 138 files / 1597,
svelte-check 312/41 (baseline 318/47), build green.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e (38-cleanup)

- theme.css: 38 remap selectors for utilities the R11 migration retired (bg-gray-*/NN
  opacity variants, the bg-primary-900 tints, text-primary-50..400, placeholder-gray-500,
  hover:bg-gray-200, dark:bg-gray-900/60 ...). Kept: every class flowbite-svelte's own
  Modal/Button/Toggle/Checkbox themes still emit, while the Settings window (pending
  37-settings) uses them.
- hud.css .hud-dot and phone.css's .resize-grip selector: nothing renders either.
- Gates: check:tokens clean, vitest 1597/1597, svelte-check 312/41, build green.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… picker ink, HUD screen row (38-cleanup)

Found by the after battery on dddf1ee (A/B against the union snapshot):
- Users: the profile menu closed the instant it opened. Its own avatar circle sits in
  the top layer exactly over the trigger, so the opening press ENDS on that circle and
  Chrome targets the click at the common ancestor - outside both. "Outside" is now
  decided by where the press started (the press-and-click backdrop rule); true at mount,
  since the opening press predates the listener. (mobile-ui-fixes, menu-keyboard-tab)
- Users: the default avatar circle over the 3D viewport takes an opaque --surface-2
  (translucent --surface-active made the light theme's silhouette vanish into the scene);
  list rows keep the translucent fill. The snippet's caller now passes the fill.
- Sidebar: the scoped .burger rule painted an undefined --color-form, which beats every
  utility - the logo tile was transparent; theme.css's !important remap used to hide it.
- Inspector + HudFieldRow colour pickers: --cp-input-color/--cp-text-color from the
  tokens (the hex field inherited --border as its ink: 1.1:1 on light).
- HudEditor: the selected screen row is a selection -> --accent-soft (--surface-active
  read the red delete x at 2.3-2.9:1 in Green/8-bit/High contrast).
- lock fixture: help.palette (38-hud's Ctrl+K, NOTES-38 #14) added to
  fixtures/lock/shortcuts.json by hand - the only red in lock-shortcuts on the union.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…in for the 3D viewport) (38-cleanup)

The migration painted it --bg-app, so the light theme previewed a HUD on a near-white
stage, where the usual white HUD text disappears. It is a picture of the scene the HUD
draws over, so it keeps its literal under a tokens-ok reason.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… (notifications sheet 44px wide on phones) (38-cleanup)

38-hud gave .hud-tr the hud-glass look, whose backdrop-filter makes the group the
containing block for fixed descendants (the CLAUDE.md transform/filter trap). It hosts
#notif-panel, which the phone shell turns into a full-width fixed sheet - measured 44x0 at
x=281, i.e. sized against the group - and #peers-popover under a docked Connect bar.
The glass (fill + blur) moves to a ::before on .hud-tr only; the other hud-glass
containers are untouched. mobile-map: the bell opens the notification centre as a sheet.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The R11 migration removed six errors and six warnings (flowbite components and their
implicit-any props); check-ratchet --update.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.

1 participant