mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-22 02:56:52 +03:00
Copy buttons on code blocks + merge Skills and Tutorials under Docs
Two small-to-medium improvements bundled together.
1. Copy buttons on every rendered code block.
- render-markdown.js: wrap each fenced code block in a .code-block-wrap
container and emit a <button class="code-block-copy" data-copy="...">
alongside it. Button text is set via CSS ::before content so the
'Copy' / 'Copied' label is a single toggle class (.is-copied).
- render-page.js: 12-line inline script at the end of the body wires
a delegated click handler that calls navigator.clipboard.writeText
and flips .is-copied for 1.5s.
- sub-pages.css: button styles matching the dark terminal palette,
hidden until you hover the code block, accent-colored success state.
2. Merge Skills and Tutorials under a single Docs nav item.
- Rename the Skills nav link to 'Docs' in every header (partial +
4 hand-authored pages). Drop the separate Tutorials nav item; it
now lives inside Docs. Anti-patterns stays as its own top-level.
- scripts/build-sub-pages.js: replace renderSkillsSidebar and
renderTutorialsSidebar with a unified renderDocsSidebar that shows
every skill category followed by a Tutorials group. Takes a
current descriptor of shape { kind: 'skill'|'tutorial', id|slug }
so both skill detail and tutorial detail pages can mark the active
row. activeNav on every /skills/* and /tutorials/* page is now
'docs'; the shared site header's data-nav matches.
Verified: /skills/polish and /tutorials/getting-started both render
with the unified Docs sidebar (all 21 skills grouped by category +
both tutorials as a final group). The Docs nav item is aria-current
on both. Copy buttons appear on every fenced code block and toggle
to 'Copied' when clicked.
This commit is contained in:
@@ -1312,8 +1312,16 @@ main#main {
|
||||
color: var(--color-ink);
|
||||
}
|
||||
|
||||
.prose .code-block {
|
||||
.prose .code-block-wrap {
|
||||
position: relative;
|
||||
margin: 1.25em 0;
|
||||
}
|
||||
|
||||
.prose .code-block-wrap .code-block {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.prose .code-block {
|
||||
padding: var(--spacing-md);
|
||||
background: oklch(12% 0.005 350);
|
||||
color: oklch(92% 0.005 350);
|
||||
@@ -1325,6 +1333,55 @@ main#main {
|
||||
border: 1px solid oklch(20% 0.005 350);
|
||||
}
|
||||
|
||||
.code-block-copy {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
padding: 4px 10px;
|
||||
background: oklch(20% 0.005 350);
|
||||
border: 1px solid oklch(30% 0.005 350);
|
||||
color: oklch(78% 0.005 350);
|
||||
border-radius: 4px;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.6875rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
transition:
|
||||
opacity var(--duration-fast) var(--ease-out),
|
||||
background var(--duration-fast) var(--ease-out),
|
||||
color var(--duration-fast) var(--ease-out),
|
||||
border-color var(--duration-fast) var(--ease-out);
|
||||
}
|
||||
|
||||
.code-block-wrap:hover .code-block-copy,
|
||||
.code-block-copy:focus-visible {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.code-block-copy::before {
|
||||
content: "Copy";
|
||||
}
|
||||
|
||||
.code-block-copy:hover {
|
||||
background: oklch(30% 0.005 350);
|
||||
color: oklch(92% 0.005 350);
|
||||
border-color: oklch(40% 0.005 350);
|
||||
}
|
||||
|
||||
.code-block-copy.is-copied {
|
||||
opacity: 1;
|
||||
background: var(--color-accent);
|
||||
color: var(--color-paper);
|
||||
border-color: var(--color-accent);
|
||||
}
|
||||
|
||||
.code-block-copy.is-copied::before {
|
||||
content: "Copied";
|
||||
}
|
||||
|
||||
.prose .code-block code {
|
||||
background: transparent;
|
||||
border: none;
|
||||
|
||||
Reference in New Issue
Block a user