Theming
The entire look is driven by a handful of CSS custom properties. Change the base color and every surface — sidebar, cards, code blocks, buttons — recomputes its own light and dark shadows.
The tokens
:root {
--neu-base: #e4e9f0; /* the one color you pick */
--neu-intensity: 0.16; /* how far light/dark diverge */
--neu-distance: 8px; /* shadow offset */
--neu-blur: 16px; /* shadow blur */
--neu-radius: 16px; /* corner radius */
}
How the shadows are derived
Rather than hand-coding two shadow colors, they are computed from --neu-base
with CSS relative color syntax, which scales each channel — the same math as
a classic neumorphism generator, but live in the browser:
--dark: rgb(from var(--neu-base) calc(r * (1 - var(--neu-intensity)))
calc(g * (1 - var(--neu-intensity)))
calc(b * (1 - var(--neu-intensity))));
--light: rgb(from var(--neu-base) calc(r * (1 + var(--neu-intensity)))
calc(g * (1 + var(--neu-intensity)))
calc(b * (1 + var(--neu-intensity))));
Derive the shadow colors on the element that uses them, not in :root. A
custom property resolves its inner var(--neu-base) at the scope where it is
declared — put it in :root and the shadows freeze to the root color even
after you override --neu-base deeper in the tree.
Light and dark
Dark surfaces need more intensity, because multiplicative contrast shrinks as the
base darkens. The dark palette simply raises --neu-intensity:
.dark {
--neu-base: #2a2f3a;
--neu-intensity: 0.45;
}
Recoloring the whole site
Point Nextra's background variable at your base color (as a space-separated RGB triple) and the theme follows:
:root { --nextra-bg: 228 233 240; } /* #e4e9f0 */
.dark { --nextra-bg: 42 47 58; } /* #2a2f3a */