From a816c0630fd803c5981200ad448669fbcbf82344 Mon Sep 17 00:00:00 2001 From: overcuriousity Date: Sun, 10 Aug 2025 19:57:59 +0200 Subject: [PATCH] knowledgebase style --- src/layouts/BaseLayout.astro | 2 + src/pages/knowledgebase/[slug].astro | 571 ++++++++++++++++------- src/styles/global.css | 170 +------ src/styles/knowledgebase.css | 661 +++++++++++++++++++++++++++ src/styles/palette.css | 62 +++ 5 files changed, 1124 insertions(+), 342 deletions(-) create mode 100644 src/styles/knowledgebase.css create mode 100644 src/styles/palette.css diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index 404d19b..c1f7ee1 100644 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -3,6 +3,8 @@ import Navigation from '../components/Navigation.astro'; import Footer from '../components/Footer.astro'; import '../styles/global.css'; import '../styles/auditTrail.css'; +import '../styles/knowledgebase.css'; +import '../styles/palette.css'; export interface Props { title: string; diff --git a/src/pages/knowledgebase/[slug].astro b/src/pages/knowledgebase/[slug].astro index 7654e8b..fb47cb0 100644 --- a/src/pages/knowledgebase/[slug].astro +++ b/src/pages/knowledgebase/[slug].astro @@ -52,205 +52,430 @@ const currentUrl = Astro.url.href; --- -
-
-
-
-

- {displayTool?.icon && {displayTool.icon}} +
+ +
+
+ + +
+

+ {displayTool?.icon && {displayTool.icon}} {entry.data.title}

-

- {entry.data.description} -

+

{entry.data.description}

-
-
- {isStandalone ? ( - Artikel - ) : ( - <> - {isConcept && Konzept} - {isMethod && Methode} - {!isMethod && !isConcept && !isStandalone && Software} - {!isMethod && !isConcept && hasValidProjectUrl && CC24-Server} - {!isMethod && !isConcept && !isStandalone && displayTool?.license !== 'Proprietary' && Open Source} - - )} - 📖 + + + +
+ + + + + + Zurück +
- -
- {entry.data.difficulty && ( -
- Schwierigkeit -

{entry.data.difficulty}

-
- )} - -
- Letztes Update -

{entry.data.last_updated.toLocaleDateString('de-DE')}

-
- -
- Autor -

{entry.data.author}

-
- -
- Typ -

- {isStandalone ? 'Allgemeiner Artikel' : - isConcept ? 'Konzept-Artikel' : - isMethod ? 'Methoden-Artikel' : - 'Software-Artikel'} -

-
- - {entry.data.categories && entry.data.categories.length > 0 && ( -
- Kategorien -
- {entry.data.categories.map((cat: string) => ( - {cat} - ))} -
-
- )} -
- - -
-
- -
-
- -
-

- {isStandalone ? 'Verwandte Aktionen' : 'Tool-Aktionen'} -

+ +
+ + -
- {isStandalone ? ( - - - - - - - - - Weitere Artikel - - ) : ( - <> - {isConcept ? ( - - - - - - - Mehr erfahren - - ) : isMethod ? ( - - - - - - - Zur Methode - - ) : ( - <> - - - - - - - Software-Homepage - - {hasValidProjectUrl && ( - - - - - - - Zugreifen - - )} - - )} - - )} + +
+
+
+ +
+
- {relatedTools.length > 0 && relatedTools.length > (primaryTool ? 1 : 0) && ( -
-
- - - - - - + +
+
- +
+ + {relatedTools.length > 0 && ( + - )} - - - - - - - Zur Hauptseite - -
+
+ )} + +
-

+ + + + +
\ No newline at end of file diff --git a/src/styles/global.css b/src/styles/global.css index 04fc56c..83ad728 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -14,72 +14,7 @@ padding: 0; } -/* =================================================================== - 2. CSS VARIABLES AND THEMING - ================================================================= */ -:root { - /* Light Theme Colors */ - --color-bg: #fff; - --color-bg-secondary: #f8fafc; - --color-bg-tertiary: #e2e8f0; - --color-text: #1e293b; - --color-text-secondary: #64748b; - --color-border: #cbd5e1; - --color-primary: #2563eb; - --color-primary-hover: #1d4ed8; - --color-accent: #059669; - --color-accent-hover: #047857; - --color-warning: #d97706; - --color-error: #dc2626; - - /* Enhanced card type colors */ - --color-hosted: #7c3aed; - --color-hosted-bg: #f3f0ff; - --color-oss: #059669; - --color-oss-bg: #ecfdf5; - --color-method: #0891b2; - --color-method-bg: #f0f9ff; - --color-concept: #ea580c; - --color-concept-bg: #fff7ed; - - /* Shadows */ - --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 5%); - --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 10%); - --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 10%); - - /* Transitions */ - --transition-fast: all 0.2s ease; - --transition-medium: all 0.3s ease; -} - -[data-theme="dark"] { - --color-bg: #0f172a; - --color-bg-secondary: #1e293b; - --color-bg-tertiary: #334155; - --color-text: #f1f5f9; - --color-text-secondary: #94a3b8; - --color-border: #475569; - --color-primary: #3b82f6; - --color-primary-hover: #60a5fa; - --color-accent: #10b981; - --color-accent-hover: #34d399; - --color-warning: #f59e0b; - --color-error: #f87171; - - --color-hosted: #a855f7; - --color-hosted-bg: #2e1065; - --color-oss: #10b981; - --color-oss-bg: #064e3b; - --color-method: #0891b2; - --color-method-bg: #164e63; - --color-concept: #f97316; - --color-concept-bg: #7c2d12; - - --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 30%); - --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 40%); - --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 50%); -} /* =================================================================== 3. BASE HTML ELEMENTS @@ -3746,133 +3681,30 @@ footer { } } - -/* =================================================================== - MIGRATION UTILITIES - Additional classes for inline style migration - ================================================================= */ - -/* Alignment utilities */ .align-middle { vertical-align: middle; } -/* Font style utilities */ .italic { font-style: italic; } -/* Border width utilities */ .border-2 { border-width: 2px; } -/* Border color utilities */ .border-accent { border-color: var(--color-accent); } -/* Card variants for complex backgrounds */ .card-warning { background: linear-gradient(135deg, var(--color-warning) 0%, var(--color-accent) 100%); color: white; } -/* Header variants for complex gradient combinations */ .header-primary { background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-accent) 100%); color: white; } -/* Ensure we have all text size variants */ .text-2xl { font-size: 1.5rem; } -/* Additional spacing utilities that might be missing */ .py-8 { padding-top: 2rem; padding-bottom: 2rem; } .px-4 { padding-left: 1rem; padding-right: 1rem; } .my-6 { margin-top: 1.5rem; margin-bottom: 1.5rem; } -/* Flex utilities that might be missing */ .flex-1 { flex: 1; } -/* Additional rounded variants */ -.rounded-xl { border-radius: 0.75rem; } - -/* =================================================================== - 23. MARKDOWN CONTENT - ================================================================= */ - -.markdown-content h1, -.markdown-content h2, -.markdown-content h3, -.markdown-content h4, -.markdown-content h5, -.markdown-content h6 { - margin-top: 2rem; - margin-bottom: 1rem; -} - -.markdown-content h1:first-child, -.markdown-content h2:first-child, -.markdown-content h3:first-child { - margin-top: 0; -} - -.markdown-content p { - margin-bottom: 1rem; -} - -.markdown-content ul, -.markdown-content ol { - margin-bottom: 1rem; - padding-left: 1.5rem; -} - -.markdown-content li { - margin-bottom: 0.5rem; -} - -.markdown-content pre { - background-color: var(--color-bg-tertiary); - border: 1px solid var(--color-border); - border-radius: 0.5rem; - padding: 1rem; - margin: 1.5rem 0; - overflow-x: auto; - font-size: 0.875rem; -} - -.markdown-content code:not(pre code) { - background-color: var(--color-bg-secondary); - border: 1px solid var(--color-border); - border-radius: 0.25rem; - padding: 0.125rem 0.375rem; - font-size: 0.875rem; -} - -.markdown-content table { - width: 100%; - border-collapse: collapse; - margin: 1.5rem 0; - background-color: var(--color-bg); - border-radius: 0.5rem; - overflow: hidden; - border: 1px solid var(--color-border); -} - -.markdown-content th, -.markdown-content td { - padding: 0.75rem; - text-align: left; - border-bottom: 1px solid var(--color-border); -} - -.markdown-content th { - background-color: var(--color-bg-secondary); - font-weight: 600; -} - -.markdown-content blockquote { - border-left: 4px solid var(--color-primary); - background-color: var(--color-bg-secondary); - padding: 1rem 1.5rem; - margin: 1.5rem 0; - border-radius: 0 0.5rem 0.5rem 0; -} - -.markdown-content hr { - border: none; - border-top: 1px solid var(--color-border); - margin: 2rem 0; -} \ No newline at end of file +.rounded-xl { border-radius: 0.75rem; } \ No newline at end of file diff --git a/src/styles/knowledgebase.css b/src/styles/knowledgebase.css new file mode 100644 index 0000000..0757479 --- /dev/null +++ b/src/styles/knowledgebase.css @@ -0,0 +1,661 @@ +/* ========================================================================== + 0) FOUNDATIONS + - Typography, rhythm, utility tokens, base elements + ========================================================================== */ + +:root { + /* Optional: gentle defaults if not already defined upstream */ + --radius-xs: 0.25rem; + --radius-sm: 0.375rem; + --radius-md: 0.5rem; + --radius-lg: 0.75rem; + --radius-xl: 1rem; + + --shadow-xs: 0 1px 2px rgba(0,0,0,0.06); + --shadow-sm: 0 2px 8px rgba(0,0,0,0.06); + --shadow-md: 0 6px 18px rgba(0,0,0,0.10); + --shadow-lg: 0 12px 30px rgba(0,0,0,0.16); + + --ease-quick: 0.2s ease; +} + +/* Base text container for articles */ +:where(.markdown-content) { + max-width: 70ch; + margin: 0 auto; + font-size: 1.125rem; + line-height: 1.8; + color: var(--color-text); +} + +:where(.markdown-content) * { + scroll-margin-top: 100px; +} + +/* ========================================================================== + 1) HEADINGS & TEXT + ========================================================================== */ + +:where(.markdown-content) h1, +:where(.markdown-content) h2, +:where(.markdown-content) h3, +:where(.markdown-content) h4, +:where(.markdown-content) h5, +:where(.markdown-content) h6 { + font-weight: 700; + line-height: 1.25; + color: var(--color-text); + margin: 0; +} + +:where(.markdown-content) h1 { + font-size: 2.5rem; + margin: 3rem 0 1.5rem 0; + border-bottom: 3px solid var(--color-primary); + padding-bottom: 0.5rem; +} + +:where(.markdown-content) h2 { + font-size: 2rem; + margin: 2.5rem 0 1rem 0; + border-bottom: 2px solid var(--color-border); + padding-bottom: 0.375rem; +} + +:where(.markdown-content) h3 { + font-size: 1.5rem; + margin: 2rem 0 0.75rem 0; + color: var(--color-primary); +} + +:where(.markdown-content) h4 { + font-size: 1.25rem; + margin: 1.5rem 0 0.5rem 0; +} + +:where(.markdown-content) h5, +:where(.markdown-content) h6 { + font-size: 1.125rem; + margin: 1rem 0 0.5rem 0; + font-weight: 600; +} + +:where(.markdown-content) p { + margin: 0 0 1.5rem 0; + text-align: justify; + hyphens: auto; +} + +:where(.markdown-content) strong { font-weight: 700; color: var(--color-text); } +:where(.markdown-content) em { font-style: italic; color: var(--color-text-secondary); } + +/* Links with refined hover state */ +:where(.markdown-content) a { + color: var(--color-primary); + text-decoration: underline; + text-decoration-color: transparent; + transition: var(--ease-quick); +} +:where(.markdown-content) a:hover { + text-decoration-color: var(--color-primary); + background-color: var(--color-bg-secondary); + padding: 0.125rem 0.25rem; + border-radius: var(--radius-xs); +} +/* External link indicator */ +:where(.markdown-content) a[href^="http"]:not([href*="localhost"]):not([href*="127.0.0.1"])::after { + content: " ↗"; + font-size: 0.875rem; + color: var(--color-text-secondary); +} + +/* ========================================================================== + 2) LISTS, DEFINITIONS, TABLES, QUOTES + ========================================================================== */ + +:where(.markdown-content) ul, +:where(.markdown-content) ol { + margin: 1.5rem 0; + padding-left: 2rem; +} + +:where(.markdown-content) li { + margin-bottom: 0.75rem; + line-height: 1.2; +} +:where(.markdown-content) li > ul, +:where(.markdown-content) li > ol { + margin: 0.5rem 0; +} + +:where(.markdown-content) dl { margin: 1.5rem 0; } +:where(.markdown-content) dt { + font-weight: 700; + margin: 1rem 0 0.5rem 0; + color: var(--color-primary); +} +:where(.markdown-content) dd { + margin-left: 1.5rem; + margin-bottom: 0.75rem; + padding-left: 1rem; + border-left: 2px solid var(--color-border); +} + +:where(.markdown-content) table { + width: 100%; + border-collapse: collapse; + margin: 1.5rem 0; + background-color: var(--color-bg); + border-radius: var(--radius-md); + overflow: hidden; + border: 1px solid var(--color-border); +} +:where(.markdown-content) th, +:where(.markdown-content) td { + padding: 0.75rem; + text-align: left; + border-bottom: 1px solid var(--color-border); +} +:where(.markdown-content) th { + background-color: var(--color-bg-secondary); + font-weight: 600; +} + +:where(.markdown-content) blockquote { + border-left: 4px solid var(--color-primary); + background-color: var(--color-bg-secondary); + padding: 1rem 1.5rem; + margin: 1.5rem 0; + border-radius: 0 var(--radius-md) var(--radius-md) 0; +} + +:where(.markdown-content) hr { + border: none; + border-top: 1px solid var(--color-border); + margin: 2rem 0; +} + +/* ========================================================================== + 3) CODE & INLINE CODE + ========================================================================== */ + +:where(.markdown-content) pre { + background-color: var(--color-bg-tertiary); + border: 1px solid var(--color-border); + border-radius: 0.75rem; + padding: 1.5rem; + margin: 2rem 0; + overflow-x: auto; + font-size: 0.875rem; + line-height: 1.6; + position: relative; + box-shadow: var(--shadow-sm); + padding-left: 1.5rem; +} + +:where(.markdown-content) pre::before { + content: attr(data-language); + position: absolute; + top: 0.5rem; + left: 0.75rem; + right: auto; + z-index: 1; + display: inline-block; + padding: 0.15rem 0.5rem; + border-radius: var(--radius-sm); + background: var(--color-bg); + border: 1px solid var(--color-border); + color: var(--color-text-secondary); + text-transform: uppercase; + font-weight: 600; + letter-spacing: 0.05em; + font-size: 0.75rem; +} + +:where(.markdown-content) pre[data-language]::before { + top: 0.5rem; + left: 0.75rem; + position: absolute; + z-index: 1; + display: inline-block; + padding: 0.15rem 0.5rem; + border-radius: var(--radius-sm); + background: var(--color-bg); + border: 1px solid var(--color-border); + color: var(--color-text-secondary); + line-height: 1; +} + +:where(.markdown-content) code:not(pre code) { + background-color: var(--color-bg-secondary); + border: 1px solid var(--color-border); + border-radius: var(--radius-sm); + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + font-family: 'SF Mono','Monaco','Menlo','Consolas',monospace; + color: var(--color-text); +} + +/* Language badges (keep if your renderer sets data-language) */ +:where(.markdown-content) pre[data-language="bash"]::before { content: "BASH"; color: #4EAA25; } +:where(.markdown-content) pre[data-language="javascript"]::before { content: "JS"; color: #F7DF1E; } +:where(.markdown-content) pre[data-language="python"]::before { content: "PYTHON"; color: #3776AB; } +:where(.markdown-content) pre[data-language="sql"]::before { content: "SQL"; color: #336791; } +:where(.markdown-content) pre[data-language="yaml"]::before { content: "YAML"; color: #CB171E; } +:where(.markdown-content) pre[data-language="json"]::before { content: "JSON"; color: #000000; } + +/* Keyboard UI hints */ +:where(.markdown-content) kbd { + background-color: var(--color-bg-tertiary); + border: 1px solid var(--color-border); + border-radius: var(--radius-xs); + padding: 0.125rem 0.375rem; + font-size: 0.75rem; + font-family: monospace; + box-shadow: var(--shadow-xs); + margin: 0 0.125rem; +} + +:where(.markdown-content) .copy-btn { + position: absolute; + top: 0.5rem; right: 0.5rem; + display: inline-flex; align-items: center; gap: 0.4rem; + padding: 0.35rem 0.6rem; + border: 1px solid var(--color-border); + background: var(--color-bg); + border-radius: var(--radius-sm); + font-size: 0.75rem; + cursor: pointer; + box-shadow: var(--shadow-sm); + line-height: 1; + z-index: 2; + transition: var(--transition-fast); + color: var(--color-text); +} + +:where(.markdown-content) .copy-btn:hover { + background: var(--color-bg-secondary); +} +:where(.markdown-content) .copy-btn:focus-visible { + outline: 2px solid color-mix(in srgb, var(--color-primary) 60%, transparent); + outline-offset: 2px; +} + +:where(.markdown-content) .copy-btn svg { + width: 14px; height: 14px; +} + +[data-theme="dark"] :where(.markdown-content) .copy-btn { + background: var(--color-bg-secondary); + border-color: color-mix(in srgb, var(--color-border) 80%, transparent); + box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-bg-tertiary) 40%, transparent), var(--shadow-sm); +} + +:where(.markdown-content) pre .copied-pill { + position: absolute; + top: 0.5rem; right: 0.5rem; + padding: 0.35rem 0.6rem; + border-radius: var(--radius-sm); + font-size: 0.75rem; + font-weight: 600; + background: var(--color-primary); + color: #fff; + opacity: 0; transform: translateY(-6px) scale(0.98); + pointer-events: none; + z-index: 2; +} + + +/* Success state driven by [data-copied="true"] on
 */
+:where(.markdown-content) pre[data-copied="true"] {
+  box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-primary) 30%, transparent) inset, var(--shadow-sm);
+}
+:where(.markdown-content) pre[data-copied="true"] .copy-btn { opacity: 0; }
+:where(.markdown-content) pre[data-copied="true"] .copied-pill {
+  opacity: 1; transform: translateY(0) scale(1);
+}
+
+/* Smooth but gentle motion */
+@media (prefers-reduced-motion: no-preference) {
+  :where(.markdown-content) pre,
+  :where(.markdown-content) .copy-btn,
+  :where(.markdown-content) pre .copied-pill {
+    transition: 180ms ease;
+  }
+}
+
+
+
+/* ==========================================================================
+   4) CALLOUTS, STEPS, HIGHLIGHT BOX
+   ========================================================================== */
+
+:where(.markdown-content) .callout {
+  border-left: 4px solid;
+  border-radius: 0.5rem;
+  margin: 2rem 0;
+  padding: 1.25rem 1.5rem;
+  background-color: var(--color-bg-secondary);
+  border-color: var(--color-border);
+  box-shadow: var(--shadow-sm);
+}
+
+:where(.markdown-content) .callout-header {
+  display: flex;
+  align-items: center;
+  gap: 0.75rem;
+  margin-bottom: 0.75rem;
+  font-weight: 600;
+  font-size: 0.9375rem;
+}
+
+:where(.markdown-content) .callout-icon {
+  width: 1.25rem;
+  height: 1.25rem;
+  flex-shrink: 0;
+}
+
+/* Callout variants */
+:where(.markdown-content) .callout-note {
+  border-left-color: var(--color-primary);
+  background-color: color-mix(in srgb, var(--color-primary) 8%, var(--color-bg-secondary));
+}
+:where(.markdown-content) .callout-note .callout-header { color: var(--color-primary); }
+
+:where(.markdown-content) .callout-tip {
+  border-left-color: var(--color-accent);
+  background-color: color-mix(in srgb, var(--color-accent) 8%, var(--color-bg-secondary));
+}
+:where(.markdown-content) .callout-tip .callout-header { color: var(--color-accent); }
+
+:where(.markdown-content) .callout-warning {
+  border-left-color: var(--color-warning);
+  background-color: color-mix(in srgb, var(--color-warning) 8%, var(--color-bg-secondary));
+}
+:where(.markdown-content) .callout-warning .callout-header { color: var(--color-warning); }
+
+:where(.markdown-content) .callout-danger {
+  border-left-color: var(--color-error);
+  background-color: color-mix(in srgb, var(--color-error) 8%, var(--color-bg-secondary));
+}
+:where(.markdown-content) .callout-danger .callout-header { color: var(--color-error); }
+
+/* Highlight feature box */
+:where(.markdown-content) .highlight-box {
+  background: linear-gradient(135deg, var(--color-accent) 0%, var(--color-primary) 100%);
+  color: white;
+  padding: 2rem;
+  border-radius: 1rem;
+  margin: 2rem 0;
+  text-align: center;
+  box-shadow: var(--shadow-md);
+}
+:where(.markdown-content) .highlight-box h3 { margin: 0; color: white; }
+
+/* Steps */
+:where(.markdown-content) .steps { counter-reset: step-counter; margin: 2rem 0; }
+:where(.markdown-content) .step {
+  counter-increment: step-counter;
+  margin: 1.25rem 0;
+  padding: 1.25rem 1.5rem;
+  background-color: var(--color-bg-secondary);
+  border-radius: 0.75rem;
+  border-left: 4px solid var(--color-primary);
+  position: relative;
+}
+:where(.markdown-content) .step::before {
+  content: counter(step-counter);
+  position: absolute;
+  left: -0.75rem;
+  top: 1rem;
+  background-color: var(--color-primary);
+  color: white;
+  width: 1.5rem;
+  height: 1.5rem;
+  border-radius: 50%;
+  display: grid;
+  place-items: center;
+  font-weight: 700;
+  font-size: 0.875rem;
+}
+:where(.markdown-content) .step h4 { margin-top: 0; color: var(--color-primary); }
+
+/* ==========================================================================
+   5) ARTICLE LAYOUT (Header, Meta, Sidebar, Footer)
+   ========================================================================== */
+
+.article-layout {
+  max-width: 1400px;
+  margin: 0 auto;
+  padding: 0 1rem;
+}
+
+/* Header */
+.article-header {
+  background: linear-gradient(135deg, var(--color-bg-secondary) 0%, var(--color-bg-tertiary) 100%);
+  border: 1px solid var(--color-border);
+  border-radius: 1rem;
+  margin-bottom: 2rem;
+  overflow: hidden;
+}
+.article-header-content { padding: 2rem; }
+
+.breadcrumb {
+  display: flex;
+  align-items: center;
+  gap: 0.5rem;
+  margin-bottom: 1rem;
+  font-size: 0.875rem;
+}
+.breadcrumb-link {
+  color: var(--color-primary);
+  text-decoration: none;
+  transition: var(--ease-quick);
+}
+.breadcrumb-link:hover { text-decoration: underline; }
+.breadcrumb-separator { color: var(--color-text-secondary); }
+.breadcrumb-current { color: var(--color-text-secondary); font-weight: 500; }
+
+.article-tags {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.5rem;
+  margin-bottom: 1.5rem;
+}
+.article-tag {
+  padding: 0.25rem 0.75rem;
+  background-color: var(--color-bg);
+  border: 1px solid var(--color-border);
+  border-radius: 1rem;
+  font-size: 0.75rem;
+  font-weight: 500;
+  color: var(--color-text-secondary);
+}
+.article-tag-category {
+  background-color: var(--color-primary);
+  color: white;
+  border-color: var(--color-primary);
+}
+
+.article-title-section { margin-bottom: 2rem; }
+.article-title {
+  font-size: 2.5rem;
+  font-weight: 700;
+  margin: 0 0 1rem 0;
+  color: var(--color-primary);
+  line-height: 1.2;
+}
+.article-icon { margin-right: 1rem; font-size: 2rem; }
+.article-description { font-size: 1.25rem; color: var(--color-text-secondary); margin: 0; line-height: 1.5; }
+
+.article-metadata-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+  gap: 1.5rem;
+  margin-bottom: 2rem;
+  padding: 1.5rem;
+  background-color: var(--color-bg);
+  border-radius: 0.75rem;
+  border: 1px solid var(--color-border);
+}
+.metadata-item { display: flex; flex-direction: column; gap: 0.5rem; }
+.metadata-label {
+  font-size: 0.75rem; font-weight: 600; text-transform: uppercase;
+  letter-spacing: 0.05em; color: var(--color-text-secondary);
+}
+.metadata-value { font-size: 0.9375rem; font-weight: 500; color: var(--color-text); }
+.metadata-badges { display: flex; flex-wrap: wrap; gap: 0.5rem; }
+
+.article-actions { display: flex; gap: 1rem; justify-content: center; }
+
+/* Content wrapper with sidebar */
+.article-content-wrapper {
+  display: grid;
+  grid-template-columns: 280px 1fr;
+  gap: 3rem;
+  align-items: start;
+}
+.article-sidebar {
+  position: sticky;
+  top: 6rem;
+  max-height: calc(100vh - 8rem);
+  overflow-y: auto;
+}
+
+/* Sidebar TOC */
+.sidebar-toc {
+  background-color: var(--color-bg-secondary);
+  border: 1px solid var(--color-border);
+  border-radius: 0.75rem;
+  padding: 1.5rem;
+}
+.toc-title {
+  margin: 0 0 1rem 0;
+  font-size: 1rem;
+  font-weight: 600;
+  color: var(--color-primary);
+}
+.toc-navigation { display: flex; flex-direction: column; gap: 0.25rem; }
+.toc-item {
+  display: block;
+  padding: 0.5rem 0.75rem;
+  color: var(--color-text);
+  text-decoration: none;
+  border-radius: var(--radius-sm);
+  font-size: 0.875rem;
+  line-height: 1.4;
+  transition: var(--ease-quick);
+  border-left: 3px solid transparent;
+}
+.toc-item:hover {
+  background-color: var(--color-bg-tertiary);
+  color: var(--color-primary);
+  border-left-color: var(--color-primary);
+}
+.toc-item.active {
+  background-color: var(--color-primary);
+  color: white;
+  border-left-color: var(--color-accent);
+}
+
+/* Indentation by level (JS sets .toc-level-X) */
+.toc-level-1 { padding-left: 0.75rem; font-weight: 600; }
+.toc-level-2 { padding-left: 1rem; font-weight: 500; }
+.toc-level-3 { padding-left: 1.5rem; }
+.toc-level-4 { padding-left: 2rem; font-size: 0.8125rem; }
+.toc-level-5 { padding-left: 2.5rem; font-size: 0.8125rem; opacity: 0.85; }
+.toc-level-6 { padding-left: 3rem; font-size: 0.8125rem; opacity: 0.8; }
+
+/* Main article column */
+.article-main { min-width: 0; max-width: 95ch; }
+.article-content { margin-bottom: 3rem; }
+
+/* Footer */
+.article-footer {
+  border-top: 2px solid var(--color-border);
+  padding-top: 2rem;
+  margin-top: 3rem;
+}
+.article-footer h3 { margin: 0 0 1.5rem 0; color: var(--color-primary); }
+.footer-actions-grid { display: flex; flex-wrap: wrap; gap: 1rem; margin-bottom: 2rem; }
+.footer-actions-grid .btn { flex: 1; min-width: 200px; }
+
+/* Tool button variants (keep since template uses them) */
+.btn-concept { background-color: var(--color-concept); color: white; border-color: var(--color-concept); }
+.btn-concept:hover { opacity: 0.9; }
+.btn-method { background-color: var(--color-method); color: white; border-color: var(--color-method); }
+.btn-method:hover { opacity: 0.9; }
+
+.related-tools { margin-top: 2rem; padding-top: 2rem; border-top: 1px solid var(--color-border); }
+.related-tools h3 { margin: 0 0 1rem 0; color: var(--color-text); }
+.related-tools-grid {
+  display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1rem;
+}
+.related-tool-card {
+  display: flex; align-items: center; gap: 0.75rem; padding: 1rem;
+  background-color: var(--color-bg-secondary); border: 1px solid var(--color-border);
+  border-radius: 0.5rem; color: var(--color-text); text-decoration: none;
+  transition: var(--ease-quick);
+}
+.related-tool-card:hover {
+  background-color: var(--color-bg-tertiary); border-color: var(--color-primary);
+  transform: translateY(-1px); box-shadow: var(--shadow-sm);
+}
+.tool-icon { font-size: 1.25rem; flex-shrink: 0; }
+.tool-name { font-weight: 500; font-size: 0.9375rem; }
+
+/* ==========================================================================
+   6) RESPONSIVE
+   ========================================================================== */
+
+@media (max-width: 1200px) {
+  .article-content-wrapper { grid-template-columns: 240px 1fr; gap: 2rem; }
+}
+
+@media (max-width: 1024px) {
+  .article-content-wrapper { grid-template-columns: 1fr; gap: 0; }
+  .article-sidebar { position: static; max-height: none; margin-bottom: 2rem; }
+  .sidebar-toc { max-width: 500px; margin: 0 auto; }
+  .article-main { max-width: 100%; }
+}
+
+@media (max-width: 768px) {
+  .article-layout { padding: 0 0.5rem; }
+  .article-header-content { padding: 1.5rem; }
+  .article-title { font-size: 2rem; }
+  .article-description { font-size: 1.125rem; }
+  .article-metadata-grid { grid-template-columns: 1fr; gap: 1rem; padding: 1rem; }
+  .article-actions { flex-direction: column; }
+  .footer-actions-grid { flex-direction: column; }
+  .footer-actions-grid .btn { min-width: auto; }
+
+  :where(.markdown-content) {
+    font-size: 1rem;
+    line-height: 1.65;
+    max-width: 100%;
+  }
+  :where(.markdown-content) pre { padding: 1rem; margin: 1.5rem 0; font-size: 0.8125rem; }
+  :where(.markdown-content) .callout { padding: 1rem; margin: 1.5rem 0; }
+  :where(.markdown-content) .step { padding: 1rem; margin: 1rem 0; }
+  :where(.markdown-content) .step::before { left: -0.5rem; top: 0.75rem; }
+}
+
+@media (max-width: 480px) {
+  .article-title { font-size: 1.75rem; }
+  .article-icon { font-size: 1.5rem; margin-right: 0.75rem; }
+  .breadcrumb { font-size: 0.8125rem; }
+}
+
+/* ==========================================================================
+   7) PRINT
+   ========================================================================== */
+
+@media print {
+  /* Hide interactive chrome not used in print */
+  .article-sidebar { display: none !important; }
+  .article-actions,
+  .article-footer .footer-actions-grid { display: none !important; }
+
+  /* Expand content */
+  .article-main { max-width: 100% !important; }
+}
diff --git a/src/styles/palette.css b/src/styles/palette.css
new file mode 100644
index 0000000..60affb9
--- /dev/null
+++ b/src/styles/palette.css
@@ -0,0 +1,62 @@
+:root {
+  /* Light Theme Colors */
+  --color-bg: #fff;
+  --color-bg-secondary: #f8fafc;
+  --color-bg-tertiary: #e2e8f0;
+  --color-text: #1e293b;
+  --color-text-secondary: #64748b;
+  --color-border: #cbd5e1;
+  --color-primary: #2563eb;
+  --color-primary-hover: #1d4ed8;
+  --color-accent: #059669;
+  --color-accent-hover: #047857;
+  --color-warning: #d97706;
+  --color-error: #dc2626;
+  
+  /* Enhanced card type colors */
+  --color-hosted: #7c3aed;
+  --color-hosted-bg: #f3f0ff;
+  --color-oss: #059669;
+  --color-oss-bg: #ecfdf5;
+  --color-method: #0891b2;
+  --color-method-bg: #f0f9ff;
+  --color-concept: #ea580c;
+  --color-concept-bg: #fff7ed;
+  
+  /* Shadows */
+  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 5%);
+  --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 10%);
+  --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 10%);
+  
+  /* Transitions */
+  --transition-fast: all 0.2s ease;
+  --transition-medium: all 0.3s ease;
+}
+
+[data-theme="dark"] {
+  --color-bg: #0f172a;
+  --color-bg-secondary: #1e293b;
+  --color-bg-tertiary: #334155;
+  --color-text: #f1f5f9;
+  --color-text-secondary: #94a3b8;
+  --color-border: #475569;
+  --color-primary: #3b82f6;
+  --color-primary-hover: #60a5fa;
+  --color-accent: #10b981;
+  --color-accent-hover: #34d399;
+  --color-warning: #f59e0b;
+  --color-error: #f87171;
+  
+  --color-hosted: #a855f7;
+  --color-hosted-bg: #2e1065;
+  --color-oss: #10b981;
+  --color-oss-bg: #064e3b;
+  --color-method: #0891b2;
+  --color-method-bg: #164e63;
+  --color-concept: #f97316;
+  --color-concept-bg: #7c2d12;
+  
+  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 30%);
+  --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 40%);
+  --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 50%);
+}
\ No newline at end of file