1---
2import { getCollection } from 'astro:content';
3import Base from '../../layouts/Base.astro';
4import '../../styles/sub-pages.css';
5import {
6 SKILL_CATEGORIES,
7 CATEGORY_ORDER,
8 CATEGORY_LABELS,
9 CATEGORY_DESCRIPTIONS,
10} from '../../data/sub-pages-data';
11
12const entries = await getCollection('skills');
13
14const grouped: Record<string, typeof entries> = {};
15for (const cat of CATEGORY_ORDER) {
16 grouped[cat] = entries
17 .filter(e => SKILL_CATEGORIES[e.id] === cat)
18 .sort((a, b) => a.id.localeCompare(b.id));
19}
20
21const allCommands = entries.map(e => ({
22 slug: e.id,
23 category: SKILL_CATEGORIES[e.id] || 'system',
24}));
25
26const sidebarGroups: Record<string, { slug: string }[]> = {};
27for (const cat of CATEGORY_ORDER) {
28 sidebarGroups[cat] = allCommands
29 .filter(c => c.category === cat)
30 .sort((a, b) => a.slug.localeCompare(b.slug));
31}
32---
33
34<Base
35 title="Docs | Impeccable"
36 description="23 commands for design fluency. Browse the full reference for every /impeccable sub-command."
37 activeNav="docs"
38 canonicalPath="/docs"
39 bodyClass="sub-page skills-layout-page"
40>
41 <div class="skills-layout">
42 <aside class="skills-sidebar" aria-label="Commands">
43 <button class="skills-sidebar-toggle" type="button" aria-expanded="false" aria-controls="skills-sidebar-inner">
44 <span class="skills-sidebar-toggle-label">Commands</span>
45 <svg class="skills-sidebar-toggle-chevron" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg>
46 </button>
47 <div class="skills-sidebar-inner" id="skills-sidebar-inner">
48 <p class="skills-sidebar-label">Commands</p>
49 {CATEGORY_ORDER.map(cat => (
50 <div class="skills-sidebar-group">
51 <span class="skills-sidebar-category">{CATEGORY_LABELS[cat]}</span>
52 <ul class="skills-sidebar-list">
53 {sidebarGroups[cat].map(cmd => (
54 <li>
55 <a href={`/docs/${cmd.slug}`}>
56 <span>{cmd.slug}</span>
57 </a>
58 </li>
59 ))}
60 </ul>
61 </div>
62 ))}
63 </div>
64 </aside>
65
66 <div class="skills-main">
67 <div class="docs-index">
68 <header class="docs-index-header">
69 <h1 class="sub-page-title">Commands</h1>
70 <p class="sub-page-lede">23 commands for design fluency. One skill, six categories, from shaping a new feature to hardening it for production.</p>
71 </header>
72
73 {CATEGORY_ORDER.map(cat => (
74 <section class="docs-category-section" id={`category-${cat}`}>
75 <header class="docs-category-header">
76 <h2 class="docs-category-title">{CATEGORY_LABELS[cat]}</h2>
77 <p class="docs-category-desc">{CATEGORY_DESCRIPTIONS[cat]}</p>
78 </header>
79 <div class="docs-card-grid">
80 {grouped[cat].map(entry => (
81 <a href={`/docs/${entry.id}`} class="docs-command-card">
82 <h3 class="docs-command-name">/impeccable {entry.id}</h3>
83 <p class="docs-command-tagline">{entry.data.tagline}</p>
84 </a>
85 ))}
86 </div>
87 </section>
88 ))}
89 </div>
90 </div>
91 </div>
92
93 <script is:inline>
94 document.addEventListener('click', (e) => {
95 const toggle = e.target.closest('.skills-sidebar-toggle');
96 if (!toggle) return;
97 const expanded = toggle.getAttribute('aria-expanded') === 'true';
98 toggle.setAttribute('aria-expanded', String(!expanded));
99 });
100 </script>
101
102 <style>
103 .docs-index { padding: 2rem 0 4rem; }
104 .docs-index-header { margin-bottom: 3rem; }
105 .docs-category-section { margin-bottom: 2.5rem; }
106 .docs-category-header { margin-bottom: 1rem; }
107 .docs-category-title { font-family: var(--font-display); font-size: 1.5rem; margin: 0 0 0.25rem; }
108 .docs-category-desc { color: var(--color-ash); font-size: 0.9375rem; margin: 0; }
109 .docs-card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 1rem; }
110 .docs-command-card {
111 display: block; padding: 1.25rem; border-radius: 8px;
112 border: 1px solid var(--color-mist); text-decoration: none; color: inherit;
113 transition: border-color 0.15s ease, box-shadow 0.15s ease;
114 }
115 .docs-command-card:hover { border-color: var(--color-accent); box-shadow: 0 2px 8px rgba(0,0,0,0.04); }
116 .docs-command-name { font-family: var(--font-mono); font-size: 0.9375rem; font-weight: 600; margin: 0 0 0.375rem; }
117 .docs-command-tagline { font-size: 0.8125rem; color: var(--color-ash); margin: 0; line-height: 1.5; }
118 </style>
119</Base>