Files
pbakaus_impeccable/site/layouts/Doc.astro
T
Paul BakausandGitHub 51d01e3a5f [codex] Add design-aware detector rules (#252)
* Add design-aware detector rules

* Fix design-aware detector noise

* Unify CLI and hook detector ignores

* Fix remaining design-system review findings

* Add detector ignore CLI

* Fix design detector review findings

* Fix design color source false positives

* Fix core test suite registration

* Add design-aware detector docs

* Fix font priority design-system parsing

* Fix color ignore value matching
2026-06-15 21:06:17 -07:00

133 lines
4.9 KiB
Plaintext

---
import Base from './Base.astro';
import DocsSidebar from '../components/DocsSidebar.astro';
import '../styles/sub-pages.css';
import '../styles/docs-kinpaku.css';
import { COMMAND_RELATIONSHIPS } from '../data/sub-pages-data';
import { getCommandDemo } from '../scripts/demos/commands/index.js';
interface Props {
title: string;
description: string;
tagline: string;
slug: string;
category: string;
pageKind?: 'command' | 'reference';
allCommands: { slug: string; category: string }[];
}
const { title, description, tagline, slug, pageKind = 'command' } = Astro.props;
const isReference = pageKind === 'reference';
// Decide hero layout at build time: when a command has a registered demo
// (in site/scripts/demos/commands/<id>.js), the hero is a two-column grid
// with the demo on the left and h1/lede on the right: same editorial
// before/after side-by-side that the old site used. When no demo exists,
// the hero stays single-column.
const hasDemo = !isReference && !!getCommandDemo(slug);
const relationships = COMMAND_RELATIONSHIPS[slug] || {};
---
<Base
title={`${title} | Impeccable`}
description={description}
activeNav="docs"
canonicalPath={`/docs/${slug}`}
bodyClass="sub-page skills-layout-page docs-kinpaku kinpaku-chrome"
>
<div class="skills-layout">
<DocsSidebar activeCommand={isReference ? undefined : slug} activeReference={isReference ? slug : undefined} />
<div class="skills-main">
<div class="skills-detail">
{hasDemo ? (
/* Two-column editorial hero: h1 + lede on the left, demo on
the right. The demo content is populated client-side by the
script below from site/scripts/demos/commands/<id>.js, same
source the homepage uses. */
<div class="docs-hero docs-hero--with-demo">
<header class="sub-page-header">
<h1 class="sub-page-title">{slug}</h1>
{tagline && <p class="sub-page-lede">{tagline}</p>}
</header>
<div class="docs-command-demo" data-command={slug}></div>
</div>
) : (
<header class="sub-page-header">
<h1 class="sub-page-title">{title}</h1>
{tagline && <p class="sub-page-lede">{tagline}</p>}
</header>
)}
<div class="skills-detail-body docs-body prose">
<slot />
</div>
{!isReference && (relationships.leadsTo || relationships.pairs || relationships.combinesWith) && (
<footer class="skills-relationships">
<h2 class="skills-relationships-title">Related commands</h2>
<div class="skills-relationships-list">
{relationships.leadsTo?.map(cmd => (
<a href={`/docs/${cmd}`} class="skills-relationship-chip" data-relation="leads-to">
<span class="skills-relationship-label">leads to</span>
<span class="skills-relationship-name">{cmd}</span>
</a>
))}
{relationships.pairs && (
<a href={`/docs/${relationships.pairs}`} class="skills-relationship-chip" data-relation="pairs">
<span class="skills-relationship-label">pairs with</span>
<span class="skills-relationship-name">{relationships.pairs}</span>
</a>
)}
{relationships.combinesWith?.map(cmd => (
<a href={`/docs/${cmd}`} class="skills-relationship-chip" data-relation="combines">
<span class="skills-relationship-label">combines with</span>
<span class="skills-relationship-name">{cmd}</span>
</a>
))}
</div>
</footer>
)}
</div>
</div>
</div>
<script is:inline>
document.addEventListener('click', (e) => {
const toggle = e.target.closest('.skills-sidebar-toggle');
if (!toggle) return;
const expanded = toggle.getAttribute('aria-expanded') === 'true';
toggle.setAttribute('aria-expanded', String(!expanded));
});
</script>
<script>
import { getCommandDemo } from '../scripts/demos/commands/index.js';
import { renderCommandDemo, initCommandDemo } from '../scripts/demo-renderer.js';
import { initSplitCompare } from '../scripts/effects/split-compare.js';
const slot = document.querySelector('.docs-command-demo');
if (slot) {
const command = slot.dataset.command;
const demo = getCommandDemo(command);
if (demo) {
slot.innerHTML = renderCommandDemo(command);
const split = slot.querySelector('.demo-split-comparison');
if (split) {
initSplitCompare(split, {
defaultPosition: 50,
skewAngle: 0,
minPosition: 10,
maxPosition: 90,
});
}
initCommandDemo(command, slot);
} else {
// No demo registered for this command; leave the layout flush.
slot.remove();
}
}
</script>
</Base>