diff --git a/CLAUDE.md b/CLAUDE.md index fe12f0b..5fb82f1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -52,7 +52,7 @@ A self-hosted OpenAI-compatible LLM proxy: one static Go binary, per-user API ke ## Documentation -`docs/` is organised by reader intent: `getting-started.md` (tutorial), `install/` (deploy), `guides/` (operate), `reference/` (look up), `concepts/` (understand). Task pages are imperative and step-numbered with expected output; rationale is one sentence plus a link, and lives in `concepts/architecture.md`. The writing rules are in CONTRIBUTING.md. A new page needs an entry in `mkdocs.yml`'s nav and in the `docs/README.md` router. `mkdocs build --strict` fails on broken internal links and runs in CI on any PR touching `docs/`. +`docs/` is organised by reader intent: `getting-started.md` (tutorial), `install/` (deploy), `guides/` (operate), `reference/` (look up), `concepts/` (understand). Task pages are imperative and step-numbered with expected output; rationale is one sentence plus a link, and lives in `concepts/architecture.md`. The writing rules are in CONTRIBUTING.md. A new page needs an entry in `mkdocs.yml`'s nav and in the `docs/README.md` router. `mkdocs build --strict` fails on broken internal links and runs in CI on any PR touching `docs/`. The site's look is the Greyhaven design system, vendored into `docs/assets/stylesheets/greyhaven.css` from the design system's tokens; re-vendor rather than hand-tune colors, and keep `mkdocs.yml`'s palette on `custom` or the theme's own colors override the stylesheet. ## Deployment files diff --git a/docs/assets/fonts/Aspekta-400.woff2 b/docs/assets/fonts/Aspekta-400.woff2 new file mode 100644 index 0000000..764b50c Binary files /dev/null and b/docs/assets/fonts/Aspekta-400.woff2 differ diff --git a/docs/assets/fonts/Aspekta-500.woff2 b/docs/assets/fonts/Aspekta-500.woff2 new file mode 100644 index 0000000..ba95918 Binary files /dev/null and b/docs/assets/fonts/Aspekta-500.woff2 differ diff --git a/docs/assets/fonts/Aspekta-600.woff2 b/docs/assets/fonts/Aspekta-600.woff2 new file mode 100644 index 0000000..ea5728e Binary files /dev/null and b/docs/assets/fonts/Aspekta-600.woff2 differ diff --git a/docs/assets/fonts/Aspekta-700.woff2 b/docs/assets/fonts/Aspekta-700.woff2 new file mode 100644 index 0000000..b9342d8 Binary files /dev/null and b/docs/assets/fonts/Aspekta-700.woff2 differ diff --git a/docs/assets/fonts/source-serif-4-italic.woff2 b/docs/assets/fonts/source-serif-4-italic.woff2 new file mode 100644 index 0000000..e99ceb8 Binary files /dev/null and b/docs/assets/fonts/source-serif-4-italic.woff2 differ diff --git a/docs/assets/fonts/source-serif-4-roman.woff2 b/docs/assets/fonts/source-serif-4-roman.woff2 new file mode 100644 index 0000000..56a26e1 Binary files /dev/null and b/docs/assets/fonts/source-serif-4-roman.woff2 differ diff --git a/docs/assets/images/favicon.svg b/docs/assets/images/favicon.svg new file mode 100644 index 0000000..cb5e07e --- /dev/null +++ b/docs/assets/images/favicon.svg @@ -0,0 +1,11 @@ + + + + + diff --git a/docs/assets/images/greyhaven-symbol-white.svg b/docs/assets/images/greyhaven-symbol-white.svg new file mode 100644 index 0000000..671f72f --- /dev/null +++ b/docs/assets/images/greyhaven-symbol-white.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/assets/stylesheets/greyhaven.css b/docs/assets/stylesheets/greyhaven.css new file mode 100644 index 0000000..06f073a --- /dev/null +++ b/docs/assets/stylesheets/greyhaven.css @@ -0,0 +1,135 @@ +/* Greyhaven design system for mkdocs-material. + Colors are vendored from the design system's tokens/color.json; + do not hand-tune values here, re-vendor from the design system. */ + +/* Aspekta: UI labels, nav, buttons (self-hosted, same weights as the web UI). */ +@font-face { font-family: 'Aspekta'; font-style: normal; font-weight: 400; font-display: swap; src: url('../fonts/Aspekta-400.woff2') format('woff2'); } +@font-face { font-family: 'Aspekta'; font-style: normal; font-weight: 500; font-display: swap; src: url('../fonts/Aspekta-500.woff2') format('woff2'); } +@font-face { font-family: 'Aspekta'; font-style: normal; font-weight: 600; font-display: swap; src: url('../fonts/Aspekta-600.woff2') format('woff2'); } +@font-face { font-family: 'Aspekta'; font-style: normal; font-weight: 700; font-display: swap; src: url('../fonts/Aspekta-700.woff2') format('woff2'); } + +/* Source Serif 4: headings and body content (variable font, latin subset). */ +@font-face { font-family: 'Source Serif 4'; font-style: normal; font-weight: 200 900; font-display: swap; src: url('../fonts/source-serif-4-roman.woff2') format('woff2'); } +@font-face { font-family: 'Source Serif 4'; font-style: italic; font-weight: 200 900; font-display: swap; src: url('../fonts/source-serif-4-italic.woff2') format('woff2'); } + +:root { + --md-text-font: 'Aspekta'; + /* The design system's mono token is the system mono stack; no font file. */ + --md-code-font: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas; + --gh-serif: 'Source Serif 4', 'Source Serif Pro', Georgia, serif; +} + +/* Light: warm off-white surfaces, off-black text, orange accent. */ +[data-md-color-scheme='default'] { + --md-default-bg-color: #F9F9F7; /* off-white */ + --md-default-fg-color: #161614; /* off-black */ + --md-default-fg-color--light: #575753; /* grey.7 */ + --md-default-fg-color--lighter: #A6A69F; /* grey.4 */ + --md-default-fg-color--lightest: #F0F0EC; /* grey.1 */ + --md-primary-fg-color: #161614; + --md-primary-fg-color--light: #2F2F2C; + --md-primary-fg-color--dark: #161614; + --md-primary-bg-color: #F9F9F7; + --md-primary-bg-color--light: #DDDDD7; + --md-accent-fg-color: #D95E2A; + --md-accent-fg-color--transparent: rgba(217, 94, 42, 0.1); + --md-typeset-a-color: #D95E2A; + --md-code-bg-color: #F0F0EC; /* grey.1 */ + --md-code-fg-color: #2F2F2C; /* grey.8 */ + --md-typeset-mark-color: rgba(217, 94, 42, 0.25); + --md-typeset-table-color: rgba(22, 22, 20, 0.12); + --md-typeset-table-color--light: rgba(22, 22, 20, 0.035); + --md-footer-bg-color: #161614; + --md-footer-bg-color--dark: #161614; + --md-footer-fg-color: #F9F9F7; + --md-footer-fg-color--light: #C4C4BD; +} + +/* Dark: off-black background, warm grey surfaces, same orange. */ +[data-md-color-scheme='slate'] { + --md-hue: 60; /* fallback for anything still derived from hue */ + --md-default-bg-color: #161614; /* off-black */ + --md-default-fg-color: #F9F9F7; /* off-white */ + --md-default-fg-color--light: #C4C4BD; /* grey.3 */ + --md-default-fg-color--lighter: #7F7F79; /* grey.5 */ + --md-default-fg-color--lightest: #2F2F2C; /* grey.8 */ + --md-primary-fg-color: #161614; + --md-primary-fg-color--light: #2F2F2C; + --md-primary-fg-color--dark: #161614; + --md-primary-bg-color: #F9F9F7; + --md-primary-bg-color--light: #DDDDD7; + --md-accent-fg-color: #D95E2A; + --md-accent-fg-color--transparent: rgba(217, 94, 42, 0.1); + --md-typeset-a-color: #D95E2A; + --md-code-bg-color: #2F2F2C; /* grey.8 */ + --md-code-fg-color: #F0F0EC; /* grey.1 */ + --md-typeset-mark-color: rgba(217, 94, 42, 0.3); + --md-typeset-table-color: rgba(249, 249, 247, 0.12); + --md-typeset-table-color--light: rgba(249, 249, 247, 0.035); + --md-footer-bg-color: #111110; + --md-footer-bg-color--dark: #111110; +} + +/* Body content reads in serif; headings serif semibold with tight tracking. */ +.md-typeset { + font-family: var(--gh-serif); + line-height: 1.625; +} +.md-typeset h1, +.md-typeset h2, +.md-typeset h3, +.md-typeset h4 { + font-family: var(--gh-serif); + font-weight: 600; + letter-spacing: -0.025em; + color: var(--md-default-fg-color); +} +.md-typeset h1 { + margin-bottom: 1em; +} +.md-typeset h5, +.md-typeset h6 { + font-family: 'Aspekta', ui-sans-serif, system-ui, sans-serif; +} + +/* UI chrome stays in the sans: nav, tabs, search, buttons, labels. */ +.md-header, +.md-tabs, +.md-nav, +.md-search, +.md-footer, +.md-typeset .md-button, +.md-top { + font-family: 'Aspekta', ui-sans-serif, system-ui, sans-serif; +} + +/* Tables and admonition titles are UI, not prose. */ +.md-typeset table:not([class]) { + font-family: 'Aspekta', ui-sans-serif, system-ui, sans-serif; +} +.md-typeset .admonition-title, +.md-typeset summary { + font-family: 'Aspekta', ui-sans-serif, system-ui, sans-serif; +} +.md-typeset .admonition, +.md-typeset details { + font-size: 0.72rem; +} + +/* Corner radius per the radii tokens. */ +.md-typeset pre > code { + border-radius: 0.375rem; +} +.md-typeset .admonition, +.md-typeset details { + border-radius: 0.375rem; +} + +/* Header: off-black bar, off-white text, like the app header. */ +.md-header { + background-color: #161614; + color: #F9F9F7; +} +.md-header__title { + font-weight: 600; +} diff --git a/mkdocs.yml b/mkdocs.yml index 9070e85..e4767c7 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -12,24 +12,28 @@ docs_dir: docs theme: name: material + logo: assets/images/greyhaven-symbol-white.svg + favicon: assets/images/favicon.svg features: - navigation.sections - navigation.top - navigation.instant - content.code.copy - search.suggest + # Colors come from extra_css (the Greyhaven tokens); "custom" stops the + # theme from emitting its own color rules that would override them. palette: - media: "(prefers-color-scheme: light)" scheme: default - primary: black - accent: indigo + primary: custom + accent: custom toggle: icon: material/brightness-7 name: Switch to dark mode - media: "(prefers-color-scheme: dark)" scheme: slate - primary: black - accent: indigo + primary: custom + accent: custom toggle: icon: material/brightness-4 name: Switch to light mode @@ -82,6 +86,9 @@ markdown_extensions: - pymdownx.highlight - pymdownx.inlinehilite +extra_css: + - assets/stylesheets/greyhaven.css + extra: social: - icon: fontawesome/brands/github