Override design tokens at the root instead of rewriting components. Colour, surfaces, typography, spacing, radius, and shadow all read from custom properties.
Keep text contrast and a visible focus ring when you change colours—both are accessibility requirements, not preferences.
05
Light and dark
The theme is driven by a data-theme attribute on the root element, and the shipped site script wires a toggle button to it and remembers the choice.
NODERFRAME
button.nx-theme type="button" data-theme-toggle="true" aria-label="Switch color theme" "Dark"
NOTE
Style dark mode with :root[data-theme="dark"] selectors so the toggle wins over the system preference.
06
Declarative actions instead of inline handlers
The Content-Security-Policy has no unsafe-inline, so onclick attributes never run. The bridge handles the common cases through data attributes—which also work in packaged and native builds.
Reduced-motion rules for animation-heavy sections.
Safe-area padding for notched devices.
Responsive type and spacing scales rather than fixed pixel sizes.
Semantic markup expectations: main, nav, article, and descriptive link text.
08
What travels to devices
The packaged mobile build renders all of Cool.css in a WebView. The native build translates a subset into StyleSheet objects—layout, type, buttons, cards, and inputs—so gradients, blur, and CSS animation have no equivalent there.
NOTE
Design the shared parts with the translated subset in mind, then add web-only flourishes in a stylesheet the native build never reads.