knowledgebase style
This commit is contained in:
		
							parent
							
								
									9a3122745d
								
							
						
					
					
						commit
						a816c0630f
					
				@ -3,6 +3,8 @@ import Navigation from '../components/Navigation.astro';
 | 
				
			|||||||
import Footer from '../components/Footer.astro';
 | 
					import Footer from '../components/Footer.astro';
 | 
				
			||||||
import '../styles/global.css';
 | 
					import '../styles/global.css';
 | 
				
			||||||
import '../styles/auditTrail.css';
 | 
					import '../styles/auditTrail.css';
 | 
				
			||||||
 | 
					import '../styles/knowledgebase.css';
 | 
				
			||||||
 | 
					import '../styles/palette.css';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface Props {
 | 
					export interface Props {
 | 
				
			||||||
  title: string;
 | 
					  title: string;
 | 
				
			||||||
 | 
				
			|||||||
@ -52,205 +52,430 @@ const currentUrl = Astro.url.href;
 | 
				
			|||||||
---
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<BaseLayout title={entry.data.title} description={entry.data.description}>
 | 
					<BaseLayout title={entry.data.title} description={entry.data.description}>
 | 
				
			||||||
  <article style="max-width: 900px; margin: 0 auto;">
 | 
					  <div class="article-layout">
 | 
				
			||||||
    <header style="margin-bottom: 2rem; padding: 2rem; background: linear-gradient(135deg, var(--color-bg-secondary) 0%, var(--color-bg-tertiary) 100%); border-radius: 1rem; border: 1px solid var(--color-border);">
 | 
					    <!-- Article Header -->
 | 
				
			||||||
      <div style="display: flex; justify-content: space-between; align-items: start; margin-bottom: 1rem;">
 | 
					    <header class="article-header">
 | 
				
			||||||
        <div style="flex: 1;">
 | 
					      <div class="article-header-content">
 | 
				
			||||||
          <h1 style="margin: 0 0 0.5rem 0; color: var(--color-primary);">
 | 
					        <div class="article-meta">
 | 
				
			||||||
            {displayTool?.icon && <span style="margin-right: 0.75rem; font-size: 1.5rem;">{displayTool.icon}</span>}
 | 
					          <nav class="breadcrumb">
 | 
				
			||||||
 | 
					            <a href="/knowledgebase" class="breadcrumb-link">Knowledgebase</a>
 | 
				
			||||||
 | 
					            <span class="breadcrumb-separator">→</span>
 | 
				
			||||||
 | 
					            <span class="breadcrumb-current">{entry.data.title}</span>
 | 
				
			||||||
 | 
					          </nav>
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          <div class="article-tags">
 | 
				
			||||||
 | 
					            {entry.data.categories?.map((cat: string) => (
 | 
				
			||||||
 | 
					              <span class="article-tag article-tag-category">{cat}</span>
 | 
				
			||||||
 | 
					            ))}
 | 
				
			||||||
 | 
					            {entry.data.tags?.map((tag: string) => (
 | 
				
			||||||
 | 
					              <span class="article-tag">{tag}</span>
 | 
				
			||||||
 | 
					            ))}
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        <div class="article-title-section">
 | 
				
			||||||
 | 
					          <h1 class="article-title">
 | 
				
			||||||
 | 
					            {displayTool?.icon && <span class="article-icon">{displayTool.icon}</span>}
 | 
				
			||||||
            {entry.data.title}
 | 
					            {entry.data.title}
 | 
				
			||||||
          </h1>
 | 
					          </h1>
 | 
				
			||||||
          <p style="margin: 0; color: var(--color-text-secondary); font-size: 1.125rem;">
 | 
					          <p class="article-description">{entry.data.description}</p>
 | 
				
			||||||
            {entry.data.description}
 | 
					 | 
				
			||||||
          </p>
 | 
					 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div style="display: flex; flex-direction: column; gap: 0.5rem; align-items: end;">
 | 
					        
 | 
				
			||||||
          <div style="display: flex; gap: 0.5rem; flex-wrap: wrap;">
 | 
					        <div class="article-metadata-grid">
 | 
				
			||||||
            {isStandalone ? (
 | 
					          <div class="metadata-item">
 | 
				
			||||||
              <span class="badge" style="background-color: var(--color-accent); color: white;">Artikel</span>
 | 
					            <span class="metadata-label">Typ</span>
 | 
				
			||||||
            ) : (
 | 
					            <div class="metadata-badges">
 | 
				
			||||||
              <>
 | 
					              {isStandalone ? (
 | 
				
			||||||
                {isConcept && <span class="badge" style="background-color: var(--color-concept); color: white;">Konzept</span>}
 | 
					                <span class="badge badge-accent">Artikel</span>
 | 
				
			||||||
                {isMethod && <span class="badge" style="background-color: var(--color-method); color: white;">Methode</span>}
 | 
					              ) : (
 | 
				
			||||||
                {!isMethod && !isConcept && !isStandalone && <span class="badge" style="background-color: var(--color-primary); color: white;">Software</span>}
 | 
					                <>
 | 
				
			||||||
                {!isMethod && !isConcept && hasValidProjectUrl && <span class="badge badge-primary">CC24-Server</span>}
 | 
					                  {isConcept && <span class="badge badge-concept">Konzept</span>}
 | 
				
			||||||
                {!isMethod && !isConcept && !isStandalone && displayTool?.license !== 'Proprietary' && <span class="badge badge-success">Open Source</span>}
 | 
					                  {isMethod && <span class="badge badge-method">Methode</span>}
 | 
				
			||||||
              </>
 | 
					                  {!isMethod && !isConcept && <span class="badge badge-primary">Software</span>}
 | 
				
			||||||
            )}
 | 
					                  {hasValidProjectUrl && <span class="badge badge-primary">CC24-Server</span>}
 | 
				
			||||||
            <span class="badge badge-error">📖</span>
 | 
					                </>
 | 
				
			||||||
 | 
					              )}
 | 
				
			||||||
 | 
					              <span class="badge badge-error">📖</span>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          {entry.data.difficulty && (
 | 
				
			||||||
 | 
					            <div class="metadata-item">
 | 
				
			||||||
 | 
					              <span class="metadata-label">Schwierigkeit</span>
 | 
				
			||||||
 | 
					              <span class="metadata-value">{entry.data.difficulty}</span>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          )}
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          <div class="metadata-item">
 | 
				
			||||||
 | 
					            <span class="metadata-label">Aktualisiert</span>
 | 
				
			||||||
 | 
					            <span class="metadata-value">{entry.data.last_updated.toLocaleDateString('de-DE')}</span>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          <div class="metadata-item">
 | 
				
			||||||
 | 
					            <span class="metadata-label">Autor</span>
 | 
				
			||||||
 | 
					            <span class="metadata-value">{entry.data.author}</span>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          <div class="metadata-item">
 | 
				
			||||||
 | 
					            <span class="metadata-label">Lesezeit</span>
 | 
				
			||||||
 | 
					            <span class="metadata-value" id="reading-time">~5 min</span>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        <div class="article-actions">
 | 
				
			||||||
          <button 
 | 
					          <button 
 | 
				
			||||||
            id="share-article-btn"
 | 
					            id="share-article-btn"
 | 
				
			||||||
            class="btn btn-secondary btn-sm"
 | 
					            class="btn btn-secondary"
 | 
				
			||||||
            onclick="window.shareCurrentArticle(this)"
 | 
					            onclick="window.shareCurrentArticle(this)"
 | 
				
			||||||
            title="Artikel teilen"
 | 
					            title="Artikel teilen"
 | 
				
			||||||
            style="font-size: 0.8125rem; padding: 0.5rem 0.75rem;"
 | 
					 | 
				
			||||||
          >
 | 
					          >
 | 
				
			||||||
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.375rem;">
 | 
					            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
 | 
				
			||||||
              <circle cx="18" cy="5" r="3"/>
 | 
					              <circle cx="18" cy="5" r="3"/>
 | 
				
			||||||
              <circle cx="6" cy="12" r="3"/>
 | 
					              <circle cx="6" cy="12" r="3"/>
 | 
				
			||||||
              <circle cx="18" cy="19" r="3"/>
 | 
					              <circle cx="18" cy="19" r="3"/>
 | 
				
			||||||
              <line x1="8.59" y1="13.51" x2="15.42" y2="17.49"/>
 | 
					              <line x1="8.59" y1="13.51" x2="15.42" y2="17.49"/>
 | 
				
			||||||
              <line x1="15.41" y1="6.51" x2="8.59" y2="10.49"/>
 | 
					              <line x1="15.41" y1="6.51" x2="8.59" y2="10.49"/>
 | 
				
			||||||
            </svg>
 | 
					            </svg>
 | 
				
			||||||
            Artikel teilen
 | 
					            Teilen
 | 
				
			||||||
          </button>
 | 
					          </button>
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          <a href="/knowledgebase" class="btn btn-secondary">
 | 
				
			||||||
 | 
					            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
 | 
				
			||||||
 | 
					              <polyline points="15,18 9,12 15,6"></polyline>
 | 
				
			||||||
 | 
					            </svg>
 | 
				
			||||||
 | 
					            Zurück
 | 
				
			||||||
 | 
					          </a>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--color-border);">
 | 
					 | 
				
			||||||
        {entry.data.difficulty && (
 | 
					 | 
				
			||||||
          <div>
 | 
					 | 
				
			||||||
            <strong style="font-size: 0.875rem; color: var(--color-text-secondary);">Schwierigkeit</strong>
 | 
					 | 
				
			||||||
            <p style="margin: 0; font-size: 0.9375rem;">{entry.data.difficulty}</p>
 | 
					 | 
				
			||||||
          </div>
 | 
					 | 
				
			||||||
        )}
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        <div>
 | 
					 | 
				
			||||||
          <strong style="font-size: 0.875rem; color: var(--color-text-secondary);">Letztes Update</strong>
 | 
					 | 
				
			||||||
          <p style="margin: 0; font-size: 0.9375rem;">{entry.data.last_updated.toLocaleDateString('de-DE')}</p>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        <div>
 | 
					 | 
				
			||||||
          <strong style="font-size: 0.875rem; color: var(--color-text-secondary);">Autor</strong>
 | 
					 | 
				
			||||||
          <p style="margin: 0; font-size: 0.9375rem;">{entry.data.author}</p>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        <div>
 | 
					 | 
				
			||||||
          <strong style="font-size: 0.875rem; color: var(--color-text-secondary);">Typ</strong>
 | 
					 | 
				
			||||||
          <p style="margin: 0; font-size: 0.9375rem;">
 | 
					 | 
				
			||||||
            {isStandalone ? 'Allgemeiner Artikel' : 
 | 
					 | 
				
			||||||
             isConcept ? 'Konzept-Artikel' : 
 | 
					 | 
				
			||||||
             isMethod ? 'Methoden-Artikel' : 
 | 
					 | 
				
			||||||
             'Software-Artikel'}
 | 
					 | 
				
			||||||
          </p>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        {entry.data.categories && entry.data.categories.length > 0 && (
 | 
					 | 
				
			||||||
          <div style="grid-column: 1 / -1;">
 | 
					 | 
				
			||||||
            <strong style="font-size: 0.875rem; color: var(--color-text-secondary);">Kategorien</strong>
 | 
					 | 
				
			||||||
            <div style="display: flex; flex-wrap: wrap; gap: 0.25rem; margin-top: 0.25rem;">
 | 
					 | 
				
			||||||
              {entry.data.categories.map((cat: string) => (
 | 
					 | 
				
			||||||
                <span class="tag" style="font-size: 0.75rem;">{cat}</span>
 | 
					 | 
				
			||||||
              ))}
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
          </div>
 | 
					 | 
				
			||||||
        )}
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
    </header>
 | 
					    </header>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <nav style="margin-bottom: 2rem; position: relative; z-index: 50;">
 | 
					    <!-- Main Content Area -->
 | 
				
			||||||
      <a href="/knowledgebase" class="btn btn-secondary">
 | 
					    <div class="article-content-wrapper">
 | 
				
			||||||
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.5rem;">
 | 
					      <!-- Sidebar Navigation (will be populated by JS) -->
 | 
				
			||||||
          <polyline points="15,18 9,12 15,6"></polyline>
 | 
					      <aside class="article-sidebar">
 | 
				
			||||||
        </svg>
 | 
					        <!-- TOC will be inserted here by JavaScript -->
 | 
				
			||||||
        Zurück zur Knowledgebase
 | 
					      </aside>
 | 
				
			||||||
      </a>
 | 
					 | 
				
			||||||
    </nav>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <div class="card" style="padding: 2rem;">
 | 
					 | 
				
			||||||
      <div class="kb-content markdown-content" style="line-height: 1.7;">
 | 
					 | 
				
			||||||
        <Content />
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <div class="card" style="margin-top: 2rem; background-color: var(--color-bg-secondary);">
 | 
					 | 
				
			||||||
      <h3 style="margin: 0 0 1rem 0; color: var(--color-text);">
 | 
					 | 
				
			||||||
        {isStandalone ? 'Verwandte Aktionen' : 'Tool-Aktionen'}
 | 
					 | 
				
			||||||
      </h3>
 | 
					 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      <div style="display: flex; gap: 1rem; flex-wrap: wrap;">
 | 
					      <!-- Article Content -->
 | 
				
			||||||
        {isStandalone ? (
 | 
					      <main class="article-main">
 | 
				
			||||||
          <a href="/knowledgebase" class="btn btn-primary">
 | 
					        <article class="article-content">
 | 
				
			||||||
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.5rem;">
 | 
					          <div class="markdown-content">
 | 
				
			||||||
              <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
 | 
					            <Content />
 | 
				
			||||||
              <polyline points="14 2 14 8 20 8"/>
 | 
					          </div>
 | 
				
			||||||
              <line x1="16" y1="13" x2="8" y2="13"/>
 | 
					        </article>
 | 
				
			||||||
              <line x1="16" y1="17" x2="8" y2="17"/>
 | 
					 | 
				
			||||||
              <polyline points="10 9 9 9 8 9"/>
 | 
					 | 
				
			||||||
            </svg>
 | 
					 | 
				
			||||||
            Weitere Artikel
 | 
					 | 
				
			||||||
          </a>
 | 
					 | 
				
			||||||
        ) : (
 | 
					 | 
				
			||||||
          <>
 | 
					 | 
				
			||||||
            {isConcept ? (
 | 
					 | 
				
			||||||
              <a href={displayTool.url} target="_blank" rel="noopener noreferrer" class="btn btn-primary" style="background-color: var(--color-concept); border-color: var(--color-concept);">
 | 
					 | 
				
			||||||
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.5rem;">
 | 
					 | 
				
			||||||
                  <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>
 | 
					 | 
				
			||||||
                  <polyline points="15 3 21 3 21 9"/>
 | 
					 | 
				
			||||||
                  <line x1="10" y1="14" x2="21" y2="3"/>
 | 
					 | 
				
			||||||
                </svg>
 | 
					 | 
				
			||||||
                Mehr erfahren
 | 
					 | 
				
			||||||
              </a>
 | 
					 | 
				
			||||||
            ) : isMethod ? (
 | 
					 | 
				
			||||||
              <a href={displayTool.projectUrl || displayTool.url} target="_blank" rel="noopener noreferrer" class="btn btn-primary" style="background-color: var(--color-method); border-color: var(--color-method);">
 | 
					 | 
				
			||||||
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.5rem;">
 | 
					 | 
				
			||||||
                  <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>
 | 
					 | 
				
			||||||
                  <polyline points="15 3 21 3 21 9"/>
 | 
					 | 
				
			||||||
                  <line x1="10" y1="14" x2="21" y2="3"/>
 | 
					 | 
				
			||||||
                </svg>
 | 
					 | 
				
			||||||
                Zur Methode
 | 
					 | 
				
			||||||
              </a>
 | 
					 | 
				
			||||||
            ) : (
 | 
					 | 
				
			||||||
              <>
 | 
					 | 
				
			||||||
                <a href={displayTool.url} target="_blank" rel="noopener noreferrer" class="btn btn-secondary">
 | 
					 | 
				
			||||||
                  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.5rem;">
 | 
					 | 
				
			||||||
                    <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>
 | 
					 | 
				
			||||||
                    <polyline points="15 3 21 3 21 9"/>
 | 
					 | 
				
			||||||
                    <line x1="10" y1="14" x2="21" y2="3"/>
 | 
					 | 
				
			||||||
                  </svg>
 | 
					 | 
				
			||||||
                  Software-Homepage
 | 
					 | 
				
			||||||
                </a>
 | 
					 | 
				
			||||||
                {hasValidProjectUrl && (
 | 
					 | 
				
			||||||
                  <a href={displayTool.projectUrl} target="_blank" rel="noopener noreferrer" class="btn btn-primary">
 | 
					 | 
				
			||||||
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.5rem;">
 | 
					 | 
				
			||||||
                      <circle cx="12" cy="12" r="10"/>
 | 
					 | 
				
			||||||
                      <path d="M12 16l4-4-4-4"/>
 | 
					 | 
				
			||||||
                      <path d="M8 12h8"/>
 | 
					 | 
				
			||||||
                    </svg>
 | 
					 | 
				
			||||||
                    Zugreifen
 | 
					 | 
				
			||||||
                  </a>
 | 
					 | 
				
			||||||
                )}
 | 
					 | 
				
			||||||
              </>
 | 
					 | 
				
			||||||
            )}
 | 
					 | 
				
			||||||
          </>
 | 
					 | 
				
			||||||
        )}
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        {relatedTools.length > 0 && relatedTools.length > (primaryTool ? 1 : 0) && (
 | 
					        <!-- Article Footer -->
 | 
				
			||||||
          <div style="margin-left: auto;">
 | 
					        <footer class="article-footer">
 | 
				
			||||||
            <details style="position: relative;">
 | 
					          <div class="article-footer-actions">
 | 
				
			||||||
              <summary class="btn btn-secondary" style="cursor: pointer; list-style: none;">
 | 
					            <h3>Tool-Aktionen</h3>
 | 
				
			||||||
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.5rem;">
 | 
					            <div class="footer-actions-grid">
 | 
				
			||||||
                  <path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/>
 | 
					              {isStandalone ? (
 | 
				
			||||||
                  <circle cx="8.5" cy="7" r="4"/>
 | 
					                <a href="/knowledgebase" class="btn btn-primary">
 | 
				
			||||||
                  <line x1="20" y1="8" x2="20" y2="14"/>
 | 
					                  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
 | 
				
			||||||
                  <line x1="23" y1="11" x2="17" y2="11"/>
 | 
					                    <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
 | 
				
			||||||
 | 
					                    <polyline points="14 2 14 8 20 8"/>
 | 
				
			||||||
 | 
					                  </svg>
 | 
				
			||||||
 | 
					                  Weitere Artikel
 | 
				
			||||||
 | 
					                </a>
 | 
				
			||||||
 | 
					              ) : (
 | 
				
			||||||
 | 
					                <>
 | 
				
			||||||
 | 
					                  {isConcept ? (
 | 
				
			||||||
 | 
					                    <a href={displayTool.url} target="_blank" rel="noopener noreferrer" class="btn btn-concept">
 | 
				
			||||||
 | 
					                      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
 | 
				
			||||||
 | 
					                        <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>
 | 
				
			||||||
 | 
					                        <polyline points="15 3 21 3 21 9"/>
 | 
				
			||||||
 | 
					                        <line x1="10" y1="14" x2="21" y2="3"/>
 | 
				
			||||||
 | 
					                      </svg>
 | 
				
			||||||
 | 
					                      Mehr erfahren
 | 
				
			||||||
 | 
					                    </a>
 | 
				
			||||||
 | 
					                  ) : isMethod ? (
 | 
				
			||||||
 | 
					                    <a href={displayTool.projectUrl || displayTool.url} target="_blank" rel="noopener noreferrer" class="btn btn-method">
 | 
				
			||||||
 | 
					                      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
 | 
				
			||||||
 | 
					                        <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>
 | 
				
			||||||
 | 
					                        <polyline points="15 3 21 3 21 9"/>
 | 
				
			||||||
 | 
					                        <line x1="10" y1="14" x2="21" y2="3"/>
 | 
				
			||||||
 | 
					                      </svg>
 | 
				
			||||||
 | 
					                      Zur Methode
 | 
				
			||||||
 | 
					                    </a>
 | 
				
			||||||
 | 
					                  ) : (
 | 
				
			||||||
 | 
					                    <>
 | 
				
			||||||
 | 
					                      <a href={displayTool.url} target="_blank" rel="noopener noreferrer" class="btn btn-secondary">
 | 
				
			||||||
 | 
					                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
 | 
				
			||||||
 | 
					                          <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>
 | 
				
			||||||
 | 
					                          <polyline points="15 3 21 3 21 9"/>
 | 
				
			||||||
 | 
					                          <line x1="10" y1="14" x2="21" y2="3"/>
 | 
				
			||||||
 | 
					                        </svg>
 | 
				
			||||||
 | 
					                        Homepage
 | 
				
			||||||
 | 
					                      </a>
 | 
				
			||||||
 | 
					                      {hasValidProjectUrl && (
 | 
				
			||||||
 | 
					                        <a href={displayTool.projectUrl} target="_blank" rel="noopener noreferrer" class="btn btn-primary">
 | 
				
			||||||
 | 
					                          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
 | 
				
			||||||
 | 
					                            <circle cx="12" cy="12" r="10"/>
 | 
				
			||||||
 | 
					                            <path d="M12 16l4-4-4-4"/>
 | 
				
			||||||
 | 
					                            <path d="M8 12h8"/>
 | 
				
			||||||
 | 
					                          </svg>
 | 
				
			||||||
 | 
					                          Zugreifen
 | 
				
			||||||
 | 
					                        </a>
 | 
				
			||||||
 | 
					                      )}
 | 
				
			||||||
 | 
					                    </>
 | 
				
			||||||
 | 
					                  )}
 | 
				
			||||||
 | 
					                </>
 | 
				
			||||||
 | 
					              )}
 | 
				
			||||||
 | 
					              
 | 
				
			||||||
 | 
					              <a href="/" class="btn btn-secondary">
 | 
				
			||||||
 | 
					                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
 | 
				
			||||||
 | 
					                  <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>
 | 
				
			||||||
 | 
					                  <polyline points="9,22 9,12 15,12 15,22"/>
 | 
				
			||||||
                </svg>
 | 
					                </svg>
 | 
				
			||||||
                Verwandte Tools ({relatedTools.length})
 | 
					                Zur Hauptseite
 | 
				
			||||||
              </summary>
 | 
					              </a>
 | 
				
			||||||
              <div style="position: absolute; top: 100%; left: 0; background: var(--color-bg); border: 1px solid var(--color-border); border-radius: 0.5rem; padding: 1rem; min-width: 200px; z-index: 100; box-shadow: var(--shadow-lg);">
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          {relatedTools.length > 0 && (
 | 
				
			||||||
 | 
					            <div class="related-tools">
 | 
				
			||||||
 | 
					              <h3>Verwandte Tools</h3>
 | 
				
			||||||
 | 
					              <div class="related-tools-grid">
 | 
				
			||||||
                {relatedTools.map((tool: any) => (
 | 
					                {relatedTools.map((tool: any) => (
 | 
				
			||||||
                  <a href={tool.projectUrl || tool.url} target="_blank" rel="noopener noreferrer" 
 | 
					                  <a href={tool.projectUrl || tool.url} target="_blank" rel="noopener noreferrer" class="related-tool-card">
 | 
				
			||||||
                     style="display: block; padding: 0.5rem; border-radius: 0.25rem; text-decoration: none; color: var(--color-text); margin-bottom: 0.25rem;"
 | 
					                    {tool.icon && <span class="tool-icon">{tool.icon}</span>}
 | 
				
			||||||
                     onmouseover="this.style.backgroundColor='var(--color-bg-secondary)'"
 | 
					                    <span class="tool-name">{tool.name}</span>
 | 
				
			||||||
                     onmouseout="this.style.backgroundColor='transparent'">
 | 
					 | 
				
			||||||
                    {tool.icon && <span style="margin-right: 0.5rem;">{tool.icon}</span>}
 | 
					 | 
				
			||||||
                    {tool.name}
 | 
					 | 
				
			||||||
                  </a>
 | 
					                  </a>
 | 
				
			||||||
                ))}
 | 
					                ))}
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            </details>
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          )}
 | 
				
			||||||
        )}
 | 
					        </footer>
 | 
				
			||||||
        
 | 
					      </main>
 | 
				
			||||||
        <a href="/" class="btn btn-secondary">
 | 
					 | 
				
			||||||
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.5rem;">
 | 
					 | 
				
			||||||
            <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>
 | 
					 | 
				
			||||||
            <polyline points="9,22 9,12 15,12 15,22"/>
 | 
					 | 
				
			||||||
          </svg>
 | 
					 | 
				
			||||||
          Zur Hauptseite
 | 
					 | 
				
			||||||
        </a>
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </article>
 | 
					  </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					  /** @template {Element} T
 | 
				
			||||||
 | 
					   *  @param {string} sel
 | 
				
			||||||
 | 
					   *  @param {Document|Element} [root=document]
 | 
				
			||||||
 | 
					   *  @returns {T|null} */
 | 
				
			||||||
 | 
					  const qs = (sel, root = document) => root.querySelector(sel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** @template {Element} T
 | 
				
			||||||
 | 
					   *  @param {string} sel
 | 
				
			||||||
 | 
					   *  @param {Document|Element} [root=document]
 | 
				
			||||||
 | 
					   *  @returns {T[]} */
 | 
				
			||||||
 | 
					  const qsa = (sel, root = document) => Array.from(root.querySelectorAll(sel));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function calculateReadingTime() {
 | 
				
			||||||
 | 
					    /** @type {HTMLElement|null} */
 | 
				
			||||||
 | 
					    const content = qs('.markdown-content');
 | 
				
			||||||
 | 
					    if (!content) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const text = (content.textContent || content.innerText || '').trim();
 | 
				
			||||||
 | 
					    if (!text) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const wordsPerMinute = 200;
 | 
				
			||||||
 | 
					    const words = text.split(/\s+/).length;
 | 
				
			||||||
 | 
					    const readingTime = Math.ceil(words / wordsPerMinute);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const readingTimeElement = document.getElementById('reading-time');
 | 
				
			||||||
 | 
					    if (readingTimeElement) {
 | 
				
			||||||
 | 
					      readingTimeElement.textContent = `~${readingTime} min`;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function generateSidebarTOC() {
 | 
				
			||||||
 | 
					    /** @type {HTMLElement|null} */
 | 
				
			||||||
 | 
					    const article = qs('.markdown-content');
 | 
				
			||||||
 | 
					    /** @type {HTMLElement|null} */
 | 
				
			||||||
 | 
					    const sidebar = qs('.article-sidebar');
 | 
				
			||||||
 | 
					    /** @type {HTMLElement|null} */
 | 
				
			||||||
 | 
					    const main = qs('.article-main');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!article || !sidebar || !main) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** @type {HTMLHeadingElement[]} */
 | 
				
			||||||
 | 
					    const headings = qsa('h1, h2, h3, h4, h5, h6', article);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (headings.length < 2) {
 | 
				
			||||||
 | 
					      sidebar.style.display = 'none';
 | 
				
			||||||
 | 
					      main.style.maxWidth = '100%';
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    headings.forEach((h, i) => {
 | 
				
			||||||
 | 
					      if (!h.id) h.id = `heading-${i}`;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const tocHTML = `
 | 
				
			||||||
 | 
					      <div class="sidebar-toc">
 | 
				
			||||||
 | 
					        <h3 class="toc-title">Inhaltsverzeichnis</h3>
 | 
				
			||||||
 | 
					        <nav class="toc-navigation">
 | 
				
			||||||
 | 
					          ${headings.map((h) => {
 | 
				
			||||||
 | 
					            const level = parseInt(h.tagName.slice(1), 10);
 | 
				
			||||||
 | 
					            const text = (h.textContent || '').trim();
 | 
				
			||||||
 | 
					            const id = h.id;
 | 
				
			||||||
 | 
					            return `
 | 
				
			||||||
 | 
					              <a href="#${id}" class="toc-item toc-level-${level}" data-heading="${id}">
 | 
				
			||||||
 | 
					                ${text}
 | 
				
			||||||
 | 
					              </a>
 | 
				
			||||||
 | 
					            `;
 | 
				
			||||||
 | 
					          }).join('')}
 | 
				
			||||||
 | 
					        </nav>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    `;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sidebar.innerHTML = tocHTML;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** @type {HTMLAnchorElement[]} */
 | 
				
			||||||
 | 
					    const tocItems = qsa('.toc-item', sidebar);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    tocItems.forEach((item) => {
 | 
				
			||||||
 | 
					      item.addEventListener('click', (e) => {
 | 
				
			||||||
 | 
					        e.preventDefault();
 | 
				
			||||||
 | 
					        const href = item.getAttribute('href');
 | 
				
			||||||
 | 
					        if (!href || !href.startsWith('#')) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const target = document.getElementById(href.slice(1));
 | 
				
			||||||
 | 
					        if (target) {
 | 
				
			||||||
 | 
					          target.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' });
 | 
				
			||||||
 | 
					          tocItems.forEach((i) => i.classList.remove('active'));
 | 
				
			||||||
 | 
					          item.classList.add('active');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const updateActiveSection = () => {
 | 
				
			||||||
 | 
					      const scrollY = window.scrollY + 100;
 | 
				
			||||||
 | 
					      let currentId = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      for (let i = 0; i < headings.length; i++) {
 | 
				
			||||||
 | 
					        const h = headings[i];
 | 
				
			||||||
 | 
					        const rect = h.getBoundingClientRect();
 | 
				
			||||||
 | 
					        const absTop = rect.top + window.pageYOffset;
 | 
				
			||||||
 | 
					        if (absTop <= scrollY) currentId = h.id;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (currentId) {
 | 
				
			||||||
 | 
					        tocItems.forEach((i) => i.classList.remove('active'));
 | 
				
			||||||
 | 
					        /** @type {HTMLAnchorElement|null} */
 | 
				
			||||||
 | 
					        const active = qs(`.toc-item[data-heading="${currentId}"]`, sidebar);
 | 
				
			||||||
 | 
					        if (active) active.classList.add('active');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let ticking = false;
 | 
				
			||||||
 | 
					    window.addEventListener('scroll', () => {
 | 
				
			||||||
 | 
					      if (ticking) return;
 | 
				
			||||||
 | 
					      ticking = true;
 | 
				
			||||||
 | 
					      requestAnimationFrame(() => {
 | 
				
			||||||
 | 
					        updateActiveSection();
 | 
				
			||||||
 | 
					        ticking = false;
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    updateActiveSection();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function enhanceCodeCopy() {
 | 
				
			||||||
 | 
					    /** @type {HTMLPreElement[]} */
 | 
				
			||||||
 | 
					    const pres = qsa('.markdown-content pre');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pres.forEach((pre) => {
 | 
				
			||||||
 | 
					      if (pre.dataset.copyEnhanced === 'true') return;
 | 
				
			||||||
 | 
					      pre.dataset.copyEnhanced = 'true';
 | 
				
			||||||
 | 
					      pre.style.position ||= 'relative';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Try to find an existing copy button we can reuse
 | 
				
			||||||
 | 
					      let btn =
 | 
				
			||||||
 | 
					        pre.querySelector('.copy-btn') ||                         // our class
 | 
				
			||||||
 | 
					        pre.querySelector('.btn-copy, .copy-button, .code-copy, .copy-code, button[aria-label*="copy" i]');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // If there is an "old" button that is NOT ours, prefer to reuse it by giving it our class.
 | 
				
			||||||
 | 
					      if (btn && !btn.classList.contains('copy-btn')) {
 | 
				
			||||||
 | 
					        btn.classList.add('copy-btn');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // If no button at all, create one
 | 
				
			||||||
 | 
					      if (!btn) {
 | 
				
			||||||
 | 
					        btn = document.createElement('button');
 | 
				
			||||||
 | 
					        btn.type = 'button';
 | 
				
			||||||
 | 
					        btn.className = 'copy-btn';
 | 
				
			||||||
 | 
					        btn.setAttribute('aria-label', 'Code kopieren');
 | 
				
			||||||
 | 
					        btn.innerHTML = `
 | 
				
			||||||
 | 
					          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
 | 
				
			||||||
 | 
					               aria-hidden="true"><rect x="9" y="9" width="13" height="13" rx="2"/>
 | 
				
			||||||
 | 
					               <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
 | 
				
			||||||
 | 
					          <span>Copy</span>
 | 
				
			||||||
 | 
					        `;
 | 
				
			||||||
 | 
					        pre.appendChild(btn);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // If there is a SECOND old button lingering (top-left in your case), hide it
 | 
				
			||||||
 | 
					      const possibleOldButtons = pre.querySelectorAll(
 | 
				
			||||||
 | 
					        '.btn-copy, .copy-button, .code-copy, .copy-code, button[aria-label*="copy" i]'
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      possibleOldButtons.forEach((b) => {
 | 
				
			||||||
 | 
					        if (b !== btn) b.style.display = 'none';
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Success pill
 | 
				
			||||||
 | 
					      if (!pre.querySelector('.copied-pill')) {
 | 
				
			||||||
 | 
					        const pill = document.createElement('div');
 | 
				
			||||||
 | 
					        pill.className = 'copied-pill';
 | 
				
			||||||
 | 
					        pill.textContent = '✓ Kopiert';
 | 
				
			||||||
 | 
					        pre.appendChild(pill);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Screen reader live region
 | 
				
			||||||
 | 
					      if (!pre.querySelector('.sr-live')) {
 | 
				
			||||||
 | 
					        const live = document.createElement('div');
 | 
				
			||||||
 | 
					        live.className = 'sr-live';
 | 
				
			||||||
 | 
					        live.setAttribute('aria-live', 'polite');
 | 
				
			||||||
 | 
					        Object.assign(live.style, {
 | 
				
			||||||
 | 
					          position: 'absolute', width: '1px', height: '1px', padding: '0', margin: '-1px',
 | 
				
			||||||
 | 
					          overflow: 'hidden', clip: 'rect(0,0,0,0)', border: '0'
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        pre.appendChild(live);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      btn.addEventListener('click', async () => {
 | 
				
			||||||
 | 
					        const code = pre.querySelector('code');
 | 
				
			||||||
 | 
					        const text = code ? code.innerText : pre.innerText;
 | 
				
			||||||
 | 
					        const live = pre.querySelector('.sr-live');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const copyText = async (t) => {
 | 
				
			||||||
 | 
					          try {
 | 
				
			||||||
 | 
					            await navigator.clipboard.writeText(t);
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					          } catch {
 | 
				
			||||||
 | 
					            const ta = document.createElement('textarea');
 | 
				
			||||||
 | 
					            ta.value = t;
 | 
				
			||||||
 | 
					            ta.style.position = 'fixed';
 | 
				
			||||||
 | 
					            ta.style.top = '-1000px';
 | 
				
			||||||
 | 
					            document.body.appendChild(ta);
 | 
				
			||||||
 | 
					            ta.select();
 | 
				
			||||||
 | 
					            const ok = document.execCommand('copy');
 | 
				
			||||||
 | 
					            document.body.removeChild(ta);
 | 
				
			||||||
 | 
					            return ok;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const ok = await copyText(text);
 | 
				
			||||||
 | 
					        pre.dataset.copied = ok ? 'true' : 'false';
 | 
				
			||||||
 | 
					        if (live) live.textContent = ok ? 'Code in die Zwischenablage kopiert' : 'Kopieren fehlgeschlagen';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        window.setTimeout(() => { pre.dataset.copied = 'false'; }, 1200);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // keep your existing DOMContentLoaded; just ensure this is called
 | 
				
			||||||
 | 
					  document.addEventListener('DOMContentLoaded', () => {
 | 
				
			||||||
 | 
					    // existing:
 | 
				
			||||||
 | 
					    calculateReadingTime();
 | 
				
			||||||
 | 
					    generateSidebarTOC();
 | 
				
			||||||
 | 
					    // new/updated:
 | 
				
			||||||
 | 
					    enhanceCodeCopy();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</BaseLayout>
 | 
					</BaseLayout>
 | 
				
			||||||
@ -14,72 +14,7 @@
 | 
				
			|||||||
  padding: 0;
 | 
					  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
 | 
					   3. BASE HTML ELEMENTS
 | 
				
			||||||
@ -3746,133 +3681,30 @@ footer {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
/* ===================================================================
 | 
					 | 
				
			||||||
   MIGRATION UTILITIES - Additional classes for inline style migration
 | 
					 | 
				
			||||||
   ================================================================= */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Alignment utilities */
 | 
					 | 
				
			||||||
.align-middle { vertical-align: middle; }
 | 
					.align-middle { vertical-align: middle; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Font style utilities */
 | 
					 | 
				
			||||||
.italic { font-style: italic; }
 | 
					.italic { font-style: italic; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Border width utilities */
 | 
					 | 
				
			||||||
.border-2 { border-width: 2px; }
 | 
					.border-2 { border-width: 2px; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Border color utilities */
 | 
					 | 
				
			||||||
.border-accent { border-color: var(--color-accent); }
 | 
					.border-accent { border-color: var(--color-accent); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Card variants for complex backgrounds */
 | 
					 | 
				
			||||||
.card-warning {
 | 
					.card-warning {
 | 
				
			||||||
  background: linear-gradient(135deg, var(--color-warning) 0%, var(--color-accent) 100%);
 | 
					  background: linear-gradient(135deg, var(--color-warning) 0%, var(--color-accent) 100%);
 | 
				
			||||||
  color: white;
 | 
					  color: white;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Header variants for complex gradient combinations */
 | 
					 | 
				
			||||||
.header-primary {
 | 
					.header-primary {
 | 
				
			||||||
  background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-accent) 100%);
 | 
					  background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-accent) 100%);
 | 
				
			||||||
  color: white;
 | 
					  color: white;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Ensure we have all text size variants */
 | 
					 | 
				
			||||||
.text-2xl { font-size: 1.5rem; }
 | 
					.text-2xl { font-size: 1.5rem; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Additional spacing utilities that might be missing */
 | 
					 | 
				
			||||||
.py-8 { padding-top: 2rem; padding-bottom: 2rem; }
 | 
					.py-8 { padding-top: 2rem; padding-bottom: 2rem; }
 | 
				
			||||||
.px-4 { padding-left: 1rem; padding-right: 1rem; }
 | 
					.px-4 { padding-left: 1rem; padding-right: 1rem; }
 | 
				
			||||||
.my-6 { margin-top: 1.5rem; margin-bottom: 1.5rem; }
 | 
					.my-6 { margin-top: 1.5rem; margin-bottom: 1.5rem; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Flex utilities that might be missing */
 | 
					 | 
				
			||||||
.flex-1 { flex: 1; }
 | 
					.flex-1 { flex: 1; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Additional rounded variants */
 | 
					.rounded-xl { border-radius: 0.75rem; }
 | 
				
			||||||
.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;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										661
									
								
								src/styles/knowledgebase.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										661
									
								
								src/styles/knowledgebase.css
									
									
									
									
									
										Normal file
									
								
							@ -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 <pre> */
 | 
				
			||||||
 | 
					: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; }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										62
									
								
								src/styles/palette.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/styles/palette.css
									
									
									
									
									
										Normal file
									
								
							@ -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%);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user