From 03ec79a1721763628cf83eb7c93731176d3038c4 Mon Sep 17 00:00:00 2001 From: Alessio Biancalana Date: Mon, 5 Oct 2026 16:43:10 +0200 Subject: [PATCH 1/5] feat(site): redesign docs with a dark-first systems aesthetic --- docusaurus.config.ts | 17 +- src/css/custom.css | 1091 ++++++++++++++++++++++++++++++++++-- src/pages/index.module.css | 565 ++++++++++++++++++- src/pages/index.tsx | 375 +++++++++++-- 4 files changed, 1964 insertions(+), 84 deletions(-) diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 28792a6..e54c2df 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -15,7 +15,12 @@ const config: Config = { trailingSlash: false, onBrokenLinks: 'throw', - onBrokenMarkdownLinks: 'warn', + + markdown: { + hooks: { + onBrokenMarkdownLinks: 'warn', + }, + }, i18n: { defaultLocale: 'en', @@ -40,6 +45,13 @@ const config: Config = { themeConfig: { image: 'img/social-card.png', + metadata: [ + { + name: 'keywords', + content: + 'sched_ext, sched_ext scheduler, Linux scheduler, BPF, OCI, Kubernetes operator, eBPF', + }, + ], colorMode: { defaultMode: 'dark', respectPrefersColorScheme: true, @@ -71,6 +83,7 @@ const config: Config = { href: 'https://github.com/schedkit', label: 'GitHub', position: 'right', + className: 'navbar__cta', }, ], }, @@ -107,7 +120,7 @@ const config: Config = { prism: { theme: prismThemes.github, darkTheme: prismThemes.dracula, - additionalLanguages: ['bash', 'yaml', 'toml', 'go', 'docker'], + additionalLanguages: ['bash', 'yaml', 'toml', 'go', 'docker', 'json'], }, } satisfies Preset.ThemeConfig, }; diff --git a/src/css/custom.css b/src/css/custom.css index f6701cc..3c2a0d4 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -1,38 +1,1065 @@ /** - * Light customisations on top of the default Docusaurus theme. - * Keep this file small. Heavy theming belongs in a swizzled component. + * schedkit docs — design system. + * + * Direction: systems / terminal. Dark-first, hairline borders instead of + * shadows, sharp radii, monospace for labels and code, generous line height + * for long-form technical prose. + * + * Light mode is a separately tuned theme, not an inversion. */ +/* ------------------------------------------------------------------ * + * Typography — system stacks only, no webfont requests. + * ------------------------------------------------------------------ */ + +:root { + --ifm-font-family-base: + ui-sans-serif, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, + 'Helvetica Neue', Arial, 'Noto Sans', sans-serif; + --ifm-font-family-monospace: + ui-monospace, 'SFMono-Regular', 'SF Mono', 'JetBrains Mono', Menlo, + Consolas, 'Liberation Mono', monospace; + + --ifm-font-size-base: 16.5px; + --ifm-line-height-base: 1.75; + --ifm-code-font-size: 87.5%; + + --ifm-heading-font-weight: 700; + --ifm-heading-line-height: 1.25; + + /* Terminal labels, eyebrows, sidebar groups. */ + --sk-font-mono: var(--ifm-font-family-monospace); + + --ifm-global-radius: 3px; + --ifm-toc-border-color: var(--sk-line); + --docusaurus-highlighted-code-line-bg: rgba(77, 163, 240, 0.14); + --ifm-h1-font-size: 2.15rem; + --ifm-h2-font-size: 1.55rem; + --ifm-h3-font-size: 1.2rem; +} + +/* ------------------------------------------------------------------ * + * Dark palette (default; darkMode default is 'dark') + * ------------------------------------------------------------------ */ + :root { - --ifm-color-primary: #2174b6; - --ifm-color-primary-dark: #1e69a4; - --ifm-color-primary-darker: #1c639b; - --ifm-color-primary-darkest: #175280; - --ifm-color-primary-light: #257fc4; - --ifm-color-primary-lighter: #2885cb; - --ifm-color-primary-lightest: #4296d9; - --ifm-code-font-size: 95%; - --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); -} - -[data-theme='dark'] { - --ifm-color-primary: #69ace2; - --ifm-color-primary-dark: #4799dc; - --ifm-color-primary-darker: #358fd9; - --ifm-color-primary-darkest: #237ec3; - --ifm-color-primary-light: #8bc0e9; - --ifm-color-primary-lighter: #a0cbed; - --ifm-color-primary-lightest: #c7e0f4; - --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); -} - -/* A bit more breathing room between paragraphs in long-form pages. */ -.markdown > p { - margin-bottom: 1.1rem; -} - -/* Slightly tighter inline code so it doesn't feel pasted on. */ + --ifm-color-primary: #5aa9f2; + --ifm-color-primary-dark: #479bec; + --ifm-color-primary-darker: #3f93e9; + --ifm-color-primary-darkest: #2e77cd; + --ifm-color-primary-light: #6db7f3; + --ifm-color-primary-lighter: #7bbfef; + --ifm-color-primary-lightest: #a2d3f7; + + --ifm-background-color: #0a0d13; + --ifm-background-surface-color: #10151d; + + --ifm-font-color-base: #b8c4d4; + --ifm-heading-color: #eef3fa; + --ifm-font-color-dark: #b8c4d4; + --ifm-font-color-darker: #d6dfea; + --ifm-font-color-darkest: #eef3fa; + --ifm-font-color-light: #9aa7b8; + --ifm-font-color-lighter: #7d8a9b; + --ifm-font-color-lightest: #6b7787; + + --ifm-color-emphasis-0: var(--ifm-font-color-base); + --ifm-color-emphasis-100: var(--ifm-background-color); + --ifm-color-emphasis-200: var(--ifm-background-surface-color); + --ifm-color-emphasis-300: #1b2230; + --ifm-color-emphasis-400: #29323f; + --ifm-color-emphasis-500: #3c4757; + --ifm-color-emphasis-600: #7d8a9b; + --ifm-color-emphasis-700: #b8c4d4; + --ifm-color-emphasis-800: #d6dfea; + --ifm-color-emphasis-900: #eef3fa; + + --ifm-navbar-background-color: rgba(10, 13, 19, 0.82); + --ifm-navbar-shadow: none; + --ifm-footer-background-color: #070a0f; + + /* Internal tokens. */ + --sk-bg-sunken: #070a0f; + --sk-surface-2: #161d27; + --sk-line: rgba(146, 168, 197, 0.14); + --sk-line-strong: rgba(146, 168, 197, 0.24); + --sk-grid: rgba(146, 168, 197, 0.055); + --sk-glow: rgba(77, 163, 240, 0.16); + --sk-term: #a9de74; + --sk-term-dim: #8fbf63; + --sk-code-bg: #0d1219; + --sk-inline-code-bg: #171f2a; + --sk-inline-code-fg: #a9d1f8; +} + +/* ------------------------------------------------------------------ * + * Light palette — independently tuned, warm-neutral, not inverted. + * ------------------------------------------------------------------ */ + +[data-theme='light'] { + --ifm-color-primary: #1a63b0; + --ifm-color-primary-dark: #185ba3; + --ifm-color-primary-darker: #17589e; + --ifm-color-primary-darkest: #134984; + --ifm-color-primary-light: #1c6bbd; + --ifm-color-primary-lighter: #1d70c5; + --ifm-color-primary-lightest: #2179d3; + + --ifm-background-color: #fdfdfc; + --ifm-background-surface-color: #ffffff; + + --ifm-font-color-base: #333c48; + --ifm-heading-color: #10161e; + --ifm-font-color-light: #5a6675; + --ifm-font-color-lighter: #5f6a79; + --ifm-font-color-lightest: #6b7684; + --ifm-font-color-dark: #2a323d; + --ifm-font-color-darker: #1e252e; + --ifm-font-color-darkest: #10161e; + + --ifm-color-emphasis-200: #ffffff; + --ifm-color-emphasis-300: #f4f5f7; + --ifm-color-emphasis-400: #e6e8ec; + --ifm-color-emphasis-500: #d2d6dc; + --ifm-color-emphasis-600: #5f6a79; + --ifm-color-emphasis-700: #4a5563; + --ifm-color-emphasis-800: #2a323d; + --ifm-color-emphasis-900: #10161e; + + --ifm-navbar-background-color: rgba(253, 253, 252, 0.85); + --ifm-footer-background-color: #f4f5f7; + + --sk-bg-sunken: #f7f8f9; + --sk-surface-2: #f4f5f7; + --sk-line: rgba(24, 38, 58, 0.13); + --sk-line-strong: rgba(24, 38, 58, 0.22); + --sk-grid: rgba(24, 38, 58, 0.045); + --sk-glow: rgba(26, 99, 176, 0.09); + --sk-term: #35701f; + --sk-term-dim: #4a7c37; + --sk-code-bg: #f7f8fa; + --sk-inline-code-bg: #eef0f4; + --sk-inline-code-fg: #1a4a86; + + --docusaurus-highlighted-code-line-bg: rgba(26, 99, 176, 0.09); +} + +/* ------------------------------------------------------------------ * + * Base + * ------------------------------------------------------------------ */ + +html { + scroll-behavior: smooth; + -webkit-text-size-adjust: 100%; +} + +body { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + font-variant-ligatures: none; +} + +::selection { + background: rgba(77, 163, 240, 0.28); + color: var(--ifm-heading-color); +} + +/* A single, consistent, keyboard-visible focus treatment everywhere. */ +:focus-visible { + outline: 2px solid var(--ifm-color-primary); + outline-offset: 2px; + border-radius: 2px; +} + +/* Thin, self-effacing scrollbars. */ +* { + scrollbar-width: thin; + scrollbar-color: var(--sk-line-strong) transparent; +} + +*::-webkit-scrollbar { + width: 9px; + height: 9px; +} + +*::-webkit-scrollbar-track { + background: transparent; +} + +*::-webkit-scrollbar-thumb { + background: var(--sk-line-strong); + border: 2px solid transparent; + background-clip: content-box; + border-radius: 999px; +} + +*::-webkit-scrollbar-thumb:hover { + background: var(--ifm-color-primary); + background-clip: content-box; +} + +.skipToContent_fallback { + border-radius: 2px; +} + +/* ------------------------------------------------------------------ * + * Navbar + * ------------------------------------------------------------------ */ + +.navbar { + border-bottom: 1px solid var(--sk-line); + padding-inline: 0.5rem; + backdrop-filter: saturate(160%) blur(12px); + -webkit-backdrop-filter: saturate(160%) blur(12px); +} + +.navbar__inner { + max-width: 1440px; + margin-inline: auto; +} + +.navbar__brand { + margin-right: 1.75rem; +} + +.navbar__logo { + height: 24px; + width: auto; +} + +.navbar__title { + font-family: var(--sk-font-mono); + font-weight: 600; + font-size: 1.02rem; + letter-spacing: -0.02em; + padding-inline-start: 0.55rem; +} + +.navbar__logo + .navbar__title { + padding-inline-start: 0.55rem; +} + +.navbar__link { + font-size: 0.875rem; + font-weight: 500; + letter-spacing: 0.01em; + transition: color 120ms ease; +} + +.navbar__link::after { + content: ''; + display: block; + height: 1px; + transform: scaleX(0); + transform-origin: left; + background: currentColor; + transition: transform 160ms ease; +} + +.navbar__link:hover::after, +.navbar__link--active::after { + transform: scaleX(1); +} + +.navbar__link--active { + color: var(--ifm-color-primary); +} + +.navbar .navbar__items--right { + margin-inline-start: auto; +} + +/* GitHub link gets an icon treatment rather than bare text on wide screens. */ +.navbar__link--github { + font-family: var(--sk-font-mono); + font-size: 0.8rem; + letter-spacing: 0.02em; +} + +.navbar__cta { + font-family: var(--sk-font-mono); + font-size: 0.78rem; + letter-spacing: 0.04em; + text-transform: uppercase; + border: 1px solid var(--sk-line-strong); + border-radius: var(--ifm-global-radius); + padding: 0.3rem 0.7rem; + transition: border-color 120ms ease, color 120ms ease; +} + +.navbar__cta:hover { + border-color: var(--ifm-color-primary); + color: var(--ifm-color-primary); + text-decoration: none; +} + +.navbar__cta::after { + display: none; +} + +/* Theme toggle: square-ish, hairline. */ +.navbar__items--right .clean-btn { + border: 1px solid var(--sk-line); + border-radius: var(--ifm-global-radius); + transition: border-color 120ms ease; +} + +.navbar__items--right .clean-btn:hover { + border-color: var(--sk-line-strong); + background: transparent; + color: var(--ifm-color-primary); +} + +.navbar__toggle, +.navbar__login { + border-radius: var(--ifm-global-radius); +} + +/* ------------------------------------------------------------------ * + * Sidebar + * ------------------------------------------------------------------ */ + +.sidebar { + border-right: 1px solid var(--sk-line); + padding-block: 1.5rem 3rem; +} + +.sidebar__group { + padding-inline-start: 0.55rem; +} + +.menu__list-item-collapsible { + list-style-type: none; +} + +.menu__list-item-collapsible > .menu__list-item-collapsible-toggle { + font-family: var(--sk-font-mono); + font-size: 0.7rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.1em; + color: var(--ifm-color-emphasis-600); + padding-block: 0.85rem 0.5rem; +} + +.menu__list-item-collapsible > .menu__list-item-collapsible-toggle:hover { + background: transparent; + color: var(--ifm-heading-color); +} + +.menu__list-item-collapsible-toggle::before { + background: var(--sk-line-strong); + height: 1px; + opacity: 1; +} + +.menu__list-item-collapsible-toggle:hover::before { + background: var(--sk-line-strong); + opacity: 1; +} + +.menu__link { + font-size: 0.895rem; + line-height: 1.45; + border-radius: var(--ifm-global-radius); + padding-block: 0.36rem; + transition: color 120ms ease, background-color 120ms ease; +} + +.menu__link:hover { + background: var(--sk-surface-2); + color: var(--ifm-heading-color); + text-decoration: none; +} + +.menu__link--active:not(.menu__link--sublist) { + background: var(--sk-surface-2); + color: var(--ifm-color-primary); + font-weight: 600; +} + +.menu__link--active:not(.menu__link--sublist)::before { + background: var(--ifm-color-primary); + width: 2px; + height: 1.05em; + opacity: 1; + left: -0.55rem; + border-radius: 2px; +} + +.menu__list-item > .menu__list-item-collapsible:hover { + background: transparent; +} + +/* ------------------------------------------------------------------ * + * Document content + * ------------------------------------------------------------------ */ + +.docItemContainer { + padding-block: 2.5rem 4rem; +} + +.theme-doc-markdown { + font-size: 1.01rem; +} + +.theme-doc-markdown > p, +.theme-doc-markdown > ul, +.theme-doc-markdown > ol { + margin-bottom: 1.15rem; +} + +/* + * Docusaurus renders the page title as

…

, so the h1 + * is not a direct child of .theme-doc-markdown. Both forms are covered. + */ +.theme-doc-markdown header > h1, +.theme-doc-markdown > h1 { + font-family: var(--sk-font-mono); + font-weight: 600; + font-size: 2rem; + letter-spacing: -0.035em; + margin-bottom: 1.5rem; +} + +.theme-doc-markdown header > h1::after, +.theme-doc-markdown > h1::after { + content: ''; + display: block; + width: 2.5rem; + height: 2px; + margin-top: 0.9rem; + background: var(--ifm-color-primary); +} + +.theme-doc-markdown > h2 { + font-size: 1.42rem; + letter-spacing: -0.022em; + margin-top: 2.9rem; + padding-top: 0.4rem; +} + +.theme-doc-markdown > h3 { + font-size: 1.13rem; + letter-spacing: -0.012em; + margin-top: 2.1rem; +} + +.theme-doc-markdown > h4, +.theme-doc-markdown > h5, +.theme-doc-markdown > h6 { + font-family: var(--sk-font-mono); + font-size: 0.94rem; + text-transform: uppercase; + letter-spacing: 0.06em; + color: var(--ifm-color-emphasis-700); + margin-top: 1.9rem; +} + +/* Prose measure: long lines are the fastest way to make docs unreadable. */ +@media screen and (min-width: 997px) { + .theme-doc-markdown { + max-width: 46rem; + } +} + +.theme-doc-markdown a { + text-decoration: underline; + text-decoration-color: var(--sk-line-strong); + text-underline-offset: 0.18em; + text-decoration-thickness: 1px; + transition: color 120ms ease, text-decoration-color 120ms ease; +} + +.theme-doc-markdown a:hover { + text-decoration-color: var(--ifm-color-primary); +} + +.theme-doc-markdown strong { + font-weight: 650; + color: var(--ifm-font-color-darkest); +} + +.theme-doc-markdown blockquote { + border-inline-start: 2px solid var(--sk-line-strong); + padding-inline-start: 1.1rem; + font-style: normal; + color: var(--ifm-color-emphasis-600); +} + +.theme-doc-markdown ul, +.theme-doc-markdown ol { + padding-inline-start: 1.4rem; +} + +.theme-doc-markdown li { + margin-bottom: 0.4rem; +} + +.theme-doc-markdown li::marker { + color: var(--sk-line-strong); +} + +.theme-doc-markdown hr { + border: 0; + border-top: 1px solid var(--sk-line); + margin-block: 2.75rem; +} + +.theme-doc-markdown img { + border: 1px solid var(--sk-line); + border-radius: var(--ifm-global-radius); +} + +/* Source-file breadcrumb above the page title. */ +.theme-doc-breadcrumbs { + font-family: var(--sk-font-mono); + font-size: 0.76rem; + letter-spacing: 0.03em; + margin-bottom: 0.9rem; +} + +.theme-doc-breadcrumbs__link { + background: var(--sk-surface-2); + border-radius: var(--ifm-global-radius); + padding: 0.15rem 0.45rem; + color: var(--ifm-color-emphasis-600); +} + +.theme-doc-breadcrumbs__link:hover { + background: var(--sk-surface-2); + color: var(--ifm-color-primary); +} + +/* Last-updated line under the title. */ +.theme-doc-footer-edit-info-row { + font-family: var(--sk-font-mono); + font-size: 0.76rem; + color: var(--ifm-color-emphasis-600); +} + +.theme-doc-footer-edit-info-row a { + text-decoration: none; +} + +.theme-doc-footer-edit-info-row a:hover { + color: var(--ifm-color-primary); +} + +/* "Edit this page" as a quiet monospace chip. */ +.theme-doc-footer-edit-meta-row { + margin-bottom: 2.5rem; +} + +.theme-doc-footer-edit-meta-row .button.button { + font-family: var(--sk-font-mono); + font-size: 0.75rem; + letter-spacing: 0.03em; + border: 1px solid var(--sk-line); + background: transparent; + color: var(--ifm-color-emphasis-700); +} + +.theme-doc-footer-edit-meta-row .button.button:hover { + border-color: var(--sk-line-strong); + background: transparent; + color: var(--ifm-color-primary); +} + +/* ------------------------------------------------------------------ * + * Code + * ------------------------------------------------------------------ */ + code { - border-radius: 4px; - padding: 0.1rem 0.3rem; + font-family: var(--sk-font-mono); + font-variant-ligatures: none; +} + +:not(pre) > code { + background: var(--sk-inline-code-bg); + color: var(--sk-inline-code-fg); + border: 1px solid var(--sk-line); + border-radius: var(--ifm-global-radius); + padding: 0.1em 0.36em; + font-size: 0.855em; + word-break: break-word; +} + +.theme-code-block { + margin-block: 1.5rem; + border: 1px solid var(--sk-line); + border-radius: var(--ifm-global-radius); + background: var(--sk-code-bg); + box-shadow: none; + overflow: hidden; +} + +.theme-code-block > pre { + margin: 0; + padding: 1.05rem 1.15rem; + font-size: 0.855rem; + line-height: 1.62; + background: transparent; +} + +.theme-code-block > pre > code { + background: transparent; + border: 0; + padding: 0; + font-size: inherit; + color: var(--ifm-font-color-base); + display: block; + white-space: pre; + overflow-x: auto; +} + +/* Language label, terminal-style, in the top-right of every code block. */ +.theme-code-block__title { + border-bottom: 1px solid var(--sk-line); + background: var(--sk-bg-sunken); +} + +.theme-code-block .code-block__title { + font-family: var(--sk-font-mono); + font-size: 0.68rem; + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.11em; + color: var(--ifm-color-emphasis-600); + padding: 0.3rem 0.75rem; + display: flex; + justify-content: flex-end; + align-items: center; + gap: 0.5rem; +} + +.theme-code-block .code-block__title::before { + content: ''; + width: 5px; + height: 5px; + border-radius: 50%; + background: var(--sk-term); + opacity: 0.75; +} + +/* The floating copy button needs to sit inside the block, not over it. */ +.theme-code-block > button { + border-radius: var(--ifm-global-radius); + background: var(--sk-surface-2); + border: 1px solid var(--sk-line); + color: var(--ifm-color-emphasis-600); + transition: color 120ms ease, border-color 120ms ease; +} + +.theme-code-block > button:hover { + color: var(--ifm-color-primary); + border-color: var(--sk-line-strong); +} + +.code-block__copy-button { + opacity: 0; + transition: opacity 140ms ease; +} + +.theme-code-block:hover .code-block__copy-button, +.code-block__copy-button:focus-visible { + opacity: 1; +} + +/* ------------------------------------------------------------------ * + * Tables + * ------------------------------------------------------------------ */ + +.theme-doc-markdown table { + display: table; + width: 100%; + margin-block: 1.5rem; + font-size: 0.9rem; + border-collapse: separate; + border-spacing: 0; + border: 1px solid var(--sk-line); + border-radius: var(--ifm-global-radius); + overflow: hidden; +} + +.theme-doc-markdown table thead { + background: var(--sk-surface-2); +} + +.theme-doc-markdown table th { + font-family: var(--sk-font-mono); + font-size: 0.72rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--ifm-color-emphasis-700); + text-align: left; +} + +.theme-doc-markdown table th, +.theme-doc-markdown table td { + padding: 0.65rem 0.85rem; + border-color: var(--sk-line); + vertical-align: top; +} + +.theme-doc-markdown table tbody tr:nth-child(even) { + background: transparent; +} + +.theme-doc-markdown table tbody tr:hover { + background: var(--sk-surface-2); +} + +/* ------------------------------------------------------------------ * + * Admonitions — left accent bar over heavy fills + * ------------------------------------------------------------------ */ + +.theme-doc-markdown .alert { + border: 1px solid var(--sk-line); + border-inline-start: 3px solid var(--ifm-color-primary); + border-radius: var(--ifm-global-radius); + background: var(--sk-surface-2); + box-shadow: none; + color: var(--ifm-font-color-base); + margin-block: 1.6rem; +} + +.theme-doc-markdown .alert--info, +.theme-doc-markdown .alert--secondary, +.theme-doc-markdown .alert--success, +.theme-doc-markdown .alert--note { + --ifm-alert-color: var(--ifm-color-primary); +} + +.theme-doc-markdown .alert--tip { + --ifm-alert-color: var(--sk-term); +} + +.theme-doc-markdown .alert--warning { + --ifm-alert-color: #d9a441; +} + +.theme-doc-markdown .alert--danger { + --ifm-alert-color: #e5646d; +} + +.theme-doc-markdown .alert__icon { + color: var(--ifm-alert-color); +} + +.theme-doc-markdown .alert__title { + font-family: var(--sk-font-mono); + font-size: 0.72rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.1em; + color: var(--ifm-alert-color); +} + +/* ------------------------------------------------------------------ * + * Cards, pagination, buttons + * ------------------------------------------------------------------ */ + +.card { + border: 1px solid var(--sk-line); + border-radius: var(--ifm-global-radius); + background: var(--ifm-background-surface-color); + box-shadow: none; + transition: border-color 140ms ease, transform 140ms ease; +} + +.card:hover { + border-color: var(--sk-line-strong); +} + +.card__header, +.card__body, +.card__footer { + border-color: var(--sk-line); +} + +.card__title { + font-family: var(--sk-font-mono); + font-size: 1rem; + letter-spacing: -0.01em; +} + +.card--linkable:hover { + transform: translateY(-2px); + border-color: var(--ifm-color-primary); +} + +.pagination-nav__link { + border: 1px solid var(--sk-line); + border-radius: var(--ifm-global-radius); + transition: border-color 140ms ease; +} + +.pagination-nav__link:hover { + border-color: var(--sk-line-strong); +} + +.pagination-nav__sublabel { + font-family: var(--sk-font-mono); + font-size: 0.68rem; + text-transform: uppercase; + letter-spacing: 0.11em; + color: var(--ifm-color-emphasis-600); +} + +.pagination-nav__label { + font-size: 0.95rem; + font-weight: 600; +} + +.button { + border-radius: var(--ifm-global-radius); + font-weight: 600; + transition: background-color 130ms ease, border-color 130ms ease, + color 130ms ease; +} + +/* + * Infima ships competing rules at (0,2,0) — `.button.button--secondary`, + * `.button.button--outline`, `.button:hover` — so every rule below is scoped + * with `.button` and declares a hover state explicitly. A bare + * `.button--secondary` silently loses and renders black-on-black in dark mode. + */ +.button.button--primary { + background: var(--ifm-color-primary); + border-color: var(--ifm-color-primary); + color: #ffffff; +} + +[data-theme='dark'] .button.button--primary { + color: #06121d; +} + +.button.button--primary:hover { + background: var(--ifm-color-primary-dark); + border-color: var(--ifm-color-primary-dark); + color: #ffffff; +} + +[data-theme='dark'] .button.button--primary:hover { + color: #06121d; +} + +.button.button--secondary, +.button.button--outline { + border-color: var(--sk-line-strong); + color: var(--ifm-font-color-darkest); + background: transparent; +} + +.button.button--secondary:hover, +.button.button--outline:hover { + background: var(--sk-surface-2); + border-color: var(--ifm-color-primary); + color: var(--ifm-color-primary); +} + +.button.button--outline--primary { + border-color: var(--sk-line-strong); + color: var(--ifm-color-primary); +} + +/* + * `button--outline` and `button--primary` are two separate Infima classes, so + * `.button--outline--primary` alone never matches an element carrying both. + * This form is what `className="button button--outline button--primary"` + * actually hits — and it needs to out-specify the dark-mode primary rule. + */ +.button.button--outline.button--primary, +[data-theme='dark'] .button.button--outline.button--primary { + background: transparent; + border-color: var(--sk-line-strong); + color: var(--ifm-color-primary); +} + +.button.button--outline.button--primary:hover, +[data-theme='dark'] .button.button--outline.button--primary:hover { + background: var(--ifm-color-primary); + border-color: var(--ifm-color-primary); + color: #ffffff; +} + +[data-theme='dark'] .button.button--outline.button--primary:hover { + color: #06121d; +} + +.tabs-container .tabs { + border-bottom: 1px solid var(--sk-line); +} + +.tabs-container .tabs__item { + font-family: var(--sk-font-mono); + font-size: 0.8rem; + letter-spacing: 0.03em; + border-color: var(--sk-line-strong); +} + +.tabs-container .tabs__item--active { + color: var(--ifm-color-primary); + border-color: var(--ifm-color-primary); +} + +.dropdown__menu { + border: 1px solid var(--sk-line); + border-radius: var(--ifm-global-radius); + background: var(--ifm-background-surface-color); + box-shadow: 0 12px 32px rgba(0, 0, 0, 0.28); +} + +/* ------------------------------------------------------------------ * + * Prism — dark + * ------------------------------------------------------------------ */ + +/* + * prism-react-renderer injects its theme from the JS bundle at runtime, after + * the stylesheet link, so ordinary specificity does not reliably win. The + * stock github (light) theme also drops two token colours below 4.5:1 on our + * light code background: `.token.function` (#d73a49) and `.token.parameter` + * (#36acaa). Darken just those two. Dark is left alone — dracula is >7:1. + */ +[data-theme='light'] .token.function { + color: #b02a37 !important; +} + +[data-theme='light'] .token.parameter, +[data-theme='light'] .token.parameter .token.punctuation { + color: #0b7285 !important; +} + +/* ------------------------------------------------------------------ * + * Table of contents + * ------------------------------------------------------------------ */ + +.table-of-contents { + font-size: 0.83rem; + padding-block-start: 2.5rem; +} + +.table-of-contents__title { + font-family: var(--sk-font-mono); + font-size: 0.68rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.11em; + color: var(--ifm-color-emphasis-600); + margin-bottom: 0.8rem; +} + +.table-of-contents__link { + line-height: 1.5; + padding-block: 0.16rem; +} + +.table-of-contents__link--active { + font-weight: 600; +} + +/* ------------------------------------------------------------------ * + * Footer + * ------------------------------------------------------------------ */ + +.footer { + border-top: 1px solid var(--sk-line); + margin-top: 3rem; +} + +/* + * The footer is `style: 'dark'` in both themes, so it carries its own fixed + * palette. Theme-scoped text tokens (--ifm-color-emphasis-600 and friends) + * are wrong in one theme or the other, which silently failed contrast. + */ +.footer { + background-color: #070a0f; + border-top: 1px solid rgba(146, 168, 197, 0.16); + color: #aab6c5; +} + +.footer__title { + font-family: var(--sk-font-mono); + font-size: 0.7rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.11em; + margin-bottom: 0.9rem; + color: #8d99a8; +} + +.footer__link-item, +.footer__link-item a { + font-size: 0.875rem; + color: #aab6c5; +} + +.footer__link-item a:hover { + color: #d7e3f2; +} + +.footer__bottom { + border-top: 1px solid rgba(146, 168, 197, 0.16); + font-family: var(--sk-font-mono); + font-size: 0.76rem; + letter-spacing: 0.01em; + text-align: center; + color: #8d99a8; +} + +.footer__copyright { + margin-top: 0.35rem; + color: #8d99a8; +} + +/* ------------------------------------------------------------------ * + * Pagination label above page title on doc pages + * ------------------------------------------------------------------ */ + +.pagination-label { + font-family: var(--sk-font-mono); + font-size: 0.68rem; + text-transform: uppercase; + letter-spacing: 0.1em; + color: var(--ifm-color-emphasis-600); +} + +/* ------------------------------------------------------------------ * + * Shared decorative primitives used by the homepage. + * ------------------------------------------------------------------ */ + +.sk-grid-bg { + background-image: + linear-gradient(var(--sk-grid) 1px, transparent 1px), + linear-gradient(90deg, var(--sk-grid) 1px, transparent 1px); + background-size: 46px 46px; +} + +.sk-eyebrow { + font-family: var(--sk-font-mono); + font-size: 0.72rem; + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.14em; + color: var(--ifm-color-emphasis-600); +} + +/* ------------------------------------------------------------------ * + * Motion — respect the OS, always. + * ------------------------------------------------------------------ */ + +@media (prefers-reduced-motion: reduce) { + html { + scroll-behavior: auto; + } + + *, + *::before, + *::after { + animation-duration: 0.001ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.001ms !important; + } } diff --git a/src/pages/index.module.css b/src/pages/index.module.css index a80aca5..a74563e 100644 --- a/src/pages/index.module.css +++ b/src/pages/index.module.css @@ -1,32 +1,571 @@ +/** + * Homepage styles. Consumed only by src/pages/index.tsx — CSS-module scoped. + * Shared primitives (sk-grid-bg, sk-eyebrow) live in src/css/custom.css. + */ + .hero { - padding: 4rem 0; - text-align: center; - background: linear-gradient(135deg, var(--ifm-color-primary-darkest) 0%, var(--ifm-color-primary) 100%); - color: white; + position: relative; + overflow: hidden; + padding: 5.5rem 0 5rem; + border-bottom: 1px solid var(--sk-line); + background-color: var(--sk-bg-sunken); +} + +/* Soft radial wash behind the hero copy. */ +.heroGlow { + position: absolute; + inset: -40% -10% auto -10%; + height: 120%; + pointer-events: none; + background: + radial-gradient( + 55% 55% at 22% 32%, + var(--sk-glow) 0%, + transparent 70% + ), + radial-gradient( + 40% 45% at 78% 18%, + rgba(158, 206, 106, 0.07) 0%, + transparent 70% + ); + mask-image: linear-gradient(to bottom, #000 30%, transparent 90%); + -webkit-mask-image: linear-gradient(to bottom, #000 30%, transparent 90%); +} + +.heroInner { + position: relative; + display: grid; + grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); + gap: 4rem; + align-items: center; +} + +.heroCopy { + min-width: 0; +} + +.heroEyebrow { + display: inline-flex; + align-items: center; + gap: 0.55rem; + margin: 0 0 1.5rem; + padding: 0.3rem 0.7rem 0.3rem 0.6rem; + border: 1px solid var(--sk-line); + border-radius: 999px; + background: var(--sk-surface-2); + font-family: var(--sk-font-mono); + font-size: 0.7rem; + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.1em; + color: var(--ifm-color-emphasis-600); +} + +/* Pulsing "host is ready" indicator. */ +.statusDot { + width: 6px; + height: 6px; + border-radius: 50%; + background: var(--sk-term); + box-shadow: 0 0 0 0 var(--sk-term-dim); + animation: statusPulse 2.6s ease-out infinite; +} + +@keyframes statusPulse { + 0% { + box-shadow: 0 0 0 0 var(--sk-term-dim); + } + 70% { + box-shadow: 0 0 0 7px transparent; + } + 100% { + box-shadow: 0 0 0 0 transparent; + } +} + +.heroTitle { + margin: 0 0 1rem; + font-family: var(--sk-font-mono); + font-size: clamp(2.9rem, 6vw, 4.35rem); + font-weight: 600; + line-height: 1; + letter-spacing: -0.045em; + color: var(--ifm-heading-color); +} + +.heroTagline { + margin: 0 0 1.25rem; + max-width: 34ch; + font-size: 1.28rem; + line-height: 1.4; + letter-spacing: -0.018em; + color: var(--ifm-font-color-dark); + text-wrap: balance; +} + +.heroBlurb { + margin: 0 0 2rem; + max-width: 52ch; + font-size: 1.01rem; + color: var(--ifm-color-emphasis-700); +} + +.heroActions { + display: flex; + flex-wrap: wrap; + gap: 0.75rem; + margin-bottom: 1.75rem; +} + +.heroActions :global(.button) { + font-size: 0.95rem; + padding-inline: 1.35rem; +} + +.heroMeta { + margin: 0; + font-family: var(--sk-font-mono); + font-size: 0.78rem; + letter-spacing: 0.01em; + color: var(--ifm-color-emphasis-600); +} + +.heroMeta a { + color: inherit; + text-decoration: none; + border-bottom: 1px solid var(--sk-line-strong); + padding-bottom: 1px; + transition: color 120ms ease, border-color 120ms ease; +} + +.heroMeta a:hover { + color: var(--ifm-color-primary); + border-color: var(--ifm-color-primary); + text-decoration: none; +} + +/* ---- Terminal card ---- */ + +.heroPanel { + min-width: 0; +} + +.terminal { + border: 1px solid var(--sk-line-strong); + border-radius: var(--ifm-global-radius); + background: var(--sk-code-bg); + overflow: hidden; + box-shadow: 0 24px 60px -28px rgba(0, 0, 0, 0.55); +} + +.terminalBar { + display: flex; + align-items: center; + gap: 0.4rem; + padding: 0.55rem 0.75rem; + border-bottom: 1px solid var(--sk-line); + background: var(--sk-bg-sunken); +} + +.terminalDot { + width: 8px; + height: 8px; + border-radius: 50%; + background: var(--sk-line-strong); +} + +.terminalTitle { + margin-left: 0.5rem; + font-family: var(--sk-font-mono); + font-size: 0.7rem; + letter-spacing: 0.02em; + color: var(--ifm-color-emphasis-600); +} + +.terminalBody { + margin: 0; + padding: 1rem 1.1rem; + overflow-x: auto; + font-family: var(--sk-font-mono); + font-size: 0.755rem; + line-height: 1.72; +} + +.terminalBody code { + display: block; + background: transparent; + border: 0; + padding: 0; + font-size: inherit; + white-space: pre; + color: var(--ifm-font-color-base); +} + +/* Command line: prompt glyph in accent, text in heading colour. */ +.termPrompt { + color: var(--ifm-heading-color); + font-weight: 600; +} + +/* A passing check line: dimmed, like real diagnostic output. */ +.termCheck { + color: var(--sk-term-dim); +} + +/* Closing summary line gets full terminal green. */ +.termSummary { + color: var(--sk-term); +} + +/* ---- Section scaffolding ---- */ + +.split, +.tools, +.routes, +.requirements, +.closing { + padding: 5rem 0; +} + +.sectionHead { + max-width: 46rem; + margin-bottom: 3rem; +} + +.sectionTitle { + margin: 0.6rem 0 0; + font-size: clamp(1.6rem, 3vw, 2.1rem); + letter-spacing: -0.028em; + color: var(--ifm-heading-color); + text-wrap: balance; +} + +.sectionLede { + margin: 1rem 0 0; + max-width: 54ch; + color: var(--ifm-color-emphasis-700); +} + +/* ---- Split ---- */ + +.splitGrid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 3.5rem; +} + +.splitCol { + padding-top: 1.25rem; + border-top: 1px solid var(--sk-line); +} + +.splitTitle { + margin: 0.55rem 0 0.9rem; + font-size: 1.45rem; + letter-spacing: -0.022em; +} + +.splitCol p { + margin: 0; + color: var(--ifm-color-emphasis-700); + max-width: 46ch; +} + +/* ---- Tools ---- */ + +.tools { + border-top: 1px solid var(--sk-line); + background: var(--sk-bg-sunken); +} + +.toolGrid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 1.5rem; } -.buttons { +.tool { display: flex; + flex-direction: column; + padding: 1.85rem; + border: 1px solid var(--sk-line); + border-radius: var(--ifm-global-radius); + background: var(--ifm-background-surface-color); + transition: border-color 140ms ease, transform 140ms ease; +} + +.tool:hover { + border-color: var(--sk-line-strong); + transform: translateY(-2px); +} + +.toolHead { + margin-bottom: 1.1rem; +} + +.toolName { + margin: 0 0 0.35rem; + font-family: var(--sk-font-mono); + font-size: 1.4rem; + font-weight: 600; + letter-spacing: -0.03em; + color: var(--ifm-heading-color); +} + +.toolBlurb { + margin: 0; + font-size: 0.94rem; + font-weight: 600; + color: var(--ifm-color-primary); +} + +.toolDetail { + margin: 0 0 1.5rem; + color: var(--ifm-color-emphasis-700); + font-size: 0.965rem; +} + +.toolInstall { + display: flex; + align-items: baseline; + gap: 0.55rem; + margin-top: auto; + padding: 0.7rem 0.85rem; + border: 1px solid var(--sk-line); + border-radius: var(--ifm-global-radius); + background: var(--sk-code-bg); + overflow-x: auto; +} + +.toolPrompt { + font-family: var(--sk-font-mono); + font-size: 0.8rem; + color: var(--ifm-color-primary); + user-select: none; +} + +.toolInstall code { + font-size: 0.8rem; + white-space: nowrap; + background: transparent; + border: 0; + padding: 0; + color: var(--ifm-font-color-base); +} + +.toolCta { + align-self: flex-start; + margin-top: 1.25rem; + font-size: 0.85rem; +} + +/* ---- Routes ---- */ + +.routeList { + list-style: none; + margin: 0; + padding: 0; + border-top: 1px solid var(--sk-line); +} + +.route { + display: grid; + grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr) auto; + gap: 1.5rem; align-items: center; + padding: 1.4rem 0.25rem; + border-bottom: 1px solid var(--sk-line); + color: inherit; + transition: padding-left 140ms ease, border-color 140ms ease; +} + +.route:hover { + color: inherit; + text-decoration: none; + padding-left: 0.75rem; + border-color: var(--ifm-color-primary); +} + +.routeWhen { + font-family: var(--sk-font-mono); + font-size: 0.86rem; + font-weight: 500; + color: var(--ifm-heading-color); +} + +.routeGo { + font-size: 0.95rem; + color: var(--ifm-color-emphasis-600); +} + +.routeArrow { + font-family: var(--sk-font-mono); + color: var(--ifm-color-emphasis-600); + transition: color 140ms ease, transform 140ms ease; +} + +.route:hover .routeArrow { + color: var(--ifm-color-primary); + transform: translateX(4px); +} + +/* ---- Requirements ---- */ + +.requirements { + border-top: 1px solid var(--sk-line); + border-bottom: 1px solid var(--sk-line); + background-color: var(--sk-bg-sunken); +} + +.reqGrid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 1px; + margin: 0; + background: var(--sk-line); + border: 1px solid var(--sk-line); + border-radius: var(--ifm-global-radius); + overflow: hidden; +} + +.req { + display: grid; + grid-template-columns: 9.5rem minmax(0, 1fr); + gap: 1.1rem; + padding: 1.25rem 1.35rem; + background: var(--ifm-background-surface-color); +} + +.reqId { + margin: 0; + font-family: var(--sk-font-mono); + font-size: 0.78rem; + color: var(--sk-term); + word-break: break-word; +} + +.reqBody { + margin: 0; + display: flex; + flex-direction: column; + gap: 0.3rem; +} + +.reqWhat { + font-size: 0.95rem; + font-weight: 600; + color: var(--ifm-heading-color); +} + +.reqWhy { + font-size: 0.885rem; + line-height: 1.6; + color: var(--ifm-color-emphasis-600); +} + +/* ---- Closing CTA ---- */ + +.closing { + text-align: center; +} + +.closingTitle { + margin: 0 0 1rem; + font-family: var(--sk-font-mono); + font-size: clamp(1.7rem, 3.5vw, 2.35rem); + font-weight: 600; + letter-spacing: -0.035em; + color: var(--ifm-heading-color); +} + +.closingText { + margin: 0 auto 2rem; + max-width: 50ch; + color: var(--ifm-color-emphasis-700); +} + +.closingActions { + display: flex; + flex-wrap: wrap; + gap: 0.75rem; justify-content: center; - gap: 1rem; - margin-top: 2rem; } -.projects { - padding: 4rem 0; +.closingActions :global(.button) { + font-size: 0.95rem; + padding-inline: 1.35rem; } -.projects h2 { - margin-top: 0; +/* ------------------------------------------------------------------ * + * Responsive + * ------------------------------------------------------------------ */ + +@media screen and (max-width: 1100px) { + .req { + grid-template-columns: minmax(0, 1fr); + gap: 0.45rem; + } } @media screen and (max-width: 996px) { .hero { - padding: 2rem 1rem; + padding: 3.5rem 0 3.25rem; + } + + .heroInner { + grid-template-columns: minmax(0, 1fr); + gap: 2.75rem; + } + + .heroTagline, + .heroBlurb { + max-width: none; + } + + .split, + .tools, + .routes, + .requirements, + .closing { + padding: 3.5rem 0; + } + + .splitGrid, + .toolGrid, + .reqGrid { + grid-template-columns: minmax(0, 1fr); + gap: 1.25rem; + } + + .route { + grid-template-columns: minmax(0, 1fr) auto; + gap: 0.5rem 1rem; + } + + .routeGo { + grid-column: 1 / -1; + grid-row: 2; + } + + .routeArrow { + grid-column: 2; + grid-row: 1; } +} - .buttons { +@media screen and (max-width: 576px) { + .heroActions, + .closingActions { flex-direction: column; + align-items: stretch; + } + + .heroActions :global(.button), + .closingActions :global(.button) { + width: 100%; + } + + .terminalBody { + font-size: 0.7rem; } } diff --git a/src/pages/index.tsx b/src/pages/index.tsx index bbd60bc..a28c98a 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -7,58 +7,142 @@ import Heading from '@theme/Heading'; import styles from './index.module.css'; +/* ------------------------------------------------------------------ * + * Hero + * ------------------------------------------------------------------ */ + +/** + * Illustrative `schedctl doctor` output. The command, the flag set and the + * check IDs mirror docs/schedctl/commands.md — this is a stylised render of + * the documented checks, not a captured transcript. + */ +type SessionKind = 'prompt' | 'check' | 'summary'; + +const DOCTOR_SESSION: Array<[SessionKind, string]> = [ + ['prompt', '$ sudo schedctl doctor'], + ['check', 'kernel.version kernel 6.12.0 ok'], + ['check', 'kernel.sched_ext /sys/kernel/sched_ext ok'], + ['check', 'kernel.btf /sys/kernel/btf/vmlinux ok'], + ['check', 'kernel.config CONFIG_SCHED_CLASS_EXT=y ok'], + ['check', 'caps.cap_bpf ok'], + ['check', 'caps.cap_sys_admin ok'], + ['check', 'caps.cap_perfmon ok'], + ['check', 'runtime.any podman socket ok'], + ['summary', 'no blocking failures — host is ready'], +]; + +const SESSION_CLASS: Record = { + prompt: styles.termPrompt, + check: styles.termCheck, + summary: styles.termSummary, +}; + +function Terminal() { + return ( +
+ +
+        
+          {DOCTOR_SESSION.map(([kind, line], i) => (
+            
+              {line}
+              {'\n'}
+            
+          ))}
+        
+      
+
+ ); +} + function Hero() { const {siteConfig} = useDocusaurusContext(); return ( -
+
+
); } -function Projects() { +/* ------------------------------------------------------------------ * + * Section: the split + * ------------------------------------------------------------------ */ + +function Split() { return ( -
+
-
-
- schedctl +
+
+

The kernel half

+ + Already solved +

- The host-side CLI. Verifies, pulls, and runs an OCI-packaged - sched_ext scheduler, with built-in kernel preflight - (schedctl doctor) and discrepancy reporting - (schedctl status). Available on openSUSE Tumbleweed - and the AUR. + Since Linux 6.12, a scheduler is a BPF program the kernel loads, + verifies and unloads on demand. No custom kernel, no module, no + maintenance window. The safety story stays with the kernel, which + verifies a scheduler before letting it touch threads.

- - Read the docs -
-
- sked +
+

The schedkit half

+ + The boring parts +

- The Kubernetes operator. A SchedExt resource names - the OCI scheduler image you want to run; sked creates a - privileged DaemonSet that runs it on the cluster. Early-stage - and minimal today — the place to start if your nodes already - live in Kubernetes. + How do you ship a scheduler binary? How do you know whether it is + running on a given machine? How do you roll back when it behaves + badly? How do any of that work across more than one host? Those + are the problems this project exists for.

- - Read the docs -
@@ -66,15 +150,232 @@ function Projects() { ); } +/* ------------------------------------------------------------------ * + * Section: the two tools + * ------------------------------------------------------------------ */ + +type Tool = { + name: string; + blurb: string; + detail: string; + install: string; + href: string; + cta: string; +}; + +const TOOLS: Tool[] = [ + { + name: 'schedctl', + blurb: 'The host-side CLI.', + detail: + 'Verifies, pulls and runs an OCI-packaged sched_ext scheduler, with a kernel preflight and discrepancy reporting built in. Reaches for a scheduler on one machine — for the length of a build, a game session, or a test run.', + install: 'sudo zypper in schedctl', + href: '/docs/schedctl/overview', + cta: 'schedctl docs', + }, + { + name: 'sked', + blurb: 'The Kubernetes operator.', + detail: + 'A SchedExt resource names the OCI scheduler image you want; sked reconciles it into a privileged DaemonSet on every node it should run on. The cluster-native path — no schedctl needed on the nodes.', + install: 'make deploy IMG=ghcr.io/schedkit/sked:latest', + href: '/docs/sked/overview', + cta: 'sked docs', + }, +]; + +function Tools() { + return ( +
+
+
+

Two tools

+ + Pick the one that matches your machine + +
+
+ {TOOLS.map((tool) => ( +
+
+ + {tool.name} + +

{tool.blurb}

+
+

{tool.detail}

+
+ + {tool.install} +
+ + {tool.cta} → + +
+ ))} +
+
+
+ ); +} + +/* ------------------------------------------------------------------ * + * Section: routes + * ------------------------------------------------------------------ */ + +type Route = { + when: string; + go: string; + href: string; +}; + +const ROUTES: Route[] = [ + { + when: 'You want to understand the design before touching anything', + go: 'Start with the Concepts section — what sched_ext is and is not, and why OCI ended up as the distribution format.', + href: '/docs/concepts/sched-ext', + }, + { + when: 'You have one machine and want to try a scheduler now', + go: 'Install schedctl, run the preflight, and attach something.', + href: '/docs/schedctl/installation', + }, + { + when: 'Your nodes already live in Kubernetes', + go: 'Install sked and declare a SchedExt resource.', + href: '/docs/sked/installation', + }, + { + when: 'You are trying to package your own scheduler', + go: 'The packaging walkthrough covers the image layout sked and schedctl both expect.', + href: '/docs/schedctl/packaging-a-scheduler', + }, +]; + +function Routes() { + return ( +
+
+
+

Where to start

+ + Four ways in + +
+
    + {ROUTES.map((route) => ( +
  • + + {route.when} + {route.go} + + +
  • + ))} +
+
+
+ ); +} + +/* ------------------------------------------------------------------ * + * Section: requirements + * ------------------------------------------------------------------ */ + +const REQUIREMENTS: Array<[string, string, string]> = [ + ['kernel.version', 'Linux 6.12 or later', 'The version that shipped sched_ext upstream.'], + ['kernel.config', 'CONFIG_SCHED_CLASS_EXT=y', 'Alongside the CONFIG_BPF* flags and CONFIG_DEBUG_INFO_BTF for CO-RE programs.'], + ['runtime.any', 'A reachable runtime socket', 'Podman or containerd, so the scheduler can be pulled as an OCI image.'], + ['privileges', 'CAP_BPF, CAP_SYS_ADMIN, CAP_PERFMON', 'Checked by schedctl doctor. sked instead runs each scheduler in a privileged DaemonSet.'], +]; + +function Requirements() { + return ( +
+
+
+

Preflight

+ + What a host actually needs + +

+ Every check below has an ID, because{' '} + schedctl doctor reports them by ID and exits non-zero + on any blocking failure. +

+
+
+ {REQUIREMENTS.map(([id, what, why]) => ( +
+
{id}
+
+ {what} + {why} +
+
+ ))} +
+
+
+ ); +} + +/* ------------------------------------------------------------------ * + * Section: closing CTA + * ------------------------------------------------------------------ */ + +function ClosingCta() { + return ( +
+
+ + Read the introduction + +

+ A few minutes on what sched_ext is, what schedkit adds on top, and + what the project deliberately does not do yet. +

+
+ + Get started + + + Browse the source + +
+
+
+ ); +} + +/* ------------------------------------------------------------------ * + * Page + * ------------------------------------------------------------------ */ + export default function Home(): ReactNode { const {siteConfig} = useDocusaurusContext(); return ( + description="OCI-packaged sched_ext schedulers, plus the tools to run them anywhere" + >
- + + + + +
); From 4b8f8ad0e63cfd99de6038f0e7703fc851586ed4 Mon Sep 17 00:00:00 2001 From: Alessio Biancalana Date: Mon, 5 Oct 2026 17:52:59 +0200 Subject: [PATCH 2/5] refactor(site): strip the decorative layer for a monochrome design --- src/css/custom.css | 1000 +++++++++++++++++------------------- src/pages/index.module.css | 613 +++++++--------------- src/pages/index.tsx | 423 ++++++--------- 3 files changed, 826 insertions(+), 1210 deletions(-) diff --git a/src/css/custom.css b/src/css/custom.css index 3c2a0d4..cef2174 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -1,15 +1,17 @@ /** - * schedkit docs — design system. + * schedkit docs — stark monochrome. * - * Direction: systems / terminal. Dark-first, hairline borders instead of - * shadows, sharp radii, monospace for labels and code, generous line height - * for long-form technical prose. + * No decorative colour anywhere. Structure is carried by type scale and 1px + * hairlines; mono is used only for literal code, commands and check IDs. + * Dark and light are the same design inverted, not two designs. * - * Light mode is a separately tuned theme, not an inversion. + * Everything is achromatic by intent. If you find yourself adding a colour, + * the first question is whether it encodes meaning (a pass/fail) or is just + * decoration. Decoration loses. */ /* ------------------------------------------------------------------ * - * Typography — system stacks only, no webfont requests. + * Typography * ------------------------------------------------------------------ */ :root { @@ -17,131 +19,152 @@ ui-sans-serif, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif; --ifm-font-family-monospace: - ui-monospace, 'SFMono-Regular', 'SF Mono', 'JetBrains Mono', Menlo, - Consolas, 'Liberation Mono', monospace; + ui-monospace, 'SFMono-Regular', 'SF Mono', Menlo, Consolas, + 'Liberation Mono', monospace; --ifm-font-size-base: 16.5px; - --ifm-line-height-base: 1.75; + --ifm-line-height-base: 1.72; --ifm-code-font-size: 87.5%; - --ifm-heading-font-weight: 700; - --ifm-heading-line-height: 1.25; + --ifm-heading-line-height: 1.12; - /* Terminal labels, eyebrows, sidebar groups. */ - --sk-font-mono: var(--ifm-font-family-monospace); + --ifm-global-radius: 0; - --ifm-global-radius: 3px; - --ifm-toc-border-color: var(--sk-line); - --docusaurus-highlighted-code-line-bg: rgba(77, 163, 240, 0.14); - --ifm-h1-font-size: 2.15rem; - --ifm-h2-font-size: 1.55rem; + --docusaurus-highlighted-code-line-bg: rgba(128, 128, 128, 0.18); + --ifm-h1-font-size: 2.5rem; + --ifm-h2-font-size: 1.6rem; --ifm-h3-font-size: 1.2rem; } /* ------------------------------------------------------------------ * - * Dark palette (default; darkMode default is 'dark') + * Dark (default). True black, off-white text, achromatic hairlines. * ------------------------------------------------------------------ */ -:root { - --ifm-color-primary: #5aa9f2; - --ifm-color-primary-dark: #479bec; - --ifm-color-primary-darker: #3f93e9; - --ifm-color-primary-darkest: #2e77cd; - --ifm-color-primary-light: #6db7f3; - --ifm-color-primary-lighter: #7bbfef; - --ifm-color-primary-lightest: #a2d3f7; - - --ifm-background-color: #0a0d13; - --ifm-background-surface-color: #10151d; - - --ifm-font-color-base: #b8c4d4; - --ifm-heading-color: #eef3fa; - --ifm-font-color-dark: #b8c4d4; - --ifm-font-color-darker: #d6dfea; - --ifm-font-color-darkest: #eef3fa; - --ifm-font-color-light: #9aa7b8; - --ifm-font-color-lighter: #7d8a9b; - --ifm-font-color-lightest: #6b7787; - - --ifm-color-emphasis-0: var(--ifm-font-color-base); - --ifm-color-emphasis-100: var(--ifm-background-color); - --ifm-color-emphasis-200: var(--ifm-background-surface-color); - --ifm-color-emphasis-300: #1b2230; - --ifm-color-emphasis-400: #29323f; - --ifm-color-emphasis-500: #3c4757; - --ifm-color-emphasis-600: #7d8a9b; - --ifm-color-emphasis-700: #b8c4d4; - --ifm-color-emphasis-800: #d6dfea; - --ifm-color-emphasis-900: #eef3fa; - - --ifm-navbar-background-color: rgba(10, 13, 19, 0.82); +/* + * Infima ships its whole dark palette on `html[data-theme=dark]`, which is + * specificity (0,1,1) — it beats a bare `:root` or `[data-theme='light']` + * selector. That silently overrode the page background (landing on #1b1b1d + * slate instead of true black) plus ~30 other tokens. `:root[data-theme=...]` + * is (0,2,0) and wins, so both theme blocks are scoped this way. + */ +:root, +:root[data-theme='dark'] { + --sk-bg: #000000; + --sk-surface: #0e0e0e; + --sk-surface-2: #171717; + --sk-fg: #ededed; + --sk-fg-muted: #a8a8a8; + --sk-fg-subtle: #8a8a8a; + --sk-line: #2b2b2b; + --sk-line-strong: #4a4a4a; + + --ifm-background-color: var(--sk-bg); + --ifm-background-surface-color: var(--sk-surface); + --ifm-font-color-base: var(--sk-fg); + --ifm-heading-color: var(--sk-fg); + --ifm-font-color-dark: var(--sk-fg); + --ifm-font-color-darker: var(--sk-fg); + --ifm-font-color-darkest: #ffffff; + --ifm-font-color-light: var(--sk-fg-muted); + --ifm-font-color-lighter: var(--sk-fg-muted); + --ifm-font-color-lightest: var(--sk-fg-subtle); + --ifm-link-color: var(--sk-fg); + + /* Infima derives the font ramp from these; pin them so it stays grey. */ + --ifm-color-content: var(--sk-fg); + --ifm-color-content-secondary: var(--sk-fg-muted); + + --ifm-color-emphasis-0: var(--sk-fg); + --ifm-color-emphasis-100: var(--sk-bg); + --ifm-color-emphasis-200: var(--sk-surface); + --ifm-color-emphasis-300: var(--sk-surface-2); + --ifm-color-emphasis-400: var(--sk-line-strong); + --ifm-color-emphasis-500: var(--sk-line-strong); + --ifm-color-emphasis-600: var(--sk-fg-muted); + --ifm-color-emphasis-700: var(--sk-fg); + --ifm-color-emphasis-800: var(--sk-fg); + --ifm-color-emphasis-900: #ffffff; + --ifm-color-emphasis-1000: #ffffff; + + /* + * Every stop is the same achromatic foreground so nothing can smuggle hue + * back in. + */ + --ifm-color-primary: #ededed; + --ifm-color-primary-dark: #d8d8d8; + --ifm-color-primary-darker: #cccccc; + --ifm-color-primary-darkest: #b0b0b0; + --ifm-color-primary-light: #ffffff; + --ifm-color-primary-lighter: #ffffff; + --ifm-color-primary-lightest: #ffffff; + --ifm-color-primary-contrast-background: #ededed; + --ifm-color-primary-contrast-foreground: #000000; + + /* Infima tints these by default; this theme is untinted. */ + --ifm-table-stripe-background: transparent; + --ifm-code-background: var(--sk-surface-2); + --ifm-hover-overlay: rgba(255, 255, 255, 0.06); + --ifm-breadcrumb-item-background-active: transparent; + + --ifm-navbar-background-color: rgba(0, 0, 0, 0.88); --ifm-navbar-shadow: none; - --ifm-footer-background-color: #070a0f; - - /* Internal tokens. */ - --sk-bg-sunken: #070a0f; - --sk-surface-2: #161d27; - --sk-line: rgba(146, 168, 197, 0.14); - --sk-line-strong: rgba(146, 168, 197, 0.24); - --sk-grid: rgba(146, 168, 197, 0.055); - --sk-glow: rgba(77, 163, 240, 0.16); - --sk-term: #a9de74; - --sk-term-dim: #8fbf63; - --sk-code-bg: #0d1219; - --sk-inline-code-bg: #171f2a; - --sk-inline-code-fg: #a9d1f8; + --ifm-footer-background-color: #000000; } /* ------------------------------------------------------------------ * - * Light palette — independently tuned, warm-neutral, not inverted. + * Light. Same design, inverted. * ------------------------------------------------------------------ */ -[data-theme='light'] { - --ifm-color-primary: #1a63b0; - --ifm-color-primary-dark: #185ba3; - --ifm-color-primary-darker: #17589e; - --ifm-color-primary-darkest: #134984; - --ifm-color-primary-light: #1c6bbd; - --ifm-color-primary-lighter: #1d70c5; - --ifm-color-primary-lightest: #2179d3; - - --ifm-background-color: #fdfdfc; - --ifm-background-surface-color: #ffffff; - - --ifm-font-color-base: #333c48; - --ifm-heading-color: #10161e; - --ifm-font-color-light: #5a6675; - --ifm-font-color-lighter: #5f6a79; - --ifm-font-color-lightest: #6b7684; - --ifm-font-color-dark: #2a323d; - --ifm-font-color-darker: #1e252e; - --ifm-font-color-darkest: #10161e; - - --ifm-color-emphasis-200: #ffffff; - --ifm-color-emphasis-300: #f4f5f7; - --ifm-color-emphasis-400: #e6e8ec; - --ifm-color-emphasis-500: #d2d6dc; - --ifm-color-emphasis-600: #5f6a79; - --ifm-color-emphasis-700: #4a5563; - --ifm-color-emphasis-800: #2a323d; - --ifm-color-emphasis-900: #10161e; - - --ifm-navbar-background-color: rgba(253, 253, 252, 0.85); - --ifm-footer-background-color: #f4f5f7; - - --sk-bg-sunken: #f7f8f9; - --sk-surface-2: #f4f5f7; - --sk-line: rgba(24, 38, 58, 0.13); - --sk-line-strong: rgba(24, 38, 58, 0.22); - --sk-grid: rgba(24, 38, 58, 0.045); - --sk-glow: rgba(26, 99, 176, 0.09); - --sk-term: #35701f; - --sk-term-dim: #4a7c37; - --sk-code-bg: #f7f8fa; - --sk-inline-code-bg: #eef0f4; - --sk-inline-code-fg: #1a4a86; - - --docusaurus-highlighted-code-line-bg: rgba(26, 99, 176, 0.09); +:root[data-theme='light'] { + --sk-bg: #ffffff; + --sk-surface: #ffffff; + --sk-surface-2: #f4f4f4; + --sk-fg: #111111; + --sk-fg-muted: #5c5c5c; + --sk-fg-subtle: #6e6e6e; + --sk-line: #e2e2e2; + --sk-line-strong: #c2c2c2; + + --ifm-background-color: var(--sk-bg); + --ifm-background-surface-color: var(--sk-surface); + --ifm-font-color-base: var(--sk-fg); + --ifm-heading-color: #000000; + --ifm-font-color-light: var(--sk-fg-muted); + --ifm-font-color-lighter: var(--sk-fg-muted); + --ifm-font-color-lightest: var(--sk-fg-subtle); + --ifm-link-color: #000000; + --ifm-color-content: var(--sk-fg); + --ifm-color-content-secondary: var(--sk-fg-muted); + + --ifm-color-emphasis-0: var(--sk-fg); + --ifm-color-emphasis-100: var(--sk-bg); + --ifm-color-emphasis-200: var(--sk-surface-2); + --ifm-color-emphasis-300: var(--sk-surface-2); + --ifm-color-emphasis-400: var(--sk-line-strong); + --ifm-color-emphasis-500: var(--sk-line-strong); + --ifm-color-emphasis-600: var(--sk-fg-muted); + --ifm-color-emphasis-700: var(--sk-fg); + --ifm-color-emphasis-800: var(--sk-fg); + --ifm-color-emphasis-900: #000000; + --ifm-color-emphasis-1000: #000000; + + --ifm-color-primary: #111111; + --ifm-color-primary-dark: #000000; + --ifm-color-primary-darker: #000000; + --ifm-color-primary-darkest: #000000; + --ifm-color-primary-light: #3d3d3d; + --ifm-color-primary-lighter: #4a4a4a; + --ifm-color-primary-lightest: #6e6e6e; + --ifm-color-primary-contrast-background: #111111; + --ifm-color-primary-contrast-foreground: #ffffff; + + --ifm-table-stripe-background: transparent; + --ifm-code-background: var(--sk-surface-2); + --ifm-hover-overlay: rgba(0, 0, 0, 0.05); + --ifm-breadcrumb-item-background-active: transparent; + + --ifm-navbar-background-color: rgba(255, 255, 255, 0.9); + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.07); } /* ------------------------------------------------------------------ * @@ -156,30 +179,27 @@ html { body { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; - font-variant-ligatures: none; } +/* Inverted selection: the loudest thing on the page, for the right reason. */ ::selection { - background: rgba(77, 163, 240, 0.28); - color: var(--ifm-heading-color); + background: var(--sk-fg); + color: var(--sk-bg); } -/* A single, consistent, keyboard-visible focus treatment everywhere. */ :focus-visible { - outline: 2px solid var(--ifm-color-primary); - outline-offset: 2px; - border-radius: 2px; + outline: 2px solid var(--sk-fg); + outline-offset: 3px; } -/* Thin, self-effacing scrollbars. */ * { scrollbar-width: thin; scrollbar-color: var(--sk-line-strong) transparent; } *::-webkit-scrollbar { - width: 9px; - height: 9px; + width: 10px; + height: 10px; } *::-webkit-scrollbar-track { @@ -188,29 +208,24 @@ body { *::-webkit-scrollbar-thumb { background: var(--sk-line-strong); - border: 2px solid transparent; + border: 3px solid transparent; background-clip: content-box; - border-radius: 999px; } *::-webkit-scrollbar-thumb:hover { - background: var(--ifm-color-primary); + background: var(--sk-fg-subtle); background-clip: content-box; } -.skipToContent_fallback { - border-radius: 2px; -} - /* ------------------------------------------------------------------ * * Navbar * ------------------------------------------------------------------ */ .navbar { border-bottom: 1px solid var(--sk-line); - padding-inline: 0.5rem; - backdrop-filter: saturate(160%) blur(12px); - -webkit-backdrop-filter: saturate(160%) blur(12px); + padding-inline: 0.75rem; + backdrop-filter: saturate(120%) blur(10px); + -webkit-backdrop-filter: saturate(120%) blur(10px); } .navbar__inner { @@ -219,100 +234,72 @@ body { } .navbar__brand { - margin-right: 1.75rem; + margin-right: 2rem; } .navbar__logo { - height: 24px; + height: 22px; width: auto; + /* + * static/img/README.md records logo.svg as a committed placeholder: a blue + * rounded square. Desaturate it so the palette stays achromatic. Delete this + * filter when a real logo lands. + */ + filter: grayscale(1) contrast(1.1); } .navbar__title { - font-family: var(--sk-font-mono); - font-weight: 600; - font-size: 1.02rem; - letter-spacing: -0.02em; - padding-inline-start: 0.55rem; + font-weight: 700; + font-size: 1rem; + letter-spacing: -0.03em; + padding-inline-start: 0.6rem; } .navbar__logo + .navbar__title { - padding-inline-start: 0.55rem; + padding-inline-start: 0.6rem; } .navbar__link { font-size: 0.875rem; font-weight: 500; - letter-spacing: 0.01em; + color: var(--sk-fg-muted); transition: color 120ms ease; } -.navbar__link::after { - content: ''; - display: block; - height: 1px; - transform: scaleX(0); - transform-origin: left; - background: currentColor; - transition: transform 160ms ease; -} - -.navbar__link:hover::after, -.navbar__link--active::after { - transform: scaleX(1); -} - +.navbar__link:hover, .navbar__link--active { - color: var(--ifm-color-primary); + color: var(--sk-fg); } -.navbar .navbar__items--right { - margin-inline-start: auto; +.navbar__link--active { + font-weight: 700; } -/* GitHub link gets an icon treatment rather than bare text on wide screens. */ .navbar__link--github { - font-family: var(--sk-font-mono); - font-size: 0.8rem; - letter-spacing: 0.02em; -} - -.navbar__cta { - font-family: var(--sk-font-mono); + font-family: var(--ifm-font-family-monospace); font-size: 0.78rem; - letter-spacing: 0.04em; - text-transform: uppercase; - border: 1px solid var(--sk-line-strong); - border-radius: var(--ifm-global-radius); - padding: 0.3rem 0.7rem; - transition: border-color 120ms ease, color 120ms ease; -} - -.navbar__cta:hover { - border-color: var(--ifm-color-primary); - color: var(--ifm-color-primary); - text-decoration: none; + letter-spacing: 0.02em; } -.navbar__cta::after { - display: none; +.navbar__items--right { + margin-inline-start: auto; } -/* Theme toggle: square-ish, hairline. */ -.navbar__items--right .clean-btn { +.navbar .clean-btn { border: 1px solid var(--sk-line); - border-radius: var(--ifm-global-radius); - transition: border-color 120ms ease; + border-radius: 0; + transition: color 120ms ease, border-color 120ms ease; } -.navbar__items--right .clean-btn:hover { +.navbar .clean-btn:hover { border-color: var(--sk-line-strong); background: transparent; - color: var(--ifm-color-primary); + color: var(--sk-fg); } .navbar__toggle, .navbar__login { - border-radius: var(--ifm-global-radius); + border-radius: 0; } /* ------------------------------------------------------------------ * @@ -321,11 +308,11 @@ body { .sidebar { border-right: 1px solid var(--sk-line); - padding-block: 1.5rem 3rem; + padding-block: 1.75rem 3rem; } .sidebar__group { - padding-inline-start: 0.55rem; + padding-inline-start: 0.6rem; } .menu__list-item-collapsible { @@ -333,58 +320,51 @@ body { } .menu__list-item-collapsible > .menu__list-item-collapsible-toggle { - font-family: var(--sk-font-mono); - font-size: 0.7rem; + font-family: var(--ifm-font-family-monospace); + font-size: 0.68rem; font-weight: 600; text-transform: uppercase; - letter-spacing: 0.1em; - color: var(--ifm-color-emphasis-600); - padding-block: 0.85rem 0.5rem; + letter-spacing: 0.12em; + color: var(--sk-fg-subtle); + padding-block: 0.9rem 0.45rem; } .menu__list-item-collapsible > .menu__list-item-collapsible-toggle:hover { background: transparent; - color: var(--ifm-heading-color); + color: var(--sk-fg); } .menu__list-item-collapsible-toggle::before { - background: var(--sk-line-strong); + background: var(--sk-line); height: 1px; opacity: 1; } -.menu__list-item-collapsible-toggle:hover::before { - background: var(--sk-line-strong); - opacity: 1; -} - .menu__link { - font-size: 0.895rem; + font-size: 0.9rem; line-height: 1.45; - border-radius: var(--ifm-global-radius); - padding-block: 0.36rem; + border-radius: 0; + padding-block: 0.34rem; + padding-inline: 0.5rem; + color: var(--sk-fg-muted); transition: color 120ms ease, background-color 120ms ease; } .menu__link:hover { background: var(--sk-surface-2); - color: var(--ifm-heading-color); + color: var(--sk-fg); text-decoration: none; } +/* Active item: inverted chip. No hue, no left bar, no tint. */ .menu__link--active:not(.menu__link--sublist) { - background: var(--sk-surface-2); - color: var(--ifm-color-primary); + background: var(--sk-fg); + color: var(--sk-bg); font-weight: 600; } .menu__link--active:not(.menu__link--sublist)::before { - background: var(--ifm-color-primary); - width: 2px; - height: 1.05em; - opacity: 1; - left: -0.55rem; - border-radius: 2px; + display: none; } .menu__list-item > .menu__list-item-collapsible:hover { @@ -392,11 +372,11 @@ body { } /* ------------------------------------------------------------------ * - * Document content + * Doc content * ------------------------------------------------------------------ */ .docItemContainer { - padding-block: 2.5rem 4rem; + padding-block: 2.75rem 4rem; } .theme-doc-markdown { @@ -409,161 +389,150 @@ body { margin-bottom: 1.15rem; } -/* - * Docusaurus renders the page title as

…

, so the h1 - * is not a direct child of .theme-doc-markdown. Both forms are covered. - */ +/* Docusaurus wraps the title in

, so cover both shapes. */ .theme-doc-markdown header > h1, .theme-doc-markdown > h1 { - font-family: var(--sk-font-mono); - font-weight: 600; - font-size: 2rem; - letter-spacing: -0.035em; - margin-bottom: 1.5rem; -} - -.theme-doc-markdown header > h1::after, -.theme-doc-markdown > h1::after { - content: ''; - display: block; - width: 2.5rem; - height: 2px; - margin-top: 0.9rem; - background: var(--ifm-color-primary); + font-size: 2.4rem; + font-weight: 700; + letter-spacing: -0.04em; + line-height: 1.08; + margin-bottom: 1.75rem; } .theme-doc-markdown > h2 { - font-size: 1.42rem; - letter-spacing: -0.022em; - margin-top: 2.9rem; - padding-top: 0.4rem; + font-size: 1.55rem; + letter-spacing: -0.028em; + margin-top: 3rem; + padding-bottom: 0.5rem; + border-bottom: 1px solid var(--sk-line); } .theme-doc-markdown > h3 { - font-size: 1.13rem; - letter-spacing: -0.012em; + font-size: 1.15rem; + letter-spacing: -0.015em; margin-top: 2.1rem; } .theme-doc-markdown > h4, .theme-doc-markdown > h5, .theme-doc-markdown > h6 { - font-family: var(--sk-font-mono); - font-size: 0.94rem; + font-family: var(--ifm-font-family-monospace); + font-size: 0.78rem; + font-weight: 600; text-transform: uppercase; - letter-spacing: 0.06em; - color: var(--ifm-color-emphasis-700); - margin-top: 1.9rem; + letter-spacing: 0.1em; + color: var(--sk-fg-subtle); + margin-top: 2rem; } -/* Prose measure: long lines are the fastest way to make docs unreadable. */ @media screen and (min-width: 997px) { .theme-doc-markdown { - max-width: 46rem; + max-width: 45rem; } } +/* Links are underlined, not coloured. */ .theme-doc-markdown a { text-decoration: underline; - text-decoration-color: var(--sk-line-strong); - text-underline-offset: 0.18em; text-decoration-thickness: 1px; - transition: color 120ms ease, text-decoration-color 120ms ease; + text-underline-offset: 0.2em; + text-decoration-color: var(--sk-line-strong); + transition: text-decoration-color 120ms ease, color 120ms ease; } .theme-doc-markdown a:hover { - text-decoration-color: var(--ifm-color-primary); + color: var(--sk-fg); + text-decoration-color: var(--sk-fg); } .theme-doc-markdown strong { - font-weight: 650; - color: var(--ifm-font-color-darkest); + font-weight: 700; } .theme-doc-markdown blockquote { - border-inline-start: 2px solid var(--sk-line-strong); + border-inline-start: 1px solid var(--sk-line-strong); padding-inline-start: 1.1rem; font-style: normal; - color: var(--ifm-color-emphasis-600); + color: var(--sk-fg-muted); } .theme-doc-markdown ul, .theme-doc-markdown ol { - padding-inline-start: 1.4rem; + padding-inline-start: 1.35rem; } .theme-doc-markdown li { - margin-bottom: 0.4rem; + margin-bottom: 0.35rem; } .theme-doc-markdown li::marker { - color: var(--sk-line-strong); + color: var(--sk-fg-subtle); } .theme-doc-markdown hr { border: 0; border-top: 1px solid var(--sk-line); - margin-block: 2.75rem; + margin-block: 3rem; } .theme-doc-markdown img { border: 1px solid var(--sk-line); - border-radius: var(--ifm-global-radius); } -/* Source-file breadcrumb above the page title. */ +/* Breadcrumbs: plain path, mono, no chips. */ .theme-doc-breadcrumbs { - font-family: var(--sk-font-mono); - font-size: 0.76rem; - letter-spacing: 0.03em; - margin-bottom: 0.9rem; -} - -.theme-doc-breadcrumbs__link { - background: var(--sk-surface-2); - border-radius: var(--ifm-global-radius); - padding: 0.15rem 0.45rem; - color: var(--ifm-color-emphasis-600); + font-family: var(--ifm-font-family-monospace); + font-size: 0.72rem; + letter-spacing: 0.02em; + margin-bottom: 1.25rem; } -.theme-doc-breadcrumbs__link:hover { - background: var(--sk-surface-2); - color: var(--ifm-color-primary); +/* + * Docusaurus puts only `theme-doc-breadcrumbs` on the