feat(console): modular panels, AI at bottom, Space Grotesk wordmark, light/dark/auto theme - #36
Merged
Merged
Conversation
…Space Grotesk wordmark, light/dark/auto theme - Wrap each main-view block as a self-contained .module with a uniform header that doubles as a drag handle and hosts a collapse chevron. Collapse state and module order persist in localStorage. - Move the AI Prompt panel to the bottom of the main view (scroll-to-reach instead of pinned near the top). - Wordmark now uses Space Grotesk via a scoped --font-brand var; editorial module titles keep Fraunces. - Add Auto/Light/Dark theme control (Settings > Appearance). Light is a warm-paper theme sharing the accent palette; an inline head script resolves the theme before first paint to avoid a flash. Preference persists and Auto tracks the system scheme live. - All element IDs preserved, so engine/app.js bindings are untouched. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ocalStorage Symmetric with the order-restore Array.isArray guard: a corrupted or future-shaped lume.console.moduleCollapsed value is non-iterable, so new Set(...) would throw and abort initModules, disabling both collapse and drag. Guard it and clarify the order-restore comment. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Updates the Console skin (/) UI concept (Euclid) to support a more flexible layout and appearance: panels become modular/collapsible/reorderable with persistence, AI Prompt moves to the bottom, the wordmark font switches to Space Grotesk, and a Light/Dark/Auto theme preference is added (resolved pre-paint to avoid flashing).
Changes:
- Introduces
.modulepanels with a uniform header/drag-handle + collapse control; order and collapse state persist via localStorage. - Adds Light/Dark/Auto theme selection in Settings, with an inline
<head>resolver and live “auto” tracking of system scheme. - Updates branding typography (Space Grotesk for the wordmark) and adds styling for modules + theme segmented control.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| ui-concepts/console-euclid-live/styles.css | Adds brand font var, light theme palette overrides, module UI styling, and theme segmented control styling. |
| ui-concepts/console-euclid-live/index.html | Adds pre-paint theme resolution, converts main panels into reorderable/collapsible modules, moves AI Prompt to bottom, and adds Appearance/Theme control in Settings. |
| ui-concepts/console-euclid-live/app.js | Adds initModules() (collapse + drag reorder + persistence) and initTheme() (persisted preference + live system tracking). |
Comments suppressed due to low confidence (2)
ui-concepts/console-euclid-live/app.js:1449
- Theme preference read from localStorage isn’t validated. If the stored value is anything other than
auto|light|dark(e.g. manual edits or stale data), it will set an unexpecteddata-themeand the UI can end up in a partially styled state. Clamp the value to the known set.
let pref = store.get() || "auto"; // "auto" | "light" | "dark"
const btns = $$("#themeSeg .theme-seg-btn");
ui-concepts/console-euclid-live/app.js:1455
- The theme segmented control only updates a CSS class; assistive tech won’t get an explicit pressed/selected state. Set
aria-pressed(or a radio-style pattern) when applying the active choice so screen readers announce the current selection.
const apply = () => {
root.setAttribute("data-theme", resolve(pref));
btns.forEach((b) => b.classList.toggle("active", b.dataset.themeChoice === pref));
};
Comment on lines
+16
to
+19
| var p = localStorage.getItem("lume.console.theme") || "auto"; | ||
| var d = p === "auto" | ||
| ? (window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark") | ||
| : p; |
Comment on lines
+427
to
+428
| .module.drop-before{ box-shadow: inset 0 2px 0 0 var(--c-red); } | ||
| .module.drop-after{ box-shadow: inset 0 -2px 0 0 var(--c-red); } |
Comment on lines
+1421
to
+1424
| e.preventDefault(); | ||
| if (e.dataTransfer) e.dataTransfer.dropEffect = "move"; | ||
| const target = e.target.closest("[data-module]"); | ||
| if (!target || target === dragEl || target.parentElement !== view) return; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Console skin (
/) only — Euclid untouched.What changed
.modulewith a uniform header that doubles as a drag handle and hosts a collapse chevron. Collapse state and module order persist in localStorage.--font-brandvar; editorial module titles keep Fraunces.<head>script resolves the theme before first paint (no flash). Auto tracks the system scheme live; preference persists.Safety / scope
app.jsdevice bindings untouched. The newinitModules/initThemelogic is pure DOM + localStorage, no network surface.try/catch-wrapped; stored values only touch classList/attributes/order (noinnerHTML).Verification
Served locally and verified in-browser (demo mode, zero console errors): collapse + drag-reorder + persistence work; Light/Dark flips both Console and Settings views cleanly; Space Grotesk renders; theme + layout survive reload.
Review
Self-reviewed via
/code-review. One low-severity robustness nit fixed in a follow-up commit (guard collapse-state restore against non-array localStorage, symmetric with the order-restore guard).Source-only; device deploy is still
python3 scripts/sync_web.py→pio run -t uploadfs.🤖 Generated with Claude Code