## Motivation and Context Opening https://ruby.sdk.modelcontextprotocol.io/ briefly showed a black half-circle at the bottom of the screen. The theme preference script in `head_custom.html` called `window.jtd.setTheme` on every page load. That helper rewrites the `href` of the render-blocking color stylesheet link, which detaches the loaded stylesheet and refetches it, so the page paints unstyled until the replacement arrives. During that window the search magnifier SVG, sized only by CSS, rendered at its fallback size and appeared as a large black half-circle near the bottom of the viewport. The site sets no `color_scheme`, so the default stylesheet is identical to the light one and most visitors paid the flash for a no-op swap. This change replaces the `jtd.setTheme` call with a local swapper that: - Leaves the stylesheet untouched when the resolved theme already matches (treating `default` as `light`). - Swaps non-destructively otherwise: the new link is inserted next to the current one and the old link is removed only after the new stylesheet has loaded. On error the new link is dropped and the page keeps its current styles. - Sets `blocking="render"` on the new link so supporting browsers hold first paint until the dark stylesheet arrives. It also pre-applies the dark background and text colors in `custom.scss`, keyed on the `data-theme` attribute that is set synchronously in the head, to soften the light-colored first paint for dark-preference visitors in browsers without `blocking="render"` support. ## How Has This Been Tested? Mirrored the live site locally, patched the inline script with the new code, and drove it in Chrome: - Unpatched baseline reproduced the old behavior: the link `href` was rewritten and `just-the-docs-light.css` was fetched in addition to `just-the-docs-default.css`. - Patched light and system-light loads keep the original link untouched with no extra stylesheet request. - Patched dark loads settle on a single `just-the-docs-dark.css` link, with `jtd.getTheme()` still reporting the right theme. - Rapid toggling keeps at most two color stylesheet links and settles on exactly one matching the final preference. - With `just-the-docs-dark.css` returning 404, the failed link is dropped and the page stays styled. ## Breaking Changes None.
77 lines
1.8 KiB
SCSS
77 lines
1.8 KiB
SCSS
.docs-header-controls {
|
|
display: flex;
|
|
height: 3.75rem;
|
|
align-items: stretch;
|
|
justify-content: flex-end;
|
|
margin-left: auto;
|
|
}
|
|
|
|
@media (min-width: 50rem) {
|
|
.docs-header-controls {
|
|
height: 100%;
|
|
padding-right: 1rem;
|
|
}
|
|
}
|
|
|
|
.docs-icon-button.site-button {
|
|
width: 3.75rem;
|
|
justify-content: center;
|
|
padding: 0;
|
|
color: inherit;
|
|
background-color: transparent;
|
|
border: 0;
|
|
cursor: pointer;
|
|
font: inherit;
|
|
text-decoration: none;
|
|
}
|
|
|
|
.docs-icon {
|
|
display: block;
|
|
width: 1.25rem;
|
|
height: 1.25rem;
|
|
background-color: currentColor;
|
|
-webkit-mask-position: center;
|
|
-webkit-mask-repeat: no-repeat;
|
|
-webkit-mask-size: contain;
|
|
mask-position: center;
|
|
mask-repeat: no-repeat;
|
|
mask-size: contain;
|
|
}
|
|
|
|
.docs-icon--github {
|
|
-webkit-mask-image: url("/assets/images/icons/github.svg");
|
|
mask-image: url("/assets/images/icons/github.svg");
|
|
}
|
|
|
|
.docs-icon--theme {
|
|
-webkit-mask-image: url("/assets/images/icons/theme-system.svg");
|
|
mask-image: url("/assets/images/icons/theme-system.svg");
|
|
}
|
|
|
|
:root[data-theme-preference="light"] .docs-icon--theme {
|
|
-webkit-mask-image: url("/assets/images/icons/theme-light.svg");
|
|
mask-image: url("/assets/images/icons/theme-light.svg");
|
|
}
|
|
|
|
:root[data-theme-preference="dark"] .docs-icon--theme {
|
|
-webkit-mask-image: url("/assets/images/icons/theme-dark.svg");
|
|
mask-image: url("/assets/images/icons/theme-dark.svg");
|
|
}
|
|
|
|
:root[data-theme="dark"] {
|
|
color-scheme: dark;
|
|
}
|
|
|
|
/*
|
|
* Applied before the dark stylesheet finishes loading, so browsers that
|
|
* do not support blocking="render" avoid a light-colored first paint.
|
|
* Values match $grey-dk-300 and $grey-lt-300 from the dark color scheme.
|
|
*/
|
|
:root[data-theme="dark"] body {
|
|
background-color: #27262b;
|
|
color: #e6e1e8;
|
|
}
|
|
|
|
:root[data-theme="light"] {
|
|
color-scheme: light;
|
|
}
|