Visual refresh: two column layout and easy themeability#197
Open
aJanuary wants to merge 2 commits into
Open
Conversation
Move navigation out of the page header and into a persistent left sidebar, giving a two-column shell (sidebar + scrolling main column). Below 768px the sidebar collapses into a drawer toggled from a top bar. Implement the drawer as a native <dialog> opened with showModal(), so the platform provides the backdrop, focus trap, focus restore, Escape to close, and inerting of the background while it is open. Layer on the parts the element doesn't give us: a CSS :has() rule locks body scroll while it is open, a click outside the dialog box dismisses it, a matchMedia listener closes it when the viewport grows back past the breakpoint, and a route-change effect closes it after navigation. The drawer slides in/out via @starting-style and allow-discrete transitions where supported, degrading to appear/disappear on older baselines. Add a NavIcon component and per-item icons for the nav links, including optional icons on NAVIGATION.EXTRA config entries via a built-in ICON_NAME set or a custom ICON_URL, and swap the help-text close label for a FaTimes icon. Move HelpText out of the header into the main column and flatten the footer markup to suit the new layout. Replace the program item's text selection label with a star icon (filled when selected, outline when not). The checkbox stays in the DOM and focusable but is visually hidden; a screen-reader-only label gives it a Select/Unselect action name, and focus-visible styling on the star keeps it keyboard-operable.
Replace the ad-hoc hard-coded color variables with a structured palette:
1. Inputs - a few tint knobs (--brand-tint, --gray-tint, --info-tint,
--danger-tint) that drive everything.
2. Palette - gray/brand/info/danger ramps (steps 50-950) plus shadow
and utility colors, derived from the inputs with
color-mix() against per-step bases.
3. Semantic - the variables the rest of the CSS references (--main-bg,
--button-primary-bg, ...), mapped onto palette entries.
Semantic mappings live once in App.css and are shared by both modes;
light and dark differ only in the ramp inputs (base colors and mix
amounts) supplied by lightmode.css and darkmode.css. Re-theming the
whole site is now a matter of changing --brand-tint.
Drive dark mode off <html data-theme="light|dark"> resolved in
AppRoutes from the "browser"/"light"/"dark" setting, and resolve it
before first paint via an inline script in index.html to avoid a flash.
This replaces the lazy-loaded ThemeSelector/LightStyle/DarkStyle
components, which are removed. Also document the system in the README.
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.
This contains two big changes:
I chose to put them in the same PR because the second depends on the first, and it felt awkward to stack it into two PRs. But if you'd prefer, I can split them apart. They are in two separate commits.
The primary motivation for the two column layout is that as we start adding more things in (such as the login link) the horizontal navigation was getting difficult to fit in. Moving it to a vertical list down the side makes it feel less cramped.
On smaller devices, it switches to a drawer that is opened by pressing the burger button. I chose to keep this always visible in a fixed header, as that felt most idiomatic. However, it does sacrifice some vertical screen-space.
While working on this, I realised I was having to make up colours, and try and hunt around the existing set to work out what ones would be most suitable. This, combined with prior experiences trying to theme the colours around a cons brand colour, let to the second part of the work.
We define a palette of colours (using variables with the structure
--<palette>-<brightness>. These are then what are referenced by the rest of the CSS. This makes it much easier to use consistent colours, because you're not having to invent a new shade of gray, or find out which grays have been used before.These palettes can be hand-picked. Or, for convenience, they can be derived from a handful of "tint" variables. For most cons without a dedicated graphic designer on hand to come up with the palettes for them, they should be able to get away with just setting
--brand-tint,--gray-tintand--info-tintto the cons brand colour and have something that looks reasonable in both light and dark mode.