From ce92275e138710055035a1a045090a847f5325f3 Mon Sep 17 00:00:00 2001 From: keirsalterego Date: Sun, 24 May 2026 00:09:57 +0530 Subject: [PATCH] fix(theme): permanent dark mode + sidebar always open + arrows on edges Three bugs the first deploy surfaced: 1. The mode picker offered light/dark/navy/etc but the brand is void-only. Customers reading at 2am should never see white. 2. The sidebar was hidden by default on a fresh visit because of how mdBook reads localStorage. The chapter list was effectively invisible. 3. When the sidebar IS open and the viewport is between 1080px and 1380px (most laptop screens), mdBook's chrome hides the wide previous/next arrows and shows mobile inline arrows at the bottom. The user saw no side arrows. Fixes: - book.toml: default-theme and preferred-dark-theme both set to "navy" so mdBook starts dark. - theme/css/variables.css: every built-in theme class (.light, .navy, .coal, .ayu, .rust, plus :root and html) resolves to the same dark palette. A stale localStorage preference cannot flash a light page. Theme picker hidden via display:none because the choice does nothing. - theme/head.hbs: a tiny synchronous script pre-sets the mdbook-theme and mdbook-sidebar localStorage keys so a fresh visitor lands on dark + sidebar-open before the page paints. - theme/css/typography.css: explicit @media override that keeps the wide nav arrows visible whenever the sidebar is open, with higher specificity than mdBook's built-in chrome rule. Plus explicit left/right + float pinning on .nav-chapters.previous and .next so any RTL or specificity edge case can't flip them. Plus a belt-and-braces dark body background rule that paints before any JS or theme class can change it. - meta name="theme-color" updated to #0a0a0b (pitch). Palette is pure brand void per product.md: #0a0a0b page background (pitch) #050505 sidebar background (void) #14141a raised surface, table header #ece3cc primary text (bone on void) #ff9156 links (ember-3 for AA on void) #ff6a3d active accents (ember-2) #ffe6b0 inline code colour (marrow) Verified locally: build emits `` on every page, theme CSS bundle includes the nav-wide-wrapper override and the !important background paint, fonts.googleapis.com preconnect still present. --- book.toml | 11 ++-- theme/css/typography.css | 75 +++++++++++++++++++++++++ theme/css/variables.css | 117 ++++++++++++++------------------------- theme/head.hbs | 36 +++++++----- 4 files changed, 147 insertions(+), 92 deletions(-) diff --git a/book.toml b/book.toml index de87da4..ae822b1 100644 --- a/book.toml +++ b/book.toml @@ -20,10 +20,13 @@ build-dir = "book" create-missing = false [output.html] -# Use the brand colour for the in-page accent and the website meta tags. -# Light theme is the daylight reading mode (bone palette). Dark theme -# is the void palette. Both are styled by theme/css/variables.css. -default-theme = "light" +# Vyrox docs are dark-only. The brand spec calls for the void / pitch +# surface and customers reading at 2am should not be flashed with +# white. We set both the default theme and the preferred-dark theme +# to "navy" (our void-palette override) and our variables.css makes +# every other built-in theme name fall through to the same dark +# colour set so a user who picks a different theme still sees dark. +default-theme = "navy" preferred-dark-theme = "navy" # Smarter punctuation handling. mdBook would otherwise turn the "--" diff --git a/theme/css/typography.css b/theme/css/typography.css index 5000084..522a45d 100644 --- a/theme/css/typography.css +++ b/theme/css/typography.css @@ -261,3 +261,78 @@ pre { .content h4 { font-size: 1.25rem; } .content table { font-size: 1.35rem; } } + +/* ------------------------------------------------------------------- + * Layout fixes for the chapter-arrow nav. + * + * mdBook's default chrome hides the wide previous/next arrows when + * the sidebar is open AND the viewport is narrower than 1380px. That + * leaves only the mobile inline arrows at the bottom of the page, + * which is what someone in the middle viewport band actually sees. + * The fix: keep the wide arrows visible across the full sidebar-open + * range so the layout reads as "sidebar on the left, content in the + * middle, arrows on the edges". Overrides go in this file because we + * load it after mdBook's chrome.css. + * ------------------------------------------------------------------- */ +@media only screen and (max-width: 1380px) { + /* When the sidebar is open, do NOT swap to mobile-style nav. + Keep the wide arrows on the left and right edges. */ + #mdbook-sidebar-toggle-anchor:checked ~ .page-wrapper .nav-wide-wrapper { + display: block; + } + #mdbook-sidebar-toggle-anchor:checked ~ .page-wrapper .nav-wrapper { + display: none; + } +} + +/* ------------------------------------------------------------------- + * Explicit arrow positioning. mdBook's chrome already puts + * `.previous { float: left }` and `.next { float: right }`, but a + * couple of `[dir=rtl]` and specificity edge cases can flip them on + * some viewports. We pin the positions with higher-specificity rules + * that ignore direction since the docs are LTR. + * ------------------------------------------------------------------- */ +nav.nav-wide-wrapper a.nav-chapters.previous { + left: var(--page-padding); + right: auto; + float: left; +} + +nav.nav-wide-wrapper a.nav-chapters.next { + right: var(--page-padding); + left: auto; + float: right; +} + +/* The mobile nav stays as a fallback for viewports under 1080px. We + only show it when there is genuinely no room for the wide arrows. */ +@media only screen and (max-width: 1080px) { + .nav-wide-wrapper { display: none !important; } + .nav-wrapper { display: block !important; } +} + +/* ------------------------------------------------------------------- + * Sidebar default-visible safety net. + * + * head.hbs pre-sets the localStorage key, but on the very first paint + * before JS runs we want the sidebar visible on any viewport wide + * enough to support the side-by-side layout. mdBook's default applies + * `sidebar-visible` to based on width; we re-assert here so a + * CSS-only client (or one with JS disabled) still sees the chapters. + * ------------------------------------------------------------------- */ +@media only screen and (min-width: 1080px) { + html:not(.js) .sidebar { transform: none !important; } + html:not(.js) .page-wrapper { + margin-inline-start: calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width)) !important; + } +} + +/* ------------------------------------------------------------------- + * Paint the dark background before any stylesheet that follows can + * override it. Belt-and-braces against a flash of white if our + * variables.css loads later than expected on a cold browser cache. + * ------------------------------------------------------------------- */ +html, body { + background-color: #0a0a0b !important; + color: #ece3cc; +} diff --git a/theme/css/variables.css b/theme/css/variables.css index 753e2f0..a7bf353 100644 --- a/theme/css/variables.css +++ b/theme/css/variables.css @@ -1,80 +1,45 @@ /* * Vyrox docs theme variables. * - * The target visual is a clean reference doc in the style of the Rust - * book (https://doc.rust-lang.org/stable/book/). Plain near-white - * background, high-contrast text, a single accent colour for links - * and active sidebar items, no decorative borders. + * Dark-only by design. The brand surface is "void" and the docs are + * read in operator contexts where a white page is the wrong choice. + * Every built-in mdBook theme class (.light, .navy, .coal, .ayu, .rust) + * resolves to the same dark colour set so a stale localStorage + * preference cannot flash a light page. * - * The brand still shows up through the ember accent and the heading - * face, but it does not fight the prose. - * - * mdBook ships several built-in themes. We override only the - * variables we need; everything else falls through to the upstream - * defaults. + * The palette comes from product.md: + * void #050505 page background + * pitch #0A0A0B raised surface + * graphite #14141A sidebar surface + * ash #1F1F26 borders, rules + * bone #ECE3CC primary text on void + * clay #6B5E48 muted text on void + * marrow #FFE6B0 inline code colour + * ember #E8462E primary accent + * ember-2 #FF6A3D active links, active sidebar + * ember-3 #FF9156 link colour, brighter for AA contrast + * rust #8B2A12 search-highlight background */ :root { - /* Slightly wider than mdBook's default to fit the longer tables - in the API reference without horizontal scroll. The Rust book - uses 750px; we go to 820px because our API tables are wider. */ --content-max-width: 820px; --sidebar-target-width: 290px; } -/* ------------------------------------------------------------------- - * Light theme. The default and the recommended reading experience. - * Near-white background, near-black text, ember accent. - * ------------------------------------------------------------------- */ -.light, html:not(.js) { - --bg: hsl(0, 0%, 100%); - --fg: hsl(0, 0%, 12%); - - --sidebar-bg: #fafafa; - --sidebar-fg: hsl(0, 0%, 12%); - --sidebar-non-existant: #aaa; - --sidebar-active: #c93a25; - --sidebar-spacer: #f0f0f0; - - --scrollbar: #8f8f8f; - - --icons: #747474; - --icons-hover: #c93a25; - - --links: #c93a25; - --inline-code-color: #6b1a08; - - --theme-popup-bg: #fafafa; - --theme-popup-border: #d8d8d8; - --theme-hover: #ececec; - - --quote-bg: #f6f6f6; - --quote-border: #e5e5e5; - - --warning-border: #c9892f; - - --table-border-color: hsl(0, 0%, 92%); - --table-header-bg: hsl(0, 0%, 96%); - --table-alternate-bg: hsl(0, 0%, 98%); - - --searchbar-border-color: #cccccc; - --searchbar-bg: #ffffff; - --searchbar-fg: #0e0a05; - --searchbar-shadow-color: rgba(0, 0, 0, 0.08); - --searchresults-header-fg: #777; - --searchresults-border-color: #e5e5e5; - --searchresults-li-bg: #fafafa; - --search-mark-bg: #ffe6b0; - - --color-scheme: light; -} - -/* ------------------------------------------------------------------- - * Dark theme (navy). Selected automatically for users whose OS - * prefers dark. Pitch black background, warm-cream text, brighter - * ember accent for AA contrast. - * ------------------------------------------------------------------- */ -.navy { +/* + * Single declaration block applied to every theme name. mdBook switches + * the html class but every class resolves to the same values. We pin + * `color-scheme: dark` on :root too so browser-provided UI (scrollbars, + * form controls) match. + */ +:root, +html, +.light, +.rust, +.coal, +.navy, +.ayu, +html:not(.js) { --bg: #0a0a0b; --fg: #ece3cc; @@ -117,15 +82,17 @@ --color-scheme: dark; } -/* ------------------------------------------------------------------- - * Selection colour. Subtle ember tint on light, slightly stronger on - * dark so the highlight reads through the lower-contrast surface. - * ------------------------------------------------------------------- */ -.light ::selection { - background: rgba(232, 70, 46, 0.16); - color: #0e0a05; -} -.navy ::selection { +::selection { background: rgba(255, 106, 61, 0.32); color: #ece3cc; } + +/* + * Hide the theme picker entirely. Dark is the only mode; offering a + * choice that does nothing is worse than offering no choice. + */ +.icon-button#theme-toggle, +.icon-button[aria-controls="theme-list"], +#theme-list { + display: none !important; +} diff --git a/theme/head.hbs b/theme/head.hbs index ec6f513..b39b974 100644 --- a/theme/head.hbs +++ b/theme/head.hbs @@ -1,25 +1,35 @@ + + - - + +