From 90b7224eb9cec5565fd87c82fccff1c89b3101c1 Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Wed, 27 May 2026 23:17:44 +0300 Subject: [PATCH 01/24] =?UTF-8?q?feat:=20update=20branding=20=E2=80=94=20d?= =?UTF-8?q?ark/light=20logos=20and=20Indigo=20primary=20colors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add separate logo for dark and light themes (logo-dark.svg, logo-light.svg) - Hide site title text next to logo (replacesTitle: true) - Set logo max-height to 28px - Replace primary accent colors with Tailwind Indigo palette: light theme → indigo-500 (#6366f1) dark theme → indigo-400 (#818cf8) Co-Authored-By: Claude Sonnet 4.6 --- astro.config.mjs | 4 +++- src/assets/logo-dark.svg | 15 +++++++++++++++ src/assets/logo-light.svg | 15 +++++++++++++++ src/styles/custom.css | 24 ++++++++++++++++++++++-- 4 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 src/assets/logo-dark.svg create mode 100644 src/assets/logo-light.svg diff --git a/astro.config.mjs b/astro.config.mjs index e147abf1..5abba751 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -28,7 +28,9 @@ export default defineConfig({ pagefind: false, logo: { - src: './src/assets/logo.svg', + light: './src/assets/logo-light.svg', + dark: './src/assets/logo-dark.svg', + replacesTitle: true, }, customCss: [ './src/styles/custom.css', diff --git a/src/assets/logo-dark.svg b/src/assets/logo-dark.svg new file mode 100644 index 00000000..3801243c --- /dev/null +++ b/src/assets/logo-dark.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/src/assets/logo-light.svg b/src/assets/logo-light.svg new file mode 100644 index 00000000..eb61b01e --- /dev/null +++ b/src/assets/logo-light.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/src/styles/custom.css b/src/styles/custom.css index 31988be7..7410ad19 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -1,10 +1,30 @@ +.site-title img { + max-height: 28px; + width: auto; +} + .docsearch-modal-footer-logo { display: none!important; } +/* Light theme — primary darker for contrast on white */ +:root[data-theme='light'] { + --sl-color-accent-low: #e0e7ff; /* indigo-100 — subtle bg highlights */ + --sl-color-accent: #6366f1; /* indigo-500 — links, badges */ + --sl-color-accent-high: #4338ca; /* indigo-700 — hover states */ + --sl-color-text-accent: #6366f1; /* indigo-500 — button bg */ + --sl-color-bg-accent: #6366f1; /* indigo-500 */ +} + +/* Dark theme — primary lighter for contrast on dark */ :root { - --sl-color-text-accent: rgb(92, 137, 252) !important; - --docsearch-primary-color: rgb(92, 137, 252) !important; + --sl-color-accent-low: #312e81; /* indigo-900 — subtle bg highlights */ + --sl-color-accent: #818cf8; /* indigo-400 — links, badges */ + --sl-color-accent-high: #c7d2fe; /* indigo-200 — high contrast text */ + --sl-color-text-accent: #818cf8; /* indigo-400 — button bg */ + --sl-color-bg-accent: #818cf8; /* indigo-400 */ + + --docsearch-primary-color: #6366f1; --docsearch-text-color: rgb(28, 30, 33); --docsearch-spacing: 12px; --docsearch-icon-stroke-width: 1.4; From 0394a0363642b7f15709657b76110fe415f97197 Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Thu, 28 May 2026 11:55:25 +0300 Subject: [PATCH 02/24] =?UTF-8?q?feat:=20refine=20UI=20branding=20?= =?UTF-8?q?=E2=80=94=20search=20button,=20menu=20button,=20and=20nav=20sty?= =?UTF-8?q?les?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- astro.config.mjs | 3 +- src/styles/custom.css | 230 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 229 insertions(+), 4 deletions(-) diff --git a/astro.config.mjs b/astro.config.mjs index 5abba751..b7c638b8 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -24,13 +24,12 @@ export default defineConfig({ errorOnInvalidHashes: false, }), ], - title: 'Testomatio', + title: 'Docs', pagefind: false, logo: { light: './src/assets/logo-light.svg', dark: './src/assets/logo-dark.svg', - replacesTitle: true, }, customCss: [ './src/styles/custom.css', diff --git a/src/styles/custom.css b/src/styles/custom.css index 7410ad19..21fe76cb 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -3,12 +3,67 @@ width: auto; } +.site-title span { + font-weight: 700; + font-size: var(--sl-text-xl); /* 20px */ + margin-inline-start: -6px; /* ближе к лого */ +} + +/* Button overrides */ +.sl-link-button.primary { + border-radius: 12px !important; + font-weight: 700 !important; + transition: background-color 0.2s ease, border-color 0.2s ease !important; +} + +:root[data-theme='light'] .sl-link-button.primary { + border-color: #4f46e5 !important; /* indigo-600 */ +} + +:root[data-theme='light'] .sl-link-button.primary:hover { + background-color: #4f46e5 !important; /* indigo-600 */ + border-color: #4338ca !important; /* indigo-700 */ +} + +:root .sl-link-button.primary { + border-color: #a5b4fc !important; /* indigo-300 */ +} + +:root .sl-link-button.primary:hover { + background-color: #6366f1 !important; /* indigo-500 */ + border-color: #818cf8 !important; /* indigo-400 */ +} + +/* Sidebar nav item hover — skip active */ +:root[data-theme='light'] nav.sidebar a:not([aria-current='page']):hover { + background-color: rgba(0, 0, 0, 0.06) !important; + border-radius: 6px !important; +} + +:root:not([data-theme='light']) nav.sidebar a:not([aria-current='page']):hover { + background-color: rgba(255, 255, 255, 0.08) !important; + border-radius: 6px !important; +} + .docsearch-modal-footer-logo { display: none!important; } +/* Global focus outline — indigo */ +:focus-visible { + outline-color: #6366f1 !important; +} + /* Light theme — primary darker for contrast on white */ :root[data-theme='light'] { + --docsearch-primary-color: #6366f1; + --docsearch-searchbox-shadow: inset 0 0 0 2px var(--docsearch-primary-color); + --docsearch-searchbox-focus-background: #fff; + --docsearch-text-color: #1c1e21; + --docsearch-muted-color: #969faf; + --docsearch-searchbox-background: transparent; + --docsearch-key-gradient: linear-gradient(-225deg, #d5dbe4 0%, #f8f8f8 100%); + --docsearch-key-shadow: inset 0 -2px 0 0 #cdcde6, inset 0 0 1px 1px #fff, 0 1px 2px 1px rgba(30, 35, 90, 0.4); --sl-color-accent-low: #e0e7ff; /* indigo-100 — subtle bg highlights */ --sl-color-accent: #6366f1; /* indigo-500 — links, badges */ --sl-color-accent-high: #4338ca; /* indigo-700 — hover states */ @@ -16,6 +71,108 @@ --sl-color-bg-accent: #6366f1; /* indigo-500 */ } +/* Search button */ +.docsearch-btn { + height: 36px !important; + padding: 0 10px 0 10px !important; + border-radius: 8px !important; + gap: 6px !important; + min-width: 180px !important; + max-width: 180px !important; + transition: box-shadow 0.15s ease, background-color 0.15s ease !important; +} + +/* Default border */ +:root[data-theme='light'] .docsearch-btn { + box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.22) !important; +} + +:root:not([data-theme='light']) .docsearch-btn { + background: transparent !important; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.2) !important; + color: var(--sl-color-white) !important; +} + +/* Hover — light theme */ +:root[data-theme='light'] #docsearch .docsearch-btn:hover, +:root[data-theme='light'] .docsearch-btn:hover { + box-shadow: inset 0 0 0 1.5px var(--sl-color-gray-4) !important; + background: transparent !important; + color: var(--docsearch-muted-color) !important; +} + +/* Hover — dark theme */ +:root:not([data-theme='light']) #docsearch .docsearch-btn:hover, +:root:not([data-theme='light']) .docsearch-btn:hover { + box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, 0.5) !important; + background: transparent !important; + color: var(--sl-color-white) !important; +} + +/* Focus */ +.docsearch-btn:focus, +.docsearch-btn:focus-visible { + outline: none !important; + box-shadow: inset 0 0 0 2px var(--sl-color-accent), 0 0 0 3px var(--sl-color-accent) !important; + background: var(--docsearch-searchbox-focus-background) !important; + color: var(--docsearch-text-color) !important; +} + + +/* Search icon — override hardcoded SVG attributes */ +.docsearch-btn-icon-container svg { + width: 20px !important; + height: 20px !important; +} + +/* Placeholder text — no truncation, no ellipsis */ +.docsearch-btn-placeholder { + overflow: visible !important; + text-overflow: unset !important; + white-space: nowrap !important; + font-size: var(--sl-text-sm) !important; + padding: 0 !important; +} + +/* kbd key badges */ +.docsearch-btn-keys { + gap: 0px !important; + margin-left: auto !important; + padding-left: 8px !important; +} + +.docsearch-btn-keys > * { + margin-right: 4px !important; +} + +.docsearch-btn-key, +.DocSearch-Commands-Key, +kbd[class*="docsearch"] { + background: transparent !important; + background-image: none !important; + box-shadow: none !important; + border: 1px solid currentColor !important; + border-radius: 6px !important; + min-width: 20px !important; + height: 20px !important; + padding: 0 4px !important; + font-size: 11px !important; + font-family: var(--__sl-font) !important; + display: flex !important; + align-items: center !important; + justify-content: center !important; + opacity: 1 !important; +} + +.docsearch-btn-key { + color: var(--sl-color-gray-4) !important; + border-color: var(--sl-color-gray-5) !important; +} + +:root:not([data-theme='light']) .docsearch-btn-key { + color: var(--sl-color-gray-3) !important; +} + /* Dark theme — primary lighter for contrast on dark */ :root { --sl-color-accent-low: #312e81; /* indigo-900 — subtle bg highlights */ @@ -36,8 +193,8 @@ --docsearch-modal-background: rgb(245, 246, 247); --docsearch-modal-shadow: inset 1px 1px 0 0 rgba(255, 255, 255, 0.5), 0 3px 8px 0 rgba(85, 90, 100, 1); --docsearch-searchbox-height: 56px; - --docsearch-searchbox-background: rgb(235, 237, 240); - --docsearch-searchbox-focus-background: #fff; + --docsearch-searchbox-background: transparent; + --docsearch-searchbox-focus-background: transparent; --docsearch-searchbox-shadow: inset 0 0 0 2px var(--docsearch-primary-color); --docsearch-hit-height: 56px; --docsearch-hit-color: rgb(68, 73, 80); @@ -60,7 +217,42 @@ html[data-theme=dark] .docsearch-btn-placeholder { color: #edeef3; } +/* Override docsearch primary color globally via container — wins over :root from library */ +#docsearch, +.docsearch-modal-container { + --docsearch-primary-color: var(--sl-color-accent); + --docsearch-highlight-color: var(--sl-color-accent); +} + +/* Search modal — icon */ +.docsearch-modal-search-input-icon { + color: var(--sl-color-gray-3) !important; +} + +/* Search modal — input */ +.docsearch-modal-search-input-form { + background: rgba(255, 255, 255, 0.1) !important; + box-shadow: inset 0 0 0 1.5px rgba(150, 159, 175, 0.5) !important; +} + +.docsearch-modal-search-input-form:focus-within { + box-shadow: inset 0 0 0 2px var(--sl-color-accent) !important; +} + @media screen and (max-width: 767px) { + .docsearch-btn { + min-width: unset !important; + width: 32px !important; + height: 32px !important; + padding: 0 !important; + justify-content: center !important; + } + + .docsearch-btn-placeholder, + .docsearch-btn-keys { + display: none !important; + } + .social-icons { flex-wrap: wrap; } @@ -70,6 +262,39 @@ html[data-theme=dark] .docsearch-btn-placeholder { } } +/* Menu button — shared styles for mobile and tablet */ +@media screen and (max-width: 799px) { + starlight-menu-button button { + background-color: transparent !important; + box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.22) !important; + border-radius: 8px !important; + width: 32px !important; + height: 32px !important; + min-width: unset !important; + padding: 0 !important; + display: flex !important; + align-items: center !important; + justify-content: center !important; + top: calc((var(--sl-nav-height) - 32px) / 2) !important; + color: var(--sl-color-gray-2) !important; + } +} + +/* Menu button dark theme — shared across mobile and tablet */ +:root:not([data-theme='light']) starlight-menu-button button { + background-color: transparent !important; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.2) !important; + color: var(--sl-color-white) !important; +} + +@media screen and (min-width: 768px) and (max-width: 799px) { + starlight-menu-button button { + width: 36px !important; + height: 36px !important; + top: calc((var(--sl-nav-height) - 36px) / 2) !important; + } +} + @media screen and (min-width: 768px) { .hero img { width: 100%; @@ -81,6 +306,7 @@ html[data-theme=dark] .docsearch-btn-placeholder { } } + @media screen and (min-width: 1024px) { .hero { position: relative; From c32441693987b1e74c700fd60e4e7b79c11cd89d Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Thu, 28 May 2026 12:09:48 +0300 Subject: [PATCH 03/24] feat: add Inter as primary font via Google Fonts --- src/styles/custom.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/styles/custom.css b/src/styles/custom.css index 21fe76cb..0e8aa640 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -1,3 +1,9 @@ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'); + +:root { + --sl-font: 'Inter', sans-serif; +} + .site-title img { max-height: 28px; width: auto; From 2ab9c1be81c59136ad6cd449d97a600450d5b895 Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Thu, 28 May 2026 12:09:59 +0300 Subject: [PATCH 04/24] feat: add rounded corners and border to article images --- src/styles/custom.css | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/styles/custom.css b/src/styles/custom.css index 0e8aa640..e18a9bb8 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -4,6 +4,16 @@ --sl-font: 'Inter', sans-serif; } +/* Article content images */ +.sl-markdown-content img { + border-radius: 12px; + border: 1px solid var(--sl-color-gray-6); +} + +:root[data-theme='dark'] .sl-markdown-content img { + border: none; +} + .site-title img { max-height: 28px; width: auto; From 5ec81c1aa38c692274635f2d0c3369a2272765c1 Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Thu, 28 May 2026 12:31:53 +0300 Subject: [PATCH 05/24] refactor: extract indigo brand palette into CSS variables --- src/styles/custom.css | 50 ++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/src/styles/custom.css b/src/styles/custom.css index e18a9bb8..77f21301 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -2,6 +2,16 @@ :root { --sl-font: 'Inter', sans-serif; + + /* Brand palette — indigo */ + --brand-100: #e0e7ff; + --brand-200: #c7d2fe; + --brand-300: #a5b4fc; + --brand-400: #818cf8; + --brand-500: #6366f1; + --brand-600: #4f46e5; + --brand-700: #4338ca; + --brand-900: #312e81; } /* Article content images */ @@ -33,21 +43,21 @@ } :root[data-theme='light'] .sl-link-button.primary { - border-color: #4f46e5 !important; /* indigo-600 */ + border-color: var(--brand-600) !important; } :root[data-theme='light'] .sl-link-button.primary:hover { - background-color: #4f46e5 !important; /* indigo-600 */ - border-color: #4338ca !important; /* indigo-700 */ + background-color: var(--brand-600) !important; + border-color: var(--brand-700) !important; } :root .sl-link-button.primary { - border-color: #a5b4fc !important; /* indigo-300 */ + border-color: var(--brand-300) !important; } :root .sl-link-button.primary:hover { - background-color: #6366f1 !important; /* indigo-500 */ - border-color: #818cf8 !important; /* indigo-400 */ + background-color: var(--brand-500) !important; + border-color: var(--brand-400) !important; } /* Sidebar nav item hover — skip active */ @@ -67,12 +77,12 @@ /* Global focus outline — indigo */ :focus-visible { - outline-color: #6366f1 !important; + outline-color: var(--brand-500) !important; } /* Light theme — primary darker for contrast on white */ :root[data-theme='light'] { - --docsearch-primary-color: #6366f1; + --docsearch-primary-color: var(--brand-500); --docsearch-searchbox-shadow: inset 0 0 0 2px var(--docsearch-primary-color); --docsearch-searchbox-focus-background: #fff; --docsearch-text-color: #1c1e21; @@ -80,11 +90,11 @@ --docsearch-searchbox-background: transparent; --docsearch-key-gradient: linear-gradient(-225deg, #d5dbe4 0%, #f8f8f8 100%); --docsearch-key-shadow: inset 0 -2px 0 0 #cdcde6, inset 0 0 1px 1px #fff, 0 1px 2px 1px rgba(30, 35, 90, 0.4); - --sl-color-accent-low: #e0e7ff; /* indigo-100 — subtle bg highlights */ - --sl-color-accent: #6366f1; /* indigo-500 — links, badges */ - --sl-color-accent-high: #4338ca; /* indigo-700 — hover states */ - --sl-color-text-accent: #6366f1; /* indigo-500 — button bg */ - --sl-color-bg-accent: #6366f1; /* indigo-500 */ + --sl-color-accent-low: var(--brand-100); + --sl-color-accent: var(--brand-500); + --sl-color-accent-high: var(--brand-700); + --sl-color-text-accent: var(--brand-500); + --sl-color-bg-accent: var(--brand-500); } /* Search button */ @@ -191,13 +201,13 @@ kbd[class*="docsearch"] { /* Dark theme — primary lighter for contrast on dark */ :root { - --sl-color-accent-low: #312e81; /* indigo-900 — subtle bg highlights */ - --sl-color-accent: #818cf8; /* indigo-400 — links, badges */ - --sl-color-accent-high: #c7d2fe; /* indigo-200 — high contrast text */ - --sl-color-text-accent: #818cf8; /* indigo-400 — button bg */ - --sl-color-bg-accent: #818cf8; /* indigo-400 */ + --sl-color-accent-low: var(--brand-900); + --sl-color-accent: var(--brand-400); + --sl-color-accent-high: var(--brand-200); + --sl-color-text-accent: var(--brand-400); + --sl-color-bg-accent: var(--brand-400); - --docsearch-primary-color: #6366f1; + --docsearch-primary-color: var(--brand-500); --docsearch-text-color: rgb(28, 30, 33); --docsearch-spacing: 12px; --docsearch-icon-stroke-width: 1.4; @@ -230,7 +240,7 @@ kbd[class*="docsearch"] { html[data-theme=dark] .docsearch-modal-btn-icon, html[data-theme=dark] .docsearch-btn-placeholder { - color: #edeef3; + color: var(--sl-color-gray-1); } /* Override docsearch primary color globally via container — wins over :root from library */ From bbb98e9e9c9595ec7347ca9075fac0f84bf7b50f Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Thu, 28 May 2026 12:40:26 +0300 Subject: [PATCH 06/24] feat: fix site title alignment and fixed gap between logo and Docs label --- src/styles/custom.css | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/styles/custom.css b/src/styles/custom.css index 77f21301..247a987d 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -24,6 +24,11 @@ border: none; } +.site-title { + align-items: center; + gap: 1.2rem; +} + .site-title img { max-height: 28px; width: auto; @@ -32,7 +37,9 @@ .site-title span { font-weight: 700; font-size: var(--sl-text-xl); /* 20px */ - margin-inline-start: -6px; /* ближе к лого */ + margin-inline-start: -10px; /* ближе к лого */ + position: relative; + top: 1px; } /* Button overrides */ From 8aabe8d136bdd5f59e22872bd193ffb85cf0994c Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Thu, 28 May 2026 12:55:11 +0300 Subject: [PATCH 07/24] feat: reduce article font sizes and hero tagline Set base article text to 14px, scale headings down ~15% from Starlight defaults, and reduce hero tagline to 16px across all breakpoints. Co-Authored-By: Claude Sonnet 4.6 --- src/styles/custom.css | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/styles/custom.css b/src/styles/custom.css index 247a987d..16e0a801 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -14,6 +14,19 @@ --brand-900: #312e81; } +/* Base article font size — slightly reduced from 1rem default */ +.sl-markdown-content { font-size: 0.875rem; } + +.hero .tagline { font-size: 16px; } + +/* Article headings — scaled down ×0.85 from Starlight defaults */ +.sl-markdown-content h1, .content-panel h1 { font-size: 2rem !important; } +.sl-markdown-content h2 { font-size: 1.75rem !important; } +.sl-markdown-content h3 { font-size: 1.275rem !important; } +.sl-markdown-content h4 { font-size: 1.0625rem !important; } +.sl-markdown-content h5 { font-size: 0.95rem !important; } +.sl-markdown-content h6 { font-size: 0.85rem !important; } + /* Article content images */ .sl-markdown-content img { border-radius: 12px; @@ -358,7 +371,7 @@ html[data-theme=dark] .docsearch-btn-placeholder { } .hero .tagline { - font-size: 18px; + font-size: 16px; } } From 7862dc03b42150be0fc8e8354280b3b9cf62f392 Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Thu, 28 May 2026 12:57:30 +0300 Subject: [PATCH 08/24] feat: add hover background to sidebar accordion group labels Matches the same hover fill used on nav items for both light and dark themes. Co-Authored-By: Claude Sonnet 4.6 --- src/styles/custom.css | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/styles/custom.css b/src/styles/custom.css index 16e0a801..b5ea5ad1 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -91,6 +91,17 @@ border-radius: 6px !important; } +/* Sidebar accordion group label hover */ +:root[data-theme='light'] nav.sidebar details > summary:hover { + background-color: rgba(0, 0, 0, 0.06) !important; + border-radius: 6px !important; +} + +:root:not([data-theme='light']) nav.sidebar details > summary:hover { + background-color: rgba(255, 255, 255, 0.08) !important; + border-radius: 6px !important; +} + .docsearch-modal-footer-logo { display: none!important; } From 558f61e1ad7857bedb78c611fb81de2d10cf5876 Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Thu, 28 May 2026 13:27:26 +0300 Subject: [PATCH 09/24] =?UTF-8?q?feat:=20style=20code=20blocks=20=E2=80=94?= =?UTF-8?q?=20rounded=20corners,=20scrollbar,=20copy=20button?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add 12px border-radius to code blocks with custom thin scrollbar. Copy button hidden by default, appears on frame hover, shows subtle fill on button hover — adapted for light and dark themes. Co-Authored-By: Claude Sonnet 4.6 --- src/styles/custom.css | 50 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/styles/custom.css b/src/styles/custom.css index b5ea5ad1..09009b0a 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -27,6 +27,56 @@ .sl-markdown-content h5 { font-size: 0.95rem !important; } .sl-markdown-content h6 { font-size: 0.85rem !important; } +/* Code blocks */ +.sl-markdown-content pre { + border-radius: 12px; + overflow: auto; +} + +.sl-markdown-content pre::-webkit-scrollbar { + height: 6px; +} + +.sl-markdown-content pre::-webkit-scrollbar-track { + background: transparent; + border-radius: 0 0 12px 12px; +} + +.sl-markdown-content pre::-webkit-scrollbar-thumb { + background: rgba(128, 128, 128, 0.3) !important; + border-radius: 12px; +} + +.sl-markdown-content pre::-webkit-scrollbar-thumb:hover { + background: rgba(128, 128, 128, 0.55) !important; +} + +/* Code block copy button */ +.expressive-code .copy button { + border-radius: 8px !important; + opacity: 0 !important; + transition: opacity 0.15s ease !important; +} + +.expressive-code:hover .copy, +.expressive-code:hover .copy button, +.expressive-code:hover .copy button:hover, +.expressive-code:hover .copy button:focus { + opacity: 1 !important; +} + +.expressive-code .copy button div { + background: transparent !important; +} + +:root[data-theme='light'] .expressive-code:hover .copy button:hover div { + background: var(--sl-color-gray-5) !important; +} + +:root:not([data-theme='light']) .expressive-code:hover .copy button:hover div { + background: rgba(255, 255, 255, 0.18) !important; +} + /* Article content images */ .sl-markdown-content img { border-radius: 12px; From e3892fa04e585ec5815b8867d357269198d337a5 Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Thu, 28 May 2026 13:40:56 +0300 Subject: [PATCH 10/24] feat: refine code block and copy button styles Rounded corners 8px on blocks, 6px on copy button. Hide decorative header, add subtle outline border, reposition copy button to top-right with border on hover. Inline code border-radius 6px. Co-Authored-By: Claude Sonnet 4.6 --- src/styles/custom.css | 46 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/src/styles/custom.css b/src/styles/custom.css index 09009b0a..a292ec64 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -27,12 +27,32 @@ .sl-markdown-content h5 { font-size: 0.95rem !important; } .sl-markdown-content h6 { font-size: 0.85rem !important; } +/* Hide code block decorative header */ +.expressive-code .header { + display: none !important; +} + /* Code blocks */ .sl-markdown-content pre { - border-radius: 12px; + border-radius: 8px; overflow: auto; } +.expressive-code { + --ec-brdWd: 0px; +} + +:root[data-theme='light'] .expressive-code .frame { + outline: 1px solid var(--sl-color-gray-6); + border-radius: 8px; +} + +:root:not([data-theme='light']) .expressive-code .frame { + outline: 1px solid var(--sl-color-gray-5); + border-radius: 8px; +} + + .sl-markdown-content pre::-webkit-scrollbar { height: 6px; } @@ -52,10 +72,19 @@ } /* Code block copy button */ +.expressive-code .copy { + position: absolute !important; + top: 8px !important; + right: 8px !important; + bottom: unset !important; +} + .expressive-code .copy button { - border-radius: 8px !important; + border-radius: 6px !important; opacity: 0 !important; transition: opacity 0.15s ease !important; + width: 28px !important; + height: 28px !important; } .expressive-code:hover .copy, @@ -69,14 +98,27 @@ background: transparent !important; } +:root[data-theme='light'] .expressive-code:hover .copy button { + box-shadow: inset 0 0 0 1px var(--sl-color-gray-5) !important; +} + :root[data-theme='light'] .expressive-code:hover .copy button:hover div { background: var(--sl-color-gray-5) !important; } +:root:not([data-theme='light']) .expressive-code:hover .copy button { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.2) !important; +} + :root:not([data-theme='light']) .expressive-code:hover .copy button:hover div { background: rgba(255, 255, 255, 0.18) !important; } +/* Inline code */ +.sl-markdown-content :not(pre) > code { + border-radius: 6px; +} + /* Article content images */ .sl-markdown-content img { border-radius: 12px; From 45a841f29a5fbc53c8600f096f006450c515171b Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Thu, 28 May 2026 13:41:54 +0300 Subject: [PATCH 11/24] feat: reduce image border-radius from 12px to 8px Co-Authored-By: Claude Sonnet 4.6 --- src/styles/custom.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/styles/custom.css b/src/styles/custom.css index a292ec64..e11cd0ff 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -121,7 +121,7 @@ /* Article content images */ .sl-markdown-content img { - border-radius: 12px; + border-radius: 8px; border: 1px solid var(--sl-color-gray-6); } From 65ad96392af07221a9544c067e175cf8c0d3d59a Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Thu, 28 May 2026 14:05:04 +0300 Subject: [PATCH 12/24] feat: add 8px border-radius to sidebar nav items and accordions Co-Authored-By: Claude Sonnet 4.6 --- src/styles/custom.css | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/styles/custom.css b/src/styles/custom.css index e11cd0ff..901806ff 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -172,26 +172,31 @@ border-color: var(--brand-400) !important; } -/* Sidebar nav item hover — skip active */ +/* Sidebar nav item — active and hover */ +nav.sidebar a[aria-current='page'] { + border-radius: 8px !important; +} + +nav.sidebar a, +nav.sidebar details > summary { + border-radius: 8px !important; +} + :root[data-theme='light'] nav.sidebar a:not([aria-current='page']):hover { background-color: rgba(0, 0, 0, 0.06) !important; - border-radius: 6px !important; } :root:not([data-theme='light']) nav.sidebar a:not([aria-current='page']):hover { background-color: rgba(255, 255, 255, 0.08) !important; - border-radius: 6px !important; } /* Sidebar accordion group label hover */ :root[data-theme='light'] nav.sidebar details > summary:hover { background-color: rgba(0, 0, 0, 0.06) !important; - border-radius: 6px !important; } :root:not([data-theme='light']) nav.sidebar details > summary:hover { background-color: rgba(255, 255, 255, 0.08) !important; - border-radius: 6px !important; } .docsearch-modal-footer-logo { From 85a3c8977d3ad0873c4436a4ec73eb1a41ef1fc0 Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Thu, 28 May 2026 17:45:42 +0300 Subject: [PATCH 13/24] feat: add neutral palette tokens and dark theme color overrides Add Tailwind neutral palette as CSS variables, apply to Starlight gray tokens for both themes. Set dark theme bg colors (content/nav/sidebar), inline code backgrounds, sidebar active state, and code block styling. Co-Authored-By: Claude Sonnet 4.6 --- src/styles/custom.css | 64 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/src/styles/custom.css b/src/styles/custom.css index 901806ff..e082e4ae 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -3,6 +3,21 @@ :root { --sl-font: 'Inter', sans-serif; + /* Neutral palette — Tailwind neutral */ + --neutral-0: #ffffff; + --neutral-50: #fafafa; + --neutral-100: #f5f5f5; + --neutral-200: #e5e5e5; + --neutral-300: #d4d4d4; + --neutral-400: #a3a3a3; + --neutral-500: #737373; + --neutral-600: #525252; + --neutral-700: #404040; + --neutral-800: #262626; + --neutral-850: #1e1e1e; + --neutral-900: #171717; + --neutral-950: #0a0a0a; + /* Brand palette — indigo */ --brand-100: #e0e7ff; --brand-200: #c7d2fe; @@ -27,6 +42,11 @@ .sl-markdown-content h5 { font-size: 0.95rem !important; } .sl-markdown-content h6 { font-size: 0.85rem !important; } +/* Code block background in dark theme */ +:root:not([data-theme='light']) .expressive-code .frame pre { + box-shadow: inset 0 0 0 1000px var(--neutral-800) !important; +} + /* Hide code block decorative header */ .expressive-code .header { display: none !important; @@ -38,6 +58,7 @@ overflow: auto; } + .expressive-code { --ec-brdWd: 0px; } @@ -48,7 +69,7 @@ } :root:not([data-theme='light']) .expressive-code .frame { - outline: 1px solid var(--sl-color-gray-5); + outline: 1px solid var(--neutral-700); border-radius: 8px; } @@ -119,6 +140,14 @@ border-radius: 6px; } +:root[data-theme='light'] .sl-markdown-content :not(pre) > code { + background-color: var(--neutral-100) !important; +} + +:root:not([data-theme='light']) .sl-markdown-content :not(pre) > code { + background-color: var(--neutral-700) !important; +} + /* Article content images */ .sl-markdown-content img { border-radius: 8px; @@ -165,6 +194,7 @@ :root .sl-link-button.primary { border-color: var(--brand-300) !important; + color: var(--neutral-0) !important; } :root .sl-link-button.primary:hover { @@ -172,11 +202,15 @@ border-color: var(--brand-400) !important; } -/* Sidebar nav item — active and hover */ +/* Sidebar nav item — active */ nav.sidebar a[aria-current='page'] { border-radius: 8px !important; } +:root:not([data-theme='light']) nav.sidebar a[aria-current='page'] { + color: var(--neutral-0) !important; +} + nav.sidebar a, nav.sidebar details > summary { border-radius: 8px !important; @@ -208,6 +242,32 @@ nav.sidebar details > summary { outline-color: var(--brand-500) !important; } +/* Light theme grays — gray-1 darkest → gray-7 lightest */ +:root[data-theme='light'] { + --sl-color-bg-nav: var(--neutral-0); + --sl-color-gray-1: var(--neutral-900); + --sl-color-gray-2: var(--neutral-700); + --sl-color-gray-3: var(--neutral-500); + --sl-color-gray-4: var(--neutral-400); + --sl-color-gray-5: var(--neutral-300); + --sl-color-gray-6: var(--neutral-200); + --sl-color-gray-7: var(--neutral-100); +} + +/* Dark theme grays — gray-1 lightest → gray-7 darkest */ +:root:not([data-theme='light']) { + --sl-color-gray-1: var(--neutral-100); + --sl-color-gray-2: var(--neutral-300); + --sl-color-gray-3: var(--neutral-400); + --sl-color-gray-4: var(--neutral-500); + --sl-color-gray-5: var(--neutral-600); + --sl-color-gray-6: var(--neutral-700); + --sl-color-gray-7: var(--neutral-800); + --sl-color-bg: var(--neutral-900); + --sl-color-bg-nav: var(--neutral-850); + --sl-color-bg-sidebar: var(--neutral-850); +} + /* Light theme — primary darker for contrast on white */ :root[data-theme='light'] { --docsearch-primary-color: var(--brand-500); From 5c90ce65acac82b323214a1027be337402fb69d5 Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Thu, 28 May 2026 18:30:46 +0300 Subject: [PATCH 14/24] feat: remove layout dividers and tighten page title spacing Co-Authored-By: Claude Sonnet 4.6 --- src/styles/custom.css | 132 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/src/styles/custom.css b/src/styles/custom.css index e082e4ae..fed89cc0 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -18,6 +18,46 @@ --neutral-900: #171717; --neutral-950: #0a0a0a; + /* Blue palette */ + --blue-50: #eff6ff; + --blue-100: #dbeafe; + --blue-300: #93c5fd; + --blue-400: #60a5fa; + --blue-500: #3b82f6; + --blue-700: #1d4ed8; + --blue-900: #1e3a8a; + --blue-950: #172554; + + /* Purple palette */ + --purple-50: #faf5ff; + --purple-100: #f3e8ff; + --purple-300: #d8b4fe; + --purple-400: #c084fc; + --purple-500: #a855f7; + --purple-700: #7e22ce; + --purple-900: #581c87; + --purple-950: #3b0764; + + /* Amber palette */ + --amber-50: #fffbeb; + --amber-100: #fef3c7; + --amber-300: #fcd34d; + --amber-400: #fbbf24; + --amber-500: #f59e0b; + --amber-700: #b45309; + --amber-900: #78350f; + --amber-950: #451a03; + + /* Red palette */ + --red-50: #fef2f2; + --red-100: #fee2e2; + --red-300: #fca5a5; + --red-400: #f87171; + --red-500: #ef4444; + --red-700: #b91c1c; + --red-900: #7f1d1d; + --red-950: #450a0a; + /* Brand palette — indigo */ --brand-100: #e0e7ff; --brand-200: #c7d2fe; @@ -148,6 +188,82 @@ background-color: var(--neutral-700) !important; } +/* Asides */ +.starlight-aside { + padding-block: 0.625rem !important; +} + +.starlight-aside__title { + font-size: 0.95rem !important; +} + + +.starlight-aside__icon { + font-size: 1em !important; + width: 0.875em !important; + height: 0.875em !important; +} + +/* Asides — light theme */ +:root[data-theme='light'] .starlight-aside { + border-radius: 8px; + border-inline-start: none; +} +:root[data-theme='light'] .starlight-aside--note { + background-color: var(--brand-100) !important; + --sl-color-asides-border: var(--brand-500) !important; + --sl-color-asides-text-accent: var(--brand-700) !important; + outline: 1px solid var(--brand-200); +} +:root[data-theme='light'] .starlight-aside--tip { + background-color: var(--purple-50) !important; + --sl-color-asides-border: var(--purple-500) !important; + --sl-color-asides-text-accent: var(--purple-700) !important; + outline: 1px solid var(--purple-100); +} +:root[data-theme='light'] .starlight-aside--caution { + background-color: var(--amber-50) !important; + --sl-color-asides-border: var(--amber-500) !important; + --sl-color-asides-text-accent: var(--amber-700) !important; + outline: 1px solid var(--amber-100); +} +:root[data-theme='light'] .starlight-aside--danger { + background-color: var(--red-50) !important; + --sl-color-asides-border: var(--red-500) !important; + --sl-color-asides-text-accent: var(--red-700) !important; + outline: 1px solid var(--red-100); +} + +/* Asides — dark theme */ +:root:not([data-theme='light']) .starlight-aside { + border-radius: 8px; + border-inline-start: none; +} +:root:not([data-theme='light']) .starlight-aside--note { + background-color: color-mix(in srgb, var(--brand-900) 70%, transparent) !important; + --sl-color-asides-border: var(--brand-400) !important; + --sl-color-asides-text-accent: var(--brand-300) !important; + outline: 1px solid color-mix(in srgb, var(--brand-700) 80%, transparent); +} +:root:not([data-theme='light']) .starlight-aside--tip { + background-color: color-mix(in srgb, var(--purple-950) 70%, transparent) !important; + --sl-color-asides-border: var(--purple-400) !important; + --sl-color-asides-text-accent: var(--purple-300) !important; + outline: 1px solid color-mix(in srgb, var(--purple-900) 80%, transparent); +} +:root:not([data-theme='light']) .starlight-aside--caution { + background-color: color-mix(in srgb, var(--amber-950) 70%, transparent) !important; + --sl-color-asides-border: var(--amber-400) !important; + --sl-color-asides-text-accent: var(--amber-300) !important; + outline: 1px solid color-mix(in srgb, var(--amber-900) 80%, transparent); +} +:root:not([data-theme='light']) .starlight-aside--danger { + background-color: color-mix(in srgb, var(--red-950) 70%, transparent) !important; + --sl-color-asides-border: var(--red-400) !important; + --sl-color-asides-text-accent: var(--red-300) !important; + outline: 1px solid color-mix(in srgb, var(--red-900) 80%, transparent); +} + /* Article content images */ .sl-markdown-content img { border-radius: 8px; @@ -237,6 +353,22 @@ nav.sidebar details > summary { display: none!important; } +/* Remove divider and top padding under page title */ +.content-panel + .content-panel { + border-top: none !important; + padding-top: 0 !important; +} + +/* Reduce bottom padding in the h1 title block */ +.content-panel:first-of-type { + padding-bottom: 0.75rem !important; +} + +/* Remove right sidebar (TOC) left border */ +.right-sidebar { + border-inline-start: none !important; +} + /* Global focus outline — indigo */ :focus-visible { outline-color: var(--brand-500) !important; From 9903fd4d1cd82bb2a6548dacff9ca7e51b8474b1 Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Tue, 2 Jun 2026 00:48:36 +0300 Subject: [PATCH 15/24] feat: add snake indicator animation to TOC sidebar Smooth sliding indicator that follows the active heading on scroll. Overrides Starlight's TableOfContents with an animated 2px line that moves instantly on page load (no shoot effect) and transitions smoothly on scroll via MutationObserver + requestIdleCallback. Co-Authored-By: Claude Sonnet 4.6 --- astro.config.mjs | 3 +- src/components/TOCList.astro | 48 +++++++ src/components/TableOfContents.astro | 203 +++++++++++++++++++++++++++ 3 files changed, 253 insertions(+), 1 deletion(-) create mode 100644 src/components/TOCList.astro create mode 100644 src/components/TableOfContents.astro diff --git a/astro.config.mjs b/astro.config.mjs index b7c638b8..5d968ed0 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -73,7 +73,8 @@ export default defineConfig({ SocialIcons: './src/components/Links.astro', Search: './src/components/Search.astro', PageTitle: './src/components/PageTitle.astro', - + ThemeSelect: './src/components/ThemeSelect.astro', + TableOfContents: './src/components/TableOfContents.astro', }, sidebar: [ diff --git a/src/components/TOCList.astro b/src/components/TOCList.astro new file mode 100644 index 00000000..8b59ff8f --- /dev/null +++ b/src/components/TOCList.astro @@ -0,0 +1,48 @@ +--- +interface TocItem { + slug: string; + text: string; + children: TocItem[]; +} + +interface Props { + toc: TocItem[]; + depth?: number; +} + +const { toc, depth = 0 } = Astro.props; +--- + +
    + { + toc.map((heading) => ( +
  • + + {heading.text} + + {heading.children.length > 0 && ( + + )} +
  • + )) + } +
+ + diff --git a/src/components/TableOfContents.astro b/src/components/TableOfContents.astro new file mode 100644 index 00000000..cfd38734 --- /dev/null +++ b/src/components/TableOfContents.astro @@ -0,0 +1,203 @@ +--- +import TOCList from './TOCList.astro'; + +const { toc } = Astro.locals.starlightRoute; +--- + +{ + toc && ( + + + + ) +} + + + + From 99b1943aab203adef00ff076256e69bec8636ddf Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Mon, 1 Jun 2026 23:26:12 +0300 Subject: [PATCH 16/24] feat: replace theme select dropdown with single toggle button Co-Authored-By: Claude Sonnet 4.6 --- src/components/ThemeSelect.astro | 103 +++++++++++++++++++++++++++++++ src/styles/custom.css | 4 ++ 2 files changed, 107 insertions(+) create mode 100644 src/components/ThemeSelect.astro diff --git a/src/components/ThemeSelect.astro b/src/components/ThemeSelect.astro new file mode 100644 index 00000000..aa4d12e9 --- /dev/null +++ b/src/components/ThemeSelect.astro @@ -0,0 +1,103 @@ +--- +--- + + + + + + + +{/* Inlined to avoid FOUC */} + + + diff --git a/src/styles/custom.css b/src/styles/custom.css index fed89cc0..aba74c2d 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -681,4 +681,8 @@ html[data-theme=dark] .docsearch-btn-placeholder { top: 40px; right: -260px; } +} + +.social-icons::after { + display: none !important; } \ No newline at end of file From 00a43d745eff5d044d037aea94494d441be3aa3b Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Mon, 1 Jun 2026 23:31:17 +0300 Subject: [PATCH 17/24] style: normalize theme toggle border-radius to 8px Co-Authored-By: Claude Sonnet 4.6 --- src/components/ThemeSelect.astro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ThemeSelect.astro b/src/components/ThemeSelect.astro index aa4d12e9..07a7139a 100644 --- a/src/components/ThemeSelect.astro +++ b/src/components/ThemeSelect.astro @@ -32,7 +32,7 @@ height: 2rem; border: none; outline: none; - border-radius: 0.375rem; + border-radius: 8px; background: transparent; color: var(--sl-color-gray-3); cursor: pointer; From 8d5b227d1de5205a6c77380f77be86d9732271bd Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Tue, 2 Jun 2026 00:10:24 +0300 Subject: [PATCH 18/24] feat: add sidebar nav icons and spacing polish - Add SVG icons for all 9 top-level sidebar groups via CSS mask-image - Set nav item height to 32px via padding-block - Fix nested accordion font-size to 14px (level 2+) - Align nesting border line under group icon Co-Authored-By: Claude Sonnet 4.6 --- public/icons/book.svg | 1 + public/icons/chart.svg | 1 + public/icons/file.svg | 1 + public/icons/folder.svg | 1 + public/icons/plug.svg | 1 + public/icons/puzzle.svg | 1 + public/icons/rocket.svg | 1 + public/icons/settings.svg | 1 + public/icons/support.svg | 1 + public/icons/users.svg | 1 + src/styles/custom.css | 81 +++++++++++++++++++++++++++++++++++++++ 11 files changed, 91 insertions(+) create mode 100644 public/icons/book.svg create mode 100644 public/icons/chart.svg create mode 100644 public/icons/file.svg create mode 100644 public/icons/folder.svg create mode 100644 public/icons/plug.svg create mode 100644 public/icons/puzzle.svg create mode 100644 public/icons/rocket.svg create mode 100644 public/icons/settings.svg create mode 100644 public/icons/support.svg create mode 100644 public/icons/users.svg diff --git a/public/icons/book.svg b/public/icons/book.svg new file mode 100644 index 00000000..3e74cf68 --- /dev/null +++ b/public/icons/book.svg @@ -0,0 +1 @@ + diff --git a/public/icons/chart.svg b/public/icons/chart.svg new file mode 100644 index 00000000..7478373b --- /dev/null +++ b/public/icons/chart.svg @@ -0,0 +1 @@ + diff --git a/public/icons/file.svg b/public/icons/file.svg new file mode 100644 index 00000000..a96aa0bf --- /dev/null +++ b/public/icons/file.svg @@ -0,0 +1 @@ + diff --git a/public/icons/folder.svg b/public/icons/folder.svg new file mode 100644 index 00000000..c51b540c --- /dev/null +++ b/public/icons/folder.svg @@ -0,0 +1 @@ + diff --git a/public/icons/plug.svg b/public/icons/plug.svg new file mode 100644 index 00000000..c3002a23 --- /dev/null +++ b/public/icons/plug.svg @@ -0,0 +1 @@ + diff --git a/public/icons/puzzle.svg b/public/icons/puzzle.svg new file mode 100644 index 00000000..32fed5b6 --- /dev/null +++ b/public/icons/puzzle.svg @@ -0,0 +1 @@ + diff --git a/public/icons/rocket.svg b/public/icons/rocket.svg new file mode 100644 index 00000000..ec2e43d8 --- /dev/null +++ b/public/icons/rocket.svg @@ -0,0 +1 @@ + diff --git a/public/icons/settings.svg b/public/icons/settings.svg new file mode 100644 index 00000000..4d92ca8a --- /dev/null +++ b/public/icons/settings.svg @@ -0,0 +1 @@ + diff --git a/public/icons/support.svg b/public/icons/support.svg new file mode 100644 index 00000000..19f8eb65 --- /dev/null +++ b/public/icons/support.svg @@ -0,0 +1 @@ + diff --git a/public/icons/users.svg b/public/icons/users.svg new file mode 100644 index 00000000..13997412 --- /dev/null +++ b/public/icons/users.svg @@ -0,0 +1 @@ + diff --git a/src/styles/custom.css b/src/styles/custom.css index aba74c2d..d6b8b544 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -318,6 +318,11 @@ border-color: var(--brand-400) !important; } +/* Align nesting border line under top-level group icon center */ +nav.sidebar ul.top-level > li > details > ul > li { + margin-inline-start: 16px !important; +} + /* Sidebar nav item — active */ nav.sidebar a[aria-current='page'] { border-radius: 8px !important; @@ -330,6 +335,8 @@ nav.sidebar a[aria-current='page'] { nav.sidebar a, nav.sidebar details > summary { border-radius: 8px !important; + padding-block: 6px !important; + margin-block: 0 !important; } :root[data-theme='light'] nav.sidebar a:not([aria-current='page']):hover { @@ -340,6 +347,11 @@ nav.sidebar details > summary { background-color: rgba(255, 255, 255, 0.08) !important; } +/* Nested accordion labels (level 2+) — same font-size as regular nav links */ +nav.sidebar details details > summary .large { + font-size: 14px !important; +} + /* Sidebar accordion group label hover */ :root[data-theme='light'] nav.sidebar details > summary:hover { background-color: rgba(0, 0, 0, 0.06) !important; @@ -349,6 +361,75 @@ nav.sidebar details > summary { background-color: rgba(255, 255, 255, 0.08) !important; } +/* Top-level sidebar group icons via ::before with SVG mask */ +nav.sidebar ul.top-level > li > details > summary .group-label { + display: inline-flex !important; + align-items: center !important; +} + +nav.sidebar ul.top-level > li > details > summary .group-label::before, +nav.sidebar ul.top-level > li > a::before { + content: ''; + display: block; + width: 16px; + height: 16px; + min-width: 16px; + margin-inline-end: 8px; + background-color: currentColor; + mask-size: contain; + mask-repeat: no-repeat; + mask-position: center; + -webkit-mask-size: contain; + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; +} + +nav.sidebar ul.top-level > li:nth-child(1) > details > summary .group-label::before, +nav.sidebar ul.top-level > li:nth-child(1) > a::before { + mask-image: url('/icons/rocket.svg'); + -webkit-mask-image: url('/icons/rocket.svg'); +} +nav.sidebar ul.top-level > li:nth-child(2) > details > summary .group-label::before, +nav.sidebar ul.top-level > li:nth-child(2) > a::before { + mask-image: url('/icons/book.svg'); + -webkit-mask-image: url('/icons/book.svg'); +} +nav.sidebar ul.top-level > li:nth-child(3) > details > summary .group-label::before, +nav.sidebar ul.top-level > li:nth-child(3) > a::before { + mask-image: url('/icons/folder.svg'); + -webkit-mask-image: url('/icons/folder.svg'); +} +nav.sidebar ul.top-level > li:nth-child(4) > details > summary .group-label::before, +nav.sidebar ul.top-level > li:nth-child(4) > a::before { + mask-image: url('/icons/chart.svg'); + -webkit-mask-image: url('/icons/chart.svg'); +} +nav.sidebar ul.top-level > li:nth-child(5) > details > summary .group-label::before, +nav.sidebar ul.top-level > li:nth-child(5) > a::before { + mask-image: url('/icons/settings.svg'); + -webkit-mask-image: url('/icons/settings.svg'); +} +nav.sidebar ul.top-level > li:nth-child(6) > details > summary .group-label::before, +nav.sidebar ul.top-level > li:nth-child(6) > a::before { + mask-image: url('/icons/puzzle.svg'); + -webkit-mask-image: url('/icons/puzzle.svg'); +} +nav.sidebar ul.top-level > li:nth-child(7) > details > summary .group-label::before, +nav.sidebar ul.top-level > li:nth-child(7) > a::before { + mask-image: url('/icons/users.svg'); + -webkit-mask-image: url('/icons/users.svg'); +} +nav.sidebar ul.top-level > li:nth-child(8) > details > summary .group-label::before, +nav.sidebar ul.top-level > li:nth-child(8) > a::before { + mask-image: url('/icons/file.svg'); + -webkit-mask-image: url('/icons/file.svg'); +} +nav.sidebar ul.top-level > li:nth-child(9) > details > summary .group-label::before, +nav.sidebar ul.top-level > li:nth-child(9) > a::before { + mask-image: url('/icons/support.svg'); + -webkit-mask-image: url('/icons/support.svg'); +} + .docsearch-modal-footer-logo { display: none!important; } From b68fd385bee87a086adb6b874a8582e7b3eb89c2 Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Tue, 2 Jun 2026 00:12:10 +0300 Subject: [PATCH 19/24] chore: remove unused plug.svg and dead CSS selectors Co-Authored-By: Claude Sonnet 4.6 --- public/icons/plug.svg | 1 - src/styles/custom.css | 30 ++++++++++-------------------- 2 files changed, 10 insertions(+), 21 deletions(-) delete mode 100644 public/icons/plug.svg diff --git a/public/icons/plug.svg b/public/icons/plug.svg deleted file mode 100644 index c3002a23..00000000 --- a/public/icons/plug.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/styles/custom.css b/src/styles/custom.css index d6b8b544..57410625 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -367,8 +367,7 @@ nav.sidebar ul.top-level > li > details > summary .group-label { align-items: center !important; } -nav.sidebar ul.top-level > li > details > summary .group-label::before, -nav.sidebar ul.top-level > li > a::before { +nav.sidebar ul.top-level > li > details > summary .group-label::before { content: ''; display: block; width: 16px; @@ -384,48 +383,39 @@ nav.sidebar ul.top-level > li > a::before { -webkit-mask-position: center; } -nav.sidebar ul.top-level > li:nth-child(1) > details > summary .group-label::before, -nav.sidebar ul.top-level > li:nth-child(1) > a::before { +nav.sidebar ul.top-level > li:nth-child(1) > details > summary .group-label::before { mask-image: url('/icons/rocket.svg'); -webkit-mask-image: url('/icons/rocket.svg'); } -nav.sidebar ul.top-level > li:nth-child(2) > details > summary .group-label::before, -nav.sidebar ul.top-level > li:nth-child(2) > a::before { +nav.sidebar ul.top-level > li:nth-child(2) > details > summary .group-label::before { mask-image: url('/icons/book.svg'); -webkit-mask-image: url('/icons/book.svg'); } -nav.sidebar ul.top-level > li:nth-child(3) > details > summary .group-label::before, -nav.sidebar ul.top-level > li:nth-child(3) > a::before { +nav.sidebar ul.top-level > li:nth-child(3) > details > summary .group-label::before { mask-image: url('/icons/folder.svg'); -webkit-mask-image: url('/icons/folder.svg'); } -nav.sidebar ul.top-level > li:nth-child(4) > details > summary .group-label::before, -nav.sidebar ul.top-level > li:nth-child(4) > a::before { +nav.sidebar ul.top-level > li:nth-child(4) > details > summary .group-label::before { mask-image: url('/icons/chart.svg'); -webkit-mask-image: url('/icons/chart.svg'); } -nav.sidebar ul.top-level > li:nth-child(5) > details > summary .group-label::before, -nav.sidebar ul.top-level > li:nth-child(5) > a::before { +nav.sidebar ul.top-level > li:nth-child(5) > details > summary .group-label::before { mask-image: url('/icons/settings.svg'); -webkit-mask-image: url('/icons/settings.svg'); } -nav.sidebar ul.top-level > li:nth-child(6) > details > summary .group-label::before, -nav.sidebar ul.top-level > li:nth-child(6) > a::before { +nav.sidebar ul.top-level > li:nth-child(6) > details > summary .group-label::before { mask-image: url('/icons/puzzle.svg'); -webkit-mask-image: url('/icons/puzzle.svg'); } -nav.sidebar ul.top-level > li:nth-child(7) > details > summary .group-label::before, -nav.sidebar ul.top-level > li:nth-child(7) > a::before { +nav.sidebar ul.top-level > li:nth-child(7) > details > summary .group-label::before { mask-image: url('/icons/users.svg'); -webkit-mask-image: url('/icons/users.svg'); } -nav.sidebar ul.top-level > li:nth-child(8) > details > summary .group-label::before, -nav.sidebar ul.top-level > li:nth-child(8) > a::before { +nav.sidebar ul.top-level > li:nth-child(8) > details > summary .group-label::before { mask-image: url('/icons/file.svg'); -webkit-mask-image: url('/icons/file.svg'); } -nav.sidebar ul.top-level > li:nth-child(9) > details > summary .group-label::before, -nav.sidebar ul.top-level > li:nth-child(9) > a::before { +nav.sidebar ul.top-level > li:nth-child(9) > details > summary .group-label::before { mask-image: url('/icons/support.svg'); -webkit-mask-image: url('/icons/support.svg'); } From 4149231b24bee359e25bae5e18287b2d173387d3 Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Tue, 2 Jun 2026 01:01:37 +0300 Subject: [PATCH 20/24] revert: restore default Starlight content font sizes Remove custom reduced font-size overrides for .sl-markdown-content and headings, restoring Starlight defaults as in the docs branch. Co-Authored-By: Claude Sonnet 4.6 --- src/styles/custom.css | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/styles/custom.css b/src/styles/custom.css index 57410625..65c5ecb5 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -69,19 +69,8 @@ --brand-900: #312e81; } -/* Base article font size — slightly reduced from 1rem default */ -.sl-markdown-content { font-size: 0.875rem; } - .hero .tagline { font-size: 16px; } -/* Article headings — scaled down ×0.85 from Starlight defaults */ -.sl-markdown-content h1, .content-panel h1 { font-size: 2rem !important; } -.sl-markdown-content h2 { font-size: 1.75rem !important; } -.sl-markdown-content h3 { font-size: 1.275rem !important; } -.sl-markdown-content h4 { font-size: 1.0625rem !important; } -.sl-markdown-content h5 { font-size: 0.95rem !important; } -.sl-markdown-content h6 { font-size: 0.85rem !important; } - /* Code block background in dark theme */ :root:not([data-theme='light']) .expressive-code .frame pre { box-shadow: inset 0 0 0 1000px var(--neutral-800) !important; From 0e7439c4980ca0cd209e9def6cc302c4354c7d5d Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Tue, 2 Jun 2026 08:10:24 +0300 Subject: [PATCH 21/24] style: migrate search modal colors to neutral palette Replace hardcoded rgb values in docsearch modal with neutral palette tokens, split into explicit light/dark theme overrides. Focus border uses indigo (brand) color. Co-Authored-By: Claude Sonnet 4.6 --- src/styles/custom.css | 64 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/src/styles/custom.css b/src/styles/custom.css index 65c5ecb5..9281ffb6 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -630,19 +630,71 @@ html[data-theme=dark] .docsearch-btn-placeholder { --docsearch-highlight-color: var(--sl-color-accent); } +/* Search modal — light theme palette */ +:root[data-theme='light'] { + --docsearch-modal-background: var(--neutral-0); + --docsearch-modal-container-background: rgba(0, 0, 0, 0.4); + --docsearch-modal-shadow: 0 8px 32px rgba(0, 0, 0, 0.12); + --docsearch-text-color: var(--neutral-900); + --docsearch-muted-color: var(--neutral-500); + --docsearch-icon-color: var(--neutral-500); + --docsearch-hit-color: var(--neutral-800); + --docsearch-hit-background: var(--neutral-0); + --docsearch-hit-shadow: 0 1px 3px 0 var(--neutral-200); + --docsearch-footer-background: var(--neutral-50); + --docsearch-footer-shadow: 0 -1px 0 0 var(--neutral-200); + --docsearch-key-gradient: linear-gradient(-225deg, var(--neutral-200) 0%, var(--neutral-100) 100%); + --docsearch-key-shadow: + inset 0 -2px 0 0 var(--neutral-300), + inset 0 0 1px 1px var(--neutral-0), + 0 1px 2px 1px rgba(0, 0, 0, 0.12); +} + +/* Search modal — dark theme palette */ +:root:not([data-theme='light']) { + --docsearch-modal-background: var(--neutral-850); + --docsearch-modal-container-background: rgba(0, 0, 0, 0.6); + --docsearch-modal-shadow: 0 8px 32px rgba(0, 0, 0, 0.5); + --docsearch-text-color: var(--neutral-100); + --docsearch-muted-color: var(--neutral-400); + --docsearch-icon-color: var(--neutral-400); + --docsearch-hit-color: var(--neutral-200); + --docsearch-hit-background: var(--neutral-800); + --docsearch-hit-shadow: 0 1px 3px 0 var(--neutral-950); + --docsearch-footer-background: var(--neutral-900); + --docsearch-footer-shadow: 0 -1px 0 0 var(--neutral-700); + --docsearch-key-gradient: linear-gradient(-225deg, var(--neutral-700) 0%, var(--neutral-600) 100%); + --docsearch-key-shadow: + inset 0 -2px 0 0 var(--neutral-800), + inset 0 0 1px 1px var(--neutral-600), + 0 1px 2px 1px rgba(0, 0, 0, 0.4); +} + /* Search modal — icon */ .docsearch-modal-search-input-icon { color: var(--sl-color-gray-3) !important; } -/* Search modal — input */ -.docsearch-modal-search-input-form { - background: rgba(255, 255, 255, 0.1) !important; - box-shadow: inset 0 0 0 1.5px rgba(150, 159, 175, 0.5) !important; +/* Search modal — input (light) */ +:root[data-theme='light'] .docsearch-modal-search-input-form { + background: var(--neutral-50) !important; + box-shadow: inset 0 0 0 1.5px var(--neutral-300) !important; +} + +/* Search modal — input (dark) */ +:root:not([data-theme='light']) .docsearch-modal-search-input-form { + background: var(--neutral-800) !important; + box-shadow: inset 0 0 0 1.5px var(--neutral-600) !important; +} + +:root[data-theme='light'] .docsearch-modal-search-input-form:focus-within { + background: var(--neutral-0) !important; + box-shadow: inset 0 0 0 2px var(--brand-500) !important; } -.docsearch-modal-search-input-form:focus-within { - box-shadow: inset 0 0 0 2px var(--sl-color-accent) !important; +:root:not([data-theme='light']) .docsearch-modal-search-input-form:focus-within { + background: var(--neutral-800) !important; + box-shadow: inset 0 0 0 2px var(--brand-400) !important; } @media screen and (max-width: 767px) { From 404f0abbb2cb4b4917f6a0d6e5ca408afea96c19 Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Tue, 2 Jun 2026 12:31:29 +0300 Subject: [PATCH 22/24] revert: remove custom TOC snake indicator and align items to heading Deletes TableOfContents.astro and TOCList.astro (snake animation + MutationObserver scroll-spy), restores Starlight's default TOC, and resets padding-inline-start so list items align flush with the "On this page" heading. Co-Authored-By: Claude Sonnet 4.6 --- astro.config.mjs | 1 - src/components/TOCList.astro | 48 ------- src/components/TableOfContents.astro | 203 --------------------------- src/styles/custom.css | 15 ++ 4 files changed, 15 insertions(+), 252 deletions(-) delete mode 100644 src/components/TOCList.astro delete mode 100644 src/components/TableOfContents.astro diff --git a/astro.config.mjs b/astro.config.mjs index 5d968ed0..22e72e40 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -74,7 +74,6 @@ export default defineConfig({ Search: './src/components/Search.astro', PageTitle: './src/components/PageTitle.astro', ThemeSelect: './src/components/ThemeSelect.astro', - TableOfContents: './src/components/TableOfContents.astro', }, sidebar: [ diff --git a/src/components/TOCList.astro b/src/components/TOCList.astro deleted file mode 100644 index 8b59ff8f..00000000 --- a/src/components/TOCList.astro +++ /dev/null @@ -1,48 +0,0 @@ ---- -interface TocItem { - slug: string; - text: string; - children: TocItem[]; -} - -interface Props { - toc: TocItem[]; - depth?: number; -} - -const { toc, depth = 0 } = Astro.props; ---- - -
    - { - toc.map((heading) => ( -
  • - - {heading.text} - - {heading.children.length > 0 && ( - - )} -
  • - )) - } -
- - diff --git a/src/components/TableOfContents.astro b/src/components/TableOfContents.astro deleted file mode 100644 index cfd38734..00000000 --- a/src/components/TableOfContents.astro +++ /dev/null @@ -1,203 +0,0 @@ ---- -import TOCList from './TOCList.astro'; - -const { toc } = Astro.locals.starlightRoute; ---- - -{ - toc && ( - - - - ) -} - - - - diff --git a/src/styles/custom.css b/src/styles/custom.css index 9281ffb6..cffe2656 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -429,6 +429,21 @@ nav.sidebar ul.top-level > li:nth-child(9) > details > summary .group-label::bef border-inline-start: none !important; } +/* TOC active item — slightly bolder */ +starlight-toc a[aria-current='true'] { + font-weight: 500 !important; +} + +/* TOC padding — level 1 aligned with heading */ +starlight-toc a { + padding-inline-start: 0 !important; +} + +/* TOC padding — level 2 */ +starlight-toc ul ul a { + padding-inline-start: 1rem !important; +} + /* Global focus outline — indigo */ :focus-visible { outline-color: var(--brand-500) !important; From 1345ac4cb65ed98b4b4a86aca485a961fc0089d0 Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Tue, 2 Jun 2026 14:22:23 +0300 Subject: [PATCH 23/24] fix: download images before rewriting paths to prevent missing image build errors Images were rewritten to local paths before being downloaded, causing Astro build failures when any image fetch returned 403. Now downloads happen first, and only successfully downloaded images get local paths; failed ones fall back to raw GitHub URLs. Co-Authored-By: Claude Sonnet 4.6 --- src/scripts/runok.cjs | 44 ++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/scripts/runok.cjs b/src/scripts/runok.cjs index 70287dbb..fb7683be 100644 --- a/src/scripts/runok.cjs +++ b/src/scripts/runok.cjs @@ -355,9 +355,35 @@ head: content = content.replace(/^# .*\n+/, ''); + const apiHeaders = typeof token !== 'undefined' ? { Authorization: `token ${token}` } : {}; + const imageListResponse = await axios.get(apiUrl, { headers: apiHeaders }); + const images = imageListResponse.data; + + const downloadedImages = new Set(); + + for (const file of images) { + if (file.type === 'file') { + const imageName = file.name; + const imageUrl = file.download_url; + const imagePath = path.join(imageFolder, imageName); + + try { + const imageData = await axios.get(imageUrl, { responseType: 'arraybuffer' }); + fs.writeFileSync(imagePath, imageData.data); + downloadedImages.add(imageName); + console.log(`🖼️ Downloaded: ${imageName}`); + } catch (imgErr) { + console.warn(`⚠️ Failed to download image: ${imageName}, ${imgErr.message}`); + } + } + } + content = content.replace(/!\[(.*?)\]\((img\/.*?)\)/g, (match, alt, imgPath) => { const imageName = path.basename(imgPath); - return `![${alt}](images/${imageName})`; + if (downloadedImages.has(imageName)) { + return `![${alt}](images/${imageName})`; + } + return `![${alt}](https://raw.githubusercontent.com/${repo}/${branch}/${imgPath})`; }); content = content.replace(/\.\/img\//g, './images/'); @@ -378,22 +404,6 @@ head: const readmePath = path.join(destinationFolder, 'java-reporter.md'); fs.writeFileSync(readmePath, content); console.log(`✅ Saved: ${readmePath}`); - - const apiHeaders = typeof token !== 'undefined' ? { Authorization: `token ${token}` } : {}; - const imageListResponse = await axios.get(apiUrl, { headers: apiHeaders }); - const images = imageListResponse.data; - - for (const file of images) { - if (file.type === 'file') { - const imageName = file.name; - const imageUrl = file.download_url; - const imagePath = path.join(imageFolder, imageName); - - const imageData = await axios.get(imageUrl, { responseType: 'arraybuffer' }); - fs.writeFileSync(imagePath, imageData.data); - console.log(`🖼️ Downloaded: ${imageName}`); - } - } } catch (err) { console.error(`❌ Failed to fetch or download: ${err.message}`); } From 8e82924834b0a104cde46104dde8d9326cb016ed Mon Sep 17 00:00:00 2001 From: Evgeniy Ellinsliy Date: Tue, 2 Jun 2026 14:35:09 +0300 Subject: [PATCH 24/24] fix: replace blue-tinted sl-color-black with neutral-900 for mobile sidebar Starlight's default --sl-color-black is hsl(224, 10%, 10%) which has a blue hue and is used as the mobile sidebar panel background. Override it with --neutral-900 (#171717) to keep the dark theme fully neutral. Co-Authored-By: Claude Sonnet 4.6 --- src/styles/custom.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/styles/custom.css b/src/styles/custom.css index cffe2656..d8f7df53 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -470,6 +470,7 @@ starlight-toc ul ul a { --sl-color-gray-5: var(--neutral-600); --sl-color-gray-6: var(--neutral-700); --sl-color-gray-7: var(--neutral-800); + --sl-color-black: var(--neutral-900); --sl-color-bg: var(--neutral-900); --sl-color-bg-nav: var(--neutral-850); --sl-color-bg-sidebar: var(--neutral-850);