CSS and Theming
Every new JamsEDU project comes with a clean set of default styles for common page elements. These give you a readable, consistent look right away so you can start publishing immediately. When you are ready to match your own brand, everything is controlled through a small set of CSS custom properties that you can override in a few files.
Built-In Element Examples
Below are examples of the styled elements available in every JamsEDU project.
Headings and Collapsible Sections
JamsEDU styles all six heading levels for you. This is also an example of a collapsible section using the details element.
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Highlighted Text
Use the mark element when a term needs extra attention on the page.
<mark>extra attention</mark>
Keyboard Input
Show keyboard shortcuts with the kbd element. For example, press Ctrl + P to print this page.
<kbd>Ctrl</kbd> + <kbd>P</kbd>
Code Blocks
Wrap terminal commands or code references with the code element and it will render like the inline code block in this paragraph. If you wrap the code element in a pre element, it will render as a code block with a border, padding, and line numbers like the following example:
<code>npm run build</code>
Horizontal Rule
Use a horizontal rule (<hr>) to visually separate sections of content on a page. By default it will render like the following example:
Definition lists
In page prose, a dl defaults to a glossary style: each div that wraps a dt and dd is spaced from the next pair with vertical margin only (no rules or hairlines), and definitions are indented so long lists of terms stay readable. For a few highlighted entries, add class="card" or class="cards" on the dl to use the same inset card treatment as blockquotes (surface, border, and start accent).
- Card row
- Uses the opt-in
dl.cards(ordl.card) layout. - Second row
- Each pair sits in its own card.
<dl>
<div><dt>Term</dt><dd>Glossary style (default).</dd></div>
</dl>
<dl class="cards">
<div><dt>Term</dt><dd>Inset card row.</dd></div>
</dl>
Blockquotes
Use a blockquote for quotations. You can optionally add a cite attribute with a URL on the blockquote element and the JamsEDU engine will automatically turn the attribution line into a link to that source.
If future generations are to remember us more with gratitude than sorrow, we must achieve more than just the miracles of technology. We must also leave them a glimpse of the world as it was created, not just as it looked when we got through with it.
Lyndon B. Johnson
<blockquote cite="https://example.com/source-url">
<p>
Your quote here.
</p>
<cite>
Author Name (Optional)
</cite>
</blockquote>
Callouts
Callouts are styled alert panels that draw attention to important information. Add class="callout" to any div for the default tone, then add a type class to change its appearance. Adding the icon class will display a leading glyph that matches the callout type. The title row is optional on all types.
Available type classes are notice (also info), success, warning (also warn and construction), and danger (also error). The same type classes also work on details elements for collapsible callouts, with an additional spoiler class that uses the warning style.
Default callout with no type class and no title row.
Highlights something readers should be aware of.
Confirms that something completed or is valid.
Signals caution or a potential risk.
Indicates a serious error or destructive action. This example has no title row.
<div class="callout success icon">
<div class="title">Saved</div>
<p>Your changes were stored.</p>
</div>
<div class="callout danger icon">
<p>No title row is still valid.</p>
</div>
Color and Theming
JamsEDU theming is token based. Every built-in feature reads its colors and spacing from CSS custom properties using a three level fallback system. The feature's own token is checked first, then your site-wide shared token, and finally a sensible default value.
--doc-text-color: var(--doc-text-color, var(--color-text, #000000));
This means your custom value always wins. If you have not set one, the shared site token is used. If neither exists, the built-in default takes over. In a new JamsEDU project the following files control your site's visual appearance. All of them are meant to be edited.
css/tokens/colors.css- Site color tokens and light or dark palettes.
css/tokens/variables.css- Typography, spacing, border radius, motion, and layout tokens.
css/vendor/jamsedu/tokens.css- Token bridge for built-in features like Tiny Doc, Rich Text, and the PDF viewer.
css/main.css- Your project's main stylesheet. It defines import order and is the usual place to add site-wide rules after the defaults.
Common Token Prefixes
When overriding built-in styles, these prefixes will help you find the right tokens.
--jamsedu-seed-*- Base seed values in the vendor token bridge. These feed the shared feature tokens below.
--jamsedu-*- Shared built-in feature tokens used across forms, Rich Text, and PDF UI.
--doc-*- Interactive form surfaces and text.
--richtext-*- Rich Text editor chrome.
--pdf-*- Embedded PDF viewer chrome.
Light and Dark Mode
JamsEDU supports light, dark, and system color modes out of the box. The default project includes a theme picker in the header and footer that lets visitors choose their preference. Their choice is saved to localStorage and applied before the first paint so there is no flash of the wrong theme on page load.
All of the color mode logic lives in the same token files described above. css/tokens/colors.css uses html:has(...) selectors to detect the active choice and sets color-scheme accordingly. When system mode is selected it defers to the browser's prefers-color-scheme setting. Because every built-in feature reads from the same token system, switching between light and dark mode updates everything on the page automatically.
To customize colors for either mode, start with the shared tokens in css/tokens/colors.css. If a specific built-in feature needs a different value in one mode, override its feature token using the prefixes listed above.
:root {
--doc-link-color: #0b57d0;
--richtext-link-color: #0b57d0;
}
If you replace the default theme picker with your own UI, make sure your implementation still sets color-scheme on the document root so the token system and CSS light-dark() functions continue to resolve correctly.