diff --git a/ui/COLOR_SYSTEM.md b/ui/COLOR_SYSTEM.md new file mode 100644 index 0000000000..1c004396ab --- /dev/null +++ b/ui/COLOR_SYSTEM.md @@ -0,0 +1,233 @@ +# Color System Documentation + +## Overview + +The CircleCI documentation UI uses a two-tier CSS variable system designed for easy theme switching. All colors are defined in `src/css/vars.css`. + +## Variable Structure + +### Base Palette Variables + +**Format**: `--color-{name}-{variant}` + +**Examples**: +- `--color-gray-50` +- `--color-accent-green` +- `--color-note-blue` + +**Purpose**: These are raw color values defined once in the base palette section. + +**Important**: **Never use base palette variables directly in CSS rules**. Always use semantic tokens instead. + +### Semantic Token Variables + +**Format**: `--{component}-{property}-{state?}` + +**Examples**: +- `--body-font-color` +- `--link_hover-font-color` +- `--table-border-color` +- `--toc-active-text-color` + +**Purpose**: These reference base palette variables and provide meaningful names for specific UI contexts. + +**Important**: **Always use semantic tokens in CSS rules**. These are the override targets for dark theme. + +## File Organization (vars.css) + +The vars.css file is organized into logical sections: + +1. **BASE COLOR PALETTE** - Raw color definitions + - Grayscale palette (white → smoke → gray → jet → black) + - Brand colors (greens) + - UI colors (vapor, fog, link blues, etc.) + - Admonition colors (note, tip, warning, important) + - Status colors (success, error) + - Visual effects (shadows, overlays) + +2. **SEMANTIC TOKENS - Light Theme** - Meaningful mappings + - Typography (body, heading, doc, caption colors) + - Links (default, hover, unresolved, success, error) + - Surfaces and backgrounds + - Code blocks (inline, pre, annotations) + - Tables (borders, striping, headers) + - Admonitions (NOTE, TIP, WARNING, IMPORTANT, CAUTION) + - TOC (font colors, borders, active state) + - Navigation, Navbar, Toolbar, Footer + - Other doc elements (abstracts, examples, kbd, quotes, sidebars) + - Modals and overlays + +3. **FONTS** - Typography settings +4. **DIMENSIONS AND POSITIONING** - Layout measurements +5. **STACKING (Z-INDEX)** - Layer ordering + +## Usage Guidelines + +### ✅ Correct Usage + +```css +/* GOOD: Use semantic tokens */ +.my-component { + color: var(--body-font-color); + background: var(--panel-background); + border: 1px solid var(--panel-border-color); +} + +.my-link { + color: var(--link-font-color); +} + +.my-link:hover { + color: var(--link_hover-font-color); +} +``` + +### ❌ Incorrect Usage + +```css +/* BAD: Using base palette colors directly */ +.my-component { + color: var(--color-jet-30); /* Don't do this! */ + background: var(--color-smoke-30); /* Use semantic tokens! */ +} + +/* BAD: Hard-coded color values */ +.my-component { + color: #343434; /* Never hard-code colors! */ + background: #fafafa; /* Use variables! */ +} +``` + +## Dark Mode Strategy (Future Implementation) + +When implementing dark mode, follow this approach: + +### Step 1: Keep Base Palette Unchanged + +The base palette colors remain the same. They are just raw color definitions. + +### Step 2: Override Semantic Tokens + +Create dark theme overrides for semantic tokens only: + +```css +@media (prefers-color-scheme: dark) { + :root { + /* Invert surfaces */ + --body-background: var(--color-jet-80); + --body-font-color: var(--color-smoke-30); + --panel-background: var(--color-jet-70); + --panel-border-color: var(--color-jet-50); + + /* Adjust links for dark background */ + --link-font-color: #5B9FFF; /* Lighter blue */ + + /* Override other semantic tokens as needed */ + --table-stripe-even: var(--color-jet-60); + --table-stripe-odd: var(--color-jet-70); + + /* Code blocks might stay dark */ + --pre-background: #0D1117; /* Even darker for dark theme */ + } +} +``` + +**OR** use a data attribute approach: + +```css +[data-theme="dark"] { + /* Same semantic token overrides */ +} +``` + +### Step 3: Syntax Highlighting Strategy + +Two options for code syntax highlighting: + +**Option A: Keep Dark Syntax Theme (Recommended for MVP)** +- Current approach uses dark syntax colors on light background +- Works on both light and dark themes +- Simplest implementation +- No changes needed + +**Option B: Theme-Aware Syntax Highlighting** +- Override `--syntax-*` variables in dark mode +- Use lighter syntax colors for dark mode +- More complex but potentially better contrast +- Requires additional dark syntax color palette + +## Adding New Colors + +When adding new colors to the system: + +1. **Determine if it's a new raw color or a new semantic use** + +2. **If it's a new raw color**: + - Add to the BASE COLOR PALETTE section + - Use the naming convention: `--color-{name}-{variant}` + - Place in appropriate subsection (grayscale, brand, UI, etc.) + +3. **If it's a new semantic use**: + - Add to the SEMANTIC TOKENS section + - Use the naming convention: `--{component}-{property}-{state?}` + - Reference a base palette color + - Place in appropriate subsection (typography, surfaces, etc.) + +4. **Update this documentation** if you introduce a new pattern or convention + +## Color Contrast Requirements + +All color combinations must meet WCAG accessibility standards: + +- **Body text**: 4.5:1 contrast ratio minimum (AA standard) +- **Large text** (18pt+ or 14pt+ bold): 3:1 contrast ratio minimum +- **UI components**: 3:1 contrast ratio minimum + +Use browser DevTools or online contrast checkers to verify. + +## Current Variable Count + +As of DOCSS-2002 dark mode preparation: + +- **Base palette colors**: ~60 variables +- **Semantic tokens**: ~80+ variables +- **Font variables**: ~15 variables +- **Dimension variables**: ~15 variables +- **Total CSS variables**: ~170 variables + +## Maintenance + +### Testing After Changes + +After modifying vars.css: + +1. **Build the UI bundle**: `cd ui && npm run build` +2. **Visual regression test**: Compare before/after screenshots +3. **Validate variable references**: Check console for undefined variables +4. **Accessibility audit**: Verify contrast ratios maintained +5. **Browser compatibility**: Test in Chrome, Firefox, Safari, Edge + +### Common Pitfalls + +- **Don't delete unused-looking variables** without searching the entire codebase. They may be referenced in hidden pages or JavaScript-generated content. +- **Don't mix hard-coded colors with variables**. Use variables consistently across the entire codebase. +- **Don't use `!important` unless absolutely necessary**. It makes dark theme overrides difficult. +- **Don't skip the color-scheme property**. It helps browsers render form controls and scrollbars correctly. + +## Related Files + +- **vars.css**: Main variable definitions +- **site.css**: Tailwind @theme configuration (references vars.css) +- **doc.css**: Document styling (uses semantic tokens) +- **toc.css**: Table of contents styling +- **tabs.css**: Tab component styling +- **highlight.css**: Syntax highlighting variables +- **shiki.css**: Shiki highlighter variables +- **base.css**: Contains `color-scheme` declaration + +## Questions? + +For questions about the color system or dark mode implementation, refer to: +- The approved implementation plan: `/Users/rosieyohannan/.claude/plans/lovely-floating-beacon.md` +- CircleCI documentation style guide: `CLAUDE.md` +- This file: `ui/COLOR_SYSTEM.md` diff --git a/ui/src/css/base.css b/ui/src/css/base.css index 38efec2574..4bac060114 100644 --- a/ui/src/css/base.css +++ b/ui/src/css/base.css @@ -9,6 +9,7 @@ html { font-size: var(--body-font-size); height: 100%; scroll-behavior: smooth; + color-scheme: light; /* Explicitly declare light mode support; prepares for future dark mode */ } @media screen and (min-width: 1024px) { @@ -24,7 +25,7 @@ body { line-height: var(--body-line-height); margin: 0; tab-size: 4; - word-wrap: anywhere; /* aka overflow-wrap; used when hyphens are disabled or aren't sufficient */ + overflow-wrap: anywhere; /* aka overflow-wrap; used when hyphens are disabled or aren't sufficient */ } a { @@ -95,7 +96,7 @@ summary { table { border-collapse: collapse; - word-wrap: normal; /* table widths aren't computed as expected when word-wrap is enabled */ + overflow-wrap: normal; /* table widths aren't computed as expected when overflow-wrap is enabled */ } object[type="image/svg+xml"]:not([width]) { @@ -142,7 +143,7 @@ object[type="image/svg+xml"]:not([width]) { } ::-webkit-scrollbar-thumb:hover { - background-color: var(--scrollbar_hover-thumb-color); + background-color: var(--scrollbar-hover-thumb-color); } } diff --git a/ui/src/css/doc.css b/ui/src/css/doc.css index b154b9e4ad..4ccda0f9ef 100644 --- a/ui/src/css/doc.css +++ b/ui/src/css/doc.css @@ -184,7 +184,7 @@ } .doc a:hover { - color: var(--link_hover-font-color); + color: var(--link-hover-font-color); } .doc a.bare { @@ -192,7 +192,7 @@ } .doc a.unresolved { - color: var(--link_unresolved-font-color); + color: var(--link-unresolved-font-color); } .doc i.fa { @@ -215,9 +215,9 @@ .doc .colist > table code, .doc .admonitionblock td.content code:not(.hljs) { color: var(--code-font-color); - background: #F7F7F7; + background: var(--inline-code-background); border-radius: 4px; - border: 1px solid #D4D4D4; + border: 1px solid var(--inline-code-border-color); font-size: 0.95em; padding: 0.15em 0.4em; } @@ -248,7 +248,7 @@ height: auto; margin: 0 0 1rem 1rem; border-radius: 8px; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + box-shadow: var(--image-shadow); overflow: hidden; } @@ -350,7 +350,7 @@ border-spacing: 0; display: table; margin-bottom: 1rem; - border: 1px solid #D4D4D4; + border: 1px solid var(--table-border-color); border-radius: 8px; overflow: hidden; } @@ -368,12 +368,12 @@ .doc table.tableblock th { box-sizing: border-box; white-space: normal; - word-wrap: break-word; + overflow-wrap: break-word; hyphens: manual; } .doc td.tableblock > .content { - word-wrap: anywhere; /* aka overflow-wrap; used when hyphens are disabled or aren't sufficient */ + overflow-wrap: anywhere; /* aka overflow-wrap; used when hyphens are disabled or aren't sufficient */ } .doc td.tableblock > .content > :first-child { @@ -383,7 +383,7 @@ .doc table.tableblock th, .doc table.tableblock td { padding: 1rem; - border-bottom: 1px solid #D4D4D4; + border-bottom: 1px solid var(--table-border-color); min-width: 100px; } @@ -397,7 +397,7 @@ .doc table.tableblock, .doc table.tableblock > * > tr:last-child > * { - border-bottom: 1px solid #D4D4D4; + border-bottom: 1px solid var(--table-border-color); } .doc .table-scroll { @@ -412,7 +412,7 @@ .doc table.grid-all > * > tr > * { border-width: 0; - border-bottom: 1px solid #D4D4D4; + border-bottom: 1px solid var(--table-border-color); } .doc table.grid-cols > * > tr > * { @@ -421,7 +421,7 @@ .doc table.grid-rows > * > tr > * { border-width: 0; - border-bottom: 1px solid #D4D4D4; + border-bottom: 1px solid var(--table-border-color); } .doc table.grid-all > thead th, @@ -479,11 +479,11 @@ } .doc table.tableblock > tbody > tr:nth-of-type(odd) { - background: white; + background: var(--table-stripe-odd); } .doc table.tableblock > tbody > tr:nth-of-type(even) { - background: #FAFAFA; + background: var(--table-stripe-even); } .doc table.stripes-hover > tbody > tr:hover { @@ -492,8 +492,8 @@ .doc table.tableblock > thead > tr > th { font-weight: bold; - border-bottom: 2px solid #D4D4D4; - background-color: #FAFAFA; + border-bottom: 2px solid var(--table-border-color); + background-color: var(--table-header-background); } .doc table.tableblock > tfoot { @@ -547,23 +547,23 @@ } .doc .admonitionblock.note > table { - border-color: #1A66F7; + border-color: var(--note-color); } .doc .admonitionblock.tip > table { - border-color: #697387; + border-color: var(--tip-color); } .doc .admonitionblock.warning > table { - border-color: #BF8532; + border-color: var(--warning-color); } .doc .admonitionblock.important > table { - border-color: #CC4242; + border-color: var(--important-color); } .doc .admonitionblock.caution > table { - border-color: #CC4242; + border-color: var(--caution-color); } .doc .admonitionblock td.icon { @@ -618,7 +618,7 @@ .doc .admonitionblock td.content { width: 100%; - word-wrap: anywhere; + overflow-wrap: anywhere; min-width: 0; } @@ -666,7 +666,7 @@ width: auto; vertical-align: middle; object-fit: contain; - border: 1px solid #D4D4D4; + border: 1px solid var(--table-border-color); border-radius: 12px; } @@ -967,7 +967,7 @@ align-items: center; border: 2px solid transparent; border-radius: 12px; - border-color: #1A66F7; + border-color: var(--note-color); padding: 1rem; box-sizing: border-box; padding: 1rem 1rem 0.75rem; @@ -1010,7 +1010,7 @@ overflow-x: auto; padding: 0.875em; border-radius: inherit; - color: #FFFFFF; + color: var(--color-white); max-width: 100%; box-sizing: border-box; } @@ -1128,7 +1128,7 @@ display: flex; align-items: center; justify-content: center; - background-color: #E8E8E8; + background-color: var(--code-comment-color); border: none; border-radius: 50%; color: inherit; @@ -1348,7 +1348,7 @@ .doc .nobreak { hyphens: none; - word-wrap: normal; + overflow-wrap: normal; } .doc :not(pre).pre-wrap { @@ -1400,7 +1400,7 @@ /* inline links pick up the new blue */ .doc a { - color: #2152E5; + color: var(--link-font-color); } /* Image Modal Styles */ @@ -1411,7 +1411,7 @@ left: 0; width: 100%; height: 100%; - background-color: rgba(0, 0, 0, 0.85); + background-color: var(--modal-overlay-background); z-index: 9999; overflow: auto; justify-content: center; @@ -1436,7 +1436,7 @@ } .image-modal-title { - color: #fff; + color: var(--color-white); margin-top: 1rem; font-size: 1rem; text-align: center; @@ -1459,12 +1459,12 @@ } .doc .circle-green { - color: #008542 !important; + color: var(--link-success-color) !important; font-weight: var(--heading-font-weight); } .doc .circle-red { - color: #8F001C !important; + color: var(--link-error-color) !important; font-weight: var(--heading-font-weight); } diff --git a/ui/src/css/highlight.css b/ui/src/css/highlight.css index fcb02df8dd..9e47785315 100644 --- a/ui/src/css/highlight.css +++ b/ui/src/css/highlight.css @@ -1,14 +1,14 @@ /*! Adapted from the GitHub style by Vasily Polovnyov */ .hljs-comment, .hljs-quote { - color: #959595; + color: var(--syntax-comment); font-style: italic; } .hljs-keyword, .hljs-selector-tag, .hljs-subst { - color: #A9B7C6; + color: var(--syntax-keyword); font-weight: var(--monospace-font-weight-bold); } @@ -17,22 +17,22 @@ .hljs-variable, .hljs-template-variable, .hljs-tag .hljs-attr { - color: #B5CEA8; + color: var(--syntax-number); } .hljs-attr { - color: #FFF176; + color: var(--syntax-attr); } .hljs-string, .hljs-doctag { - color: #FFFFFF; + color: var(--syntax-string); } .hljs-title, .hljs-section, .hljs-selector-id { - color: #F78C6C; + color: var(--syntax-title); font-weight: var(--monospace-font-weight-bold); } @@ -42,43 +42,43 @@ .hljs-type, .hljs-class .hljs-title { - color: #89DDFF; + color: var(--syntax-type); font-weight: var(--monospace-font-weight-bold); } .hljs-tag, .hljs-name, .hljs-attribute { - color: #7986CB; + color: var(--syntax-tag); font-weight: normal; } .hljs-regexp, .hljs-link { - color: #C3E88D; + color: var(--syntax-regexp); } .hljs-symbol, .hljs-bullet { - color: #D4D4D4; + color: var(--syntax-symbol); } .hljs-built_in, .hljs-builtin-name { - color: #82AAFF; + color: var(--syntax-builtin); } .hljs-meta { - color: #C792EA; + color: var(--syntax-meta); font-weight: var(--monospace-font-weight-bold); } .hljs-deletion { - background: #643434; + background: var(--syntax-deletion-bg); } .hljs-addition { - background: #345F34; + background: var(--syntax-addition-bg); } .hljs-emphasis { @@ -103,7 +103,7 @@ .hljs-ln-numbers { user-select: none; text-align: right; - color: #bbb; + color: var(--syntax-line-number); vertical-align: top; padding-right: 0.5em; padding-left: 0.5em; diff --git a/ui/src/css/shiki.css b/ui/src/css/shiki.css index efd013edcf..693f8ed309 100644 --- a/ui/src/css/shiki.css +++ b/ui/src/css/shiki.css @@ -49,6 +49,6 @@ /* Highlighted lines for documentation (using AsciiDoc highlight attribute) */ .doc pre.shiki code .line.highlighted { - background-color: rgba(255, 255, 255, 0.1); - box-shadow: inset 3px 0 0 0 rgba(255, 255, 255, 0.4); + background-color: var(--syntax-highlighted-line-bg); + box-shadow: inset 3px 0 0 0 var(--syntax-highlighted-line-border); } diff --git a/ui/src/css/site.css b/ui/src/css/site.css index 830b83846a..421226d1f1 100644 --- a/ui/src/css/site.css +++ b/ui/src/css/site.css @@ -17,23 +17,19 @@ @source inline("translate-x-0"); @source inline("h-dvh"); @theme { - --color-slime-green: #00DB74; - --color-operational-green: #00A657; - --color-dark-green: #005600; - --color-accent-green: #00B25E; - - --color-terminal-black: #161616; - --color-body-dark: #343434; - - --color-vapor: #D4D4D4; - --color-fog: #EDEDED; - --color-inline-grey: #F7F7F7; - - --color-link-on-light: #2152E5; - - --color-disabled-element: #959595; - - --shadow-default: 0 0 6px 4px #1616161F; + /* Reference colors from vars.css instead of redefining */ + --color-slime-green: var(--color-slime-green); + --color-operational-green: var(--color-operational-green); + --color-dark-green: var(--color-dark-green); + --color-accent-green: var(--color-accent-green); + --color-terminal-black: var(--color-terminal-black); + --color-body-dark: var(--color-body-dark); + --color-vapor: var(--color-vapor); + --color-fog: var(--color-fog); + --color-inline-grey: var(--color-inline-grey); + --color-link-on-light: var(--color-link-on-light); + --color-disabled-element: var(--color-disabled-element); + --shadow-default: var(--shadow-default); --breakpoint-lg: 75rem; } diff --git a/ui/src/css/tabs.css b/ui/src/css/tabs.css index b57d25f0c7..1c23d24c15 100644 --- a/ui/src/css/tabs.css +++ b/ui/src/css/tabs.css @@ -14,7 +14,7 @@ .tablist > ul li { align-items: center; - background-color: #fff; + background-color: var(--color-white); cursor: pointer; display: flex; font-weight: 400; @@ -63,7 +63,7 @@ } .tabs.is-loading .tablist li:first-child::after { - background-color: #fff; + background-color: var(--color-white); } /* @@ -79,7 +79,7 @@ } .tabpanel { - background-color: #fff; + background-color: var(--color-white); padding: calc(40 / var(--rem-base) * 1rem) 0 calc(20 / var(--rem-base) * 1rem) 0; } diff --git a/ui/src/css/toc.css b/ui/src/css/toc.css index 28b0de547c..d56d88399d 100644 --- a/ui/src/css/toc.css +++ b/ui/src/css/toc.css @@ -114,9 +114,9 @@ } .toc .toc-menu a.is-active { - border-left-color: #00B25E; + border-left-color: var(--toc-active-border-color); border-left-width: 2px; - color: #161616; + color: var(--toc-active-text-color); } .sidebar.toc .toc-menu a:focus { diff --git a/ui/src/css/vars.css b/ui/src/css/vars.css index 42b9f6c434..f012ad1958 100644 --- a/ui/src/css/vars.css +++ b/ui/src/css/vars.css @@ -1,5 +1,10 @@ :root { - /* colors */ + /* ============================================ + BASE COLOR PALETTE + Define all raw colors - single source of truth + ============================================ */ + + /* Grayscale palette */ --color-white: #fff; --color-smoke-10: #fefefe; --color-smoke-30: #fafafa; @@ -17,113 +22,205 @@ --color-jet-70: #222; --color-jet-80: #191919; --color-black: #000; - --color-body-dark:#343434; - /* fonts */ - --rem-base: 18; /* used to compute rem value from desired pixel value (e.g., calc(18 / var(--rem-base) * 1rem) = 18px) */ - --body-font-size: 1.0625em; /* 17px */ - --body-font-size--desktop: 1.125em; /* 18px */ - --body-font-size--print: 0.9375em; /* 15px */ - --body-line-height: 1.6; + --color-body-dark: #343434; + + /* Brand colors */ + --color-slime-green: #00DB74; + --color-operational-green: #00A657; + --color-dark-green: #005600; + --color-accent-green: #00B25E; + + /* UI colors */ + --color-terminal-black: #161616; + --color-vapor: #D4D4D4; + --color-fog: #EDEDED; + --color-inline-grey: #F7F7F7; + --color-link-blue: #2152E5; + --color-link-hover-blue: #104d92; + --color-link-on-light: #2152E5; + --color-disabled-element: #959595; + + /* Admonition colors */ + --color-note-blue: #1A66F7; + --color-tip-gray: #697387; + --color-warning-orange: #BF8532; + --color-important-red: #CC4242; + + /* Status colors */ + --color-success-green: #008542; + --color-error-red: #8F001C; + + /* Visual effects */ + --shadow-default: 0 0 6px 4px #1616161F; + --shadow-image: 0 2px 8px rgb(0 0 0 / 10%); + --overlay-modal: rgb(0 0 0 / 85%); + + /* Syntax highlighting colors (for code blocks) */ + --syntax-comment: #959595; + --syntax-keyword: #A9B7C6; + --syntax-number: #B5CEA8; + --syntax-attr: #FFF176; + --syntax-string: #FFF; + --syntax-title: #F78C6C; + --syntax-type: #89DDFF; + --syntax-tag: #7986CB; + --syntax-regexp: #C3E88D; + --syntax-symbol: #D4D4D4; + --syntax-builtin: #82AAFF; + --syntax-meta: #C792EA; + --syntax-deletion-bg: #643434; + --syntax-addition-bg: #345F34; + --syntax-line-number: #bbb; + --syntax-highlighted-line-bg: rgb(255 255 255 / 10%); + --syntax-highlighted-line-border: rgb(255 255 255 / 40%); + + /* ============================================ + SEMANTIC TOKENS - Light Theme + Map base colors to semantic meanings + These are the override targets for dark theme + ============================================ */ + + /* Typography */ --body-font-color: var(--color-body-dark); - --body-font-family: "Inter", sans-serif; - --body-font-weight-bold: 700; - --monospace-font-family: "IBM Plex Mono", monospace; - --monospace-font-weight-bold: 600; - /* base */ + --heading-font-color: var(--color-terminal-black); + --doc-font-color: var(--color-body-dark); + --caption-font-color: var(--color-body-dark); + + /* Links */ + --link-font-color: var(--color-link-blue); + --link-hover-font-color: var(--color-link-hover-blue); + --link-unresolved-font-color: var(--color-important-red); + --link-success-color: var(--color-success-green); + --link-error-color: var(--color-error-red); + + /* Surfaces and backgrounds */ --body-background: var(--color-white); --panel-background: var(--color-smoke-30); --panel-border-color: var(--color-smoke-90); --scrollbar-track-color: var(--color-smoke-30); --scrollbar-thumb-color: var(--color-gray-10); - --scrollbar_hover-thumb-color: var(--color-gray-30); - /* navbar */ + --scrollbar-hover-thumb-color: var(--color-gray-30); + + /* Code blocks */ + --inline-code-background: var(--color-inline-grey); + --inline-code-border-color: var(--color-vapor); + --code-background: var(--panel-background); + --code-font-color: var(--body-font-color); + --code-comment-color: var(--color-fog); + --pre-background: #1C273A; /* Intentionally dark for light theme */ + --pre-title-background: var(--color-fog); + --pre-border-color: var(--panel-border-color); + --pre-annotation-font-color: var(--color-gray-50); + + /* Tables */ + --table-border-color: var(--panel-border-color); + --table-stripe-background: var(--panel-background); + --table-stripe-odd: var(--color-white); + --table-stripe-even: var(--color-smoke-30); + --table-header-background: var(--color-smoke-30); + --table-footer-background: linear-gradient(to bottom, var(--color-smoke-70) 0%, var(--color-white) 100%); + + /* Admonitions */ + --note-color: var(--color-note-blue); + --note-on-color: var(--color-white); + --tip-color: var(--color-tip-gray); + --tip-on-color: var(--color-white); + --warning-color: var(--color-warning-orange); + --warning-on-color: var(--color-white); + --important-color: var(--color-important-red); + --important-on-color: var(--color-white); + --caution-color: var(--color-important-red); + --caution-on-color: var(--color-white); + --admonition-background: var(--panel-background); + --admonition-label-font-weight: var(--body-font-weight-bold); + + /* TOC (Table of Contents) */ + --toc-font-color: #6A6A6A; + --toc-heading-font-color: var(--color-body-dark); + --toc-border-color: var(--color-vapor); + --toc-active-border-color: var(--color-accent-green); + --toc-active-text-color: var(--color-terminal-black); + + /* Navigation */ + --nav-background: var(--panel-background); + --nav-border-color: var(--color-gray-10); + --nav-heading-font-color: var(--color-jet-30); + --nav-muted-color: var(--color-gray-70); + --nav-panel-divider-color: var(--color-smoke-90); + --nav-secondary-background: var(--color-smoke-70); + + /* Navbar */ --navbar-background: var(--color-jet-80); --navbar-font-color: var(--color-white); - --navbar_hover-background: var(--color-black); + --navbar-hover-background: var(--color-black); --navbar-button-background: var(--color-white); --navbar-button-border-color: var(--panel-border-color); --navbar-button-font-color: var(--body-font-color); --navbar-menu-border-color: var(--panel-border-color); --navbar-menu-background: var(--color-white); --navbar-menu-font-color: var(--body-font-color); - --navbar-menu_hover-background: var(--color-smoke-50); - /* nav */ - --nav-background: var(--panel-background); - --nav-border-color: var(--color-gray-10); - --nav-line-height: 1.35; - --nav-heading-font-color: var(--color-jet-30); - --nav-muted-color: var(--color-gray-70); - --nav-panel-divider-color: var(--color-smoke-90); - --nav-secondary-background: var(--color-smoke-70); - /* toolbar */ + --navbar-menu-hover-background: var(--color-smoke-50); + + /* Toolbar */ --toolbar-background: var(--panel-background); --toolbar-border-color: var(--panel-border-color); --toolbar-font-color: var(--color-gray-70); --toolbar-muted-color: var(--color-gray-40); --page-version-menu-background: var(--color-smoke-70); --page-version-missing-font-color: var(--color-gray-40); - /* admonitions */ - --caution-color: #a0439c; - --caution-on-color: var(--color-white); - --important-color: #d32f2f; - --important-on-color: var(--color-white); - --note-color: #217ee7; - --note-on-color: var(--color-white); - --tip-color: #41af46; - --tip-on-color: var(--color-white); - --warning-color: #e18114; - --warning-on-color: var(--color-white); - /* doc */ - --doc-font-color: #343434; - --doc-font-size: 16px; - --doc-font-size--desktop: 16px; - --doc-line-height: 1.7; - --doc-margin: 0 auto; - --doc-margin--desktop: 0 2rem; - --heading-font-color: #161616; - --heading-font-weight: 500; - --alt-heading-font-weight: 500; - --section-divider-color: var(--panel-border-color); - --link-font-color: #2152E5; - --link_hover-font-color: #104d92; - --link_unresolved-font-color: var(--important-color); + + /* Footer */ + --footer-background: var(--color-smoke-90); + --footer-font-color: var(--color-gray-70); + --footer-link-font-color: var(--color-jet-80); + + /* Other doc elements */ --abstract-background: var(--color-smoke-70); --abstract-font-color: var(--color-jet-20); --abstract-border-color: var(--panel-border-color); - --admonition-background: var(--panel-background); - --admonition-label-font-weight: var(--body-font-weight-bold); - --caption-font-color: #343434; - --caption-font-style: italic; - --caption-font-weight: 300; - --code-background: var(--panel-background); - --code-font-color: var(--body-font-color); --example-background: var(--color-white); --example-border-color: var(--color-gray-70); --kbd-background: var(--panel-background); --kbd-border-color: var(--color-gray-10); - --pre-title-background: #EDEDED; - --pre-background: #1C273A; - --pre-border-color: var(--panel-border-color); - --pre-annotation-font-color: var(--color-gray-50); --quote-background: var(--panel-background); --quote-border-color: var(--color-gray-70); --quote-font-color: var(--color-gray-70); --quote-attribution-font-color: var(--color-gray-40); --sidebar-background: var(--color-smoke-90); - --table-border-color: var(--panel-border-color); - --table-stripe-background: var(--panel-background); - --table-footer-background: linear-gradient(to bottom, var(--color-smoke-70) 0%, var(--color-white) 100%); - /* toc */ - --toc-font-color: #6A6A6A; - --toc-heading-font-color: #343434; - --toc-border-color: #D4D4D4; + --section-divider-color: var(--panel-border-color); + + /* Modals and overlays */ + --modal-overlay-background: var(--overlay-modal); + --image-shadow: var(--shadow-image); + + /* ============================================ + FONTS + ============================================ */ + + --rem-base: 18; /* used to compute rem value from desired pixel value (e.g., calc(18 / var(--rem-base) * 1rem) = 18px) */ + --body-font-size: 1.0625em; /* 17px */ + --body-font-size--desktop: 1.125em; /* 18px */ + --body-font-size--print: 0.9375em; /* 15px */ + --body-line-height: 1.6; + --body-font-family: "Inter", sans-serif; + --body-font-weight-bold: 700; + --monospace-font-family: "IBM Plex Mono", monospace; + --monospace-font-weight-bold: 600; + --doc-font-size: 16px; + --doc-font-size--desktop: 16px; + --doc-line-height: 1.7; + --heading-font-weight: 500; + --alt-heading-font-weight: 500; --toc-line-height: 1.2; - /* footer */ + --nav-line-height: 1.35; --footer-line-height: var(--doc-line-height); - --footer-background: var(--color-smoke-90); - --footer-font-color: var(--color-gray-70); - --footer-link-font-color: var(--color-jet-80); - /* dimensions and positioning */ + --caption-font-style: italic; + --caption-font-weight: 300; + + /* ============================================ + DIMENSIONS AND POSITIONING + ============================================ */ + --navbar-height: calc(63 / var(--rem-base) * 1rem); --toolbar-height: calc(45 / var(--rem-base) * 1rem); --drawer-height: var(--toolbar-height); @@ -134,13 +231,20 @@ --nav-panel-menu-height: calc(100% - var(--drawer-height)); --nav-panel-explore-height: calc(50% + var(--drawer-height)); --nav-width: calc(270 / var(--rem-base) * 1rem); ---toc-top: calc(var(--spacing) * 35); /* Empirically determined position: navbar + toolbar + additional spacing (≈8.75rem vs logical 6rem) */ ---toc-height: calc(100vh - var(--toc-top) - 6.2rem); + --spacing: 0.25rem; /* Base spacing unit (0.25rem * 35 = 8.75rem for TOC positioning) */ + --toc-top: calc(var(--spacing) * 35); /* Empirically determined position: navbar + toolbar + additional spacing (≈8.75rem vs logical 6rem) */ + --toc-height: calc(100vh - var(--toc-top) - 6.2rem); --toc-width: calc(265 / var(--rem-base) * 1rem); --toc-width--widescreen: calc(474 / var(--rem-base) * 1rem); --doc-max-width: calc(720 / var(--rem-base) * 1rem); --doc-max-width--desktop: calc(888 / var(--rem-base) * 1rem); - /* stacking */ + --doc-margin: 0 auto; + --doc-margin--desktop: 0 2rem; + + /* ============================================ + STACKING (Z-INDEX) + ============================================ */ + --z-index-nav: 1; --z-index-toolbar: 2; --z-index-page-version-menu: 3;