mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-15 07:36:50 +03:00
Site polish: de-warm the palette, refine chrome, clean up /designing (#176)
* fix(home): command-wheel contrast, slop copy, line-length Address P1/P2/P3 findings from /impeccable critique of the homepage: - Command wheel (The Language): off-center command names floored at ~1.43:1 contrast were illegible (WCAG 1.4.3 fail) and hid most of the 23-command vocabulary. Raise the fisheye opacity floor 0.25 -> 0.62, MIN_SCALE 0.35 -> 0.52, and lift the base color from --ks-text-muted to --ks-text. Off-center now measures >=4.59:1; full list stays scannable while gold + size + weight still carry focus. - Slop section copy: rewrite all 7 discipline cards off the uniform "No X. No Y. No Z." triad into varied cadence with positives, and lead the section with what Impeccable does instead of the "Skills can't..." negation pivot. Drops the en-dash joiners too. - Line length: cap .downloads-rebuild-note (was unbounded, ~102ch) and tighten the homepage .section-lead 68ch -> 62ch (rendered ~86 actual chars/line). The diagonal plinth ramp on the slop grid is intentionally kept per design preference. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(home): de-warm and brighten the text ramp Warmth now lives only in the gold accents and surfaces, not the type. Body, headings, and the secondary tiers read crisp on lacquer instead of mushing into the warm floor: - --ks-champagne 84% .035 82 -> 91% .006 90 (headings/strong, now neutral; token name kept for compatibility) - --ks-text 81% .03 82 -> 88% .008 90 (body) - --ks-text-muted / -faint / -mute-deep lifted and de-warmed to match DESIGN.md frontmatter + prose synced to the new values. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(home): outlined testimonials + cleaner hero boundary Testimonials: - Flatten the double container: drop the t-plinth shelf wrapper (markup + CSS); the marquee sits directly in the section and carries its inset. - Outlined cards: no fill, 1px solid neutral border (oklch .64 0 0 / .22), no dead drop-shadow. Removes the mushy gray-on-gray blend and the stacked dotted-divider + gold-hairline chrome. - Section has no background of its own (rides the body lacquer gradient) and no top padding, so cards sit right under the hero divider. Hero: - Drop the bottom fade and the top nav scrim; the kintsugi art runs at full strength. A 1px neutral border-bottom (matching the card border) marks the testimonials boundary instead of a wash. - "How it works" is the kit ghost link (white), not an outlined button. Foundation/slop cards: lift the surface 9% -> 15% so they read as raised specimen cards instead of vanishing into the ground. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(live): quieter, more refined picker chrome Gold is reserved for the brand mark and the active control instead of ringing every container. Applied to the homepage demo, /live-mode, and the real injected picker (skill/scripts/live-browser.js, rebuilt into the harness dirs): - Container: neutral 1px hairline + tight neutral shadow (was a 1.5px gold border + gold halo ring); radius 10px -> 8px. - Active toggle: crisp graphite pill with gold text (was a murky kinpaku-dim wash). - Internal control borders (action pill / input / count): neutral hairline (was a warm gold rule); configure-row controls share one 30px baseline. - Pick outline: crisp 1.5px line, no soft gold glow ring; tighter radius. - Demo browser chrome: small uniform neutral dots, neutral URL pill, slimmer bar; frame edge neutral hairline + tighter shadow that registers on dark. DESIGN.md "Live Mode Picker" spec + "Picker Is Brand Rule" updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(design): neutral default hairline (--ks-rule) The default border/divider token was a warm gold hairline, used ~200x as the site-wide default border — so every small label, pill, counter, card, and divider carried warmth. Redefine it neutral so borders read clean; gold stays where it signals. - --ks-rule oklch(58% 0.065 82 / 0.32) -> oklch(78% 0 0 / 0.16) - --ks-rule-strong (active/focus/brand borders) unchanged, still gold - GitHub star pill: explicit near-white border (oklch 92% 0 0 / 0.18) - DESIGN.md hairline mirror + prose synced Verified across home, /design-system, and /docs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(home): testimonials separator + visible star-pill border - Move the dotted accent to the bottom of the testimonials (neutral dots) as a deliberate separator into the slop section; drop the oversized bottom padding to 1em so cards sit near the separator. - Star-counter pill: solid oklch(80% 0 0) border. The previous near-white at 0.32 alpha rendered as faded mid-gray on the near-black pill; a solid light border reads as the intended white hairline. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(design): neutralize body text (--ks-text) Drop the last bit of warm chroma from the body text token; it still read slightly warm at 0.008 chroma. --ks-text oklch(88% 0.008 90) -> oklch(88% 0 0) (pure neutral) DESIGN.md mirror + prose synced. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(design): neutral text everywhere Zero the residual warm chroma across the rest of the text ramp so no text tier carries warmth (warmth lives only in gold accents + surfaces). - --ks-champagne 91% .006 90 -> 91% 0 0 - --ks-text-muted 72% .01 90 -> 72% 0 0 - --ks-text-faint 62% .008 90 -> 62% 0 0 - --ks-text-mute-deep 52% .008 90 -> 52% 0 0 (--ks-text was already neutralized.) DESIGN.md mirror + prose synced. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(home): crisp, neutral Desloppification section - Foundation card background: oklch(15% .004 95) -> oklch(15% 0 0) (neutral graphite) so cards read crisp, not warm. - Plinth hatch: kinpaku gold -> neutral (oklch 80% 0 0 / .07) on a neutral base; the gold hatch was washing the section champagne. - Remove the plinth bottom mask-fade so the pedestals end on a clean edge. Gold stays only on the card icons as the accent. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(home): drop the homepage warm-token overrides The homepage redefined --ks-rule, --ks-rule-strong, and --ks-muted to warm values locally (an old "busier surfaces" tweak), so homepage borders and secondary text stayed champagne even after the global de-warm. That's why the Desloppification cards still read warm. - Remove the --ks-rule / --ks-rule-strong overrides; inherit the global tokens (neutral default border, gold strong/active border). - Alias --ks-muted to the global --ks-text-muted (no divergent value); legacy code still reads the --ks-muted name. Result: all homepage borders + secondary text are neutral; gold stays on accents (icons, mark, CTAs, active/focus). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(design): canonical code tokens (inline + block) Code styling was all over the place: homepage inline code was gold-on-gold, the slop CLI was a one-off gold-on-raised-lacquer, downloads used a separate --card-cmd-* set, docs used yet another. Add one shared token set and point the canonical surfaces at it. New :root tokens: - --ks-code-fg / --ks-code-bg / --ks-code-radius (inline: neutral chip) - --ks-code-block-fg / -bg / -border / -radius (block/CLI: lacquer terminal) - --ks-code-cmd (code that's a command link) Migrated: homepage inline code (was gold -> neutral chip), slop-teaser-cli (the "weird color" -> neutral terminal), downloads-cmd, and the docs inline + fenced-block rules (now the token source of truth; block text also neutralized). Remaining pages (designing, changelog/faq, detector, case studies) swept next. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(design): sweep remaining pages onto code tokens Point the rest of the site's code rules at the shared code tokens so inline code and blocks are consistent everywhere: - Inline code (designing, changelog, faq): gold -> neutral chip (--ks-code-fg / --ks-code-bg). - Detector rule pills + table cells: code text -> --ks-code-fg. - Neon-mirai case-study code block -> --ks-code-block-* tokens. Command tags (the gold /command pills: spread-flow-cmd, docs-flow-cmd, designing-phase-cmd, why-ci-cmd, etc.) are intentionally left as their own interactive category, not generic code. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(home): polish "The Language" section - Command tags (/polish, /adapt): gold command text on a neutral code chip (--ks-code-cmd / --ks-code-bg), dropping the muddy gold-tint border. - Commands panel kept as the solid oklch(0.17 0 0) panel (no border). - Demo preview cleaned up to a single framed split: strip the grid ::before, the gold-grid/radial-glow container background, and the inner drop-shadow; before-half inherits the panel, after-half is near-black, with one thin neutral border on the demo itself (caption sits outside it). - Periodic table: crisp flat neutral graphite tiles. Removed the JS-inlined category bg (var(--cat-*-bg)) + 1.5px colored border + hover drop-shadow, the gold-leaf ::before texture, the ::after accent line, the inset box-shadow, and the gold hover glow. Now a 1px neutral border, white symbols, readable neutral names, and a clean neutral-border hover with no shadow. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(design): roomier inline-code padding Inline code chips were tight top/bottom (the homepage one was only 0.05em). Add a --ks-code-pad token (0.3em 0.5em) and point every inline-code rule at it so the chips have consistent breathing room. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(home): drop non-steering commands from the command palette impeccable, init, extract, document, and live are setup/management commands, not steering verbs. Filter them out of the palette (fisheye + mobile carousel) via a shared PALETTE_EXCLUDED set. They stay in the periodic table, which is rendered separately by framework-viz.js. Palette: 23 -> 18 commands. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(designing): flatten the pre-ship nested box The pre-ship cards were a box-in-box: a legacy .designing-polish-grid panel (cream bg + L/R/B border + padding, from docs-visuals.css) wrapping cards that already have their own border + fill. Override the grid to a plain transparent layout so the three cards are the only surface. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(designing): remove step counter + flatten design-debt boxes - Drop the cryptic "03 · 04" pre-ship step counter (.designing-polish-band-meta) and tighten the band to a single bottom hairline. - Design-debt: flatten the box-in-box (bento plinth > tile > stage). The .designing-maintain-stage no longer adds its own border + fill; the demo sits directly in the bento tile. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(designing): neutralize code/terminal/panel surfaces The terminal block, surface-cmd chips, command pills, live-frame, and other dark panels used a slightly-warm dark fill (oklch 1X% 0.006 95). Drop the warm chroma so they read neutral like the rest of the de-warmed site; the page ground + deep surfaces stay lacquer-warm. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(designing): neutralize inline code + live-mock picker chrome - Inline code: the phase-sub and avoid-title code were still gold; point them at --ks-code-fg so all inline code reads neutral (gold stays only on command *links*). - docs-viz-live mock: bring the duplicated picker chrome in line with the refactored neutral treatment — neutral 1px container borders (no gold halo), neutral active "Pick" pill (was the kinpaku-dim wash), crisp pick outline (no glow), tighter radii. - CTAs (SEND ME ONE, Accept): pale-cream kinpaku-pale -> solid kinpaku gold. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(designing): flatten lanes + avoid sections - Brand/Product lane mock cards: drop the inner border+fill box; the mock sits directly in the bento tile, separated by a top hairline (no plinth>tile>mock nesting). - "What to avoid" list: flatten the boxed list cards into a clean divided list (hairline separators, no per-item border/fill). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(designing): clean up the Brand/Product lanes - Drop the bento plinth (0.17 fill + 8px gutter that drew the weird gutter "borders") and the tile fill; the two lanes sit on the page split by a single center hairline. - Brand mock title used the pinstripe display face at 1.6rem (reads broken at that size, the "champagne text"); switch it to the clean body face so it matches the product mock title. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(site): update GitHub star count to 31k 31,188 stars as of now; header pill + aria-label were stale at 30k. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Add Neo Kinpaku light mode across the site. Wire theme persistence and a header toggle, then layer light-mode overrides for docs viz contrast, command demos, live-mode pathway cards, and the designing/home surfaces. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(designing): replace em dashes flagged by prose validator Brand/Product lane copy used em dashes ("the deliverable —", "the task —"); swap for colons per STYLE.md so the Cloudflare build's validateProse passes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(designing): address Cursor bugbot nits - Fold the duplicate .designing-avoid { gap: 0 } override into the original rule (the gap: 18px was dead code). - Drop the leftover el.style.boxShadow = 'none' in the periodic-tile deactivate handler — activate no longer sets a box-shadow, so this only left a dead inline none that could suppress a future CSS shadow. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
Cursor
parent
63074dd362
commit
c8e973b324
@@ -46,9 +46,11 @@
|
||||
mist: 'oklch(90% 0.008 82 / 0.6)', // light hairline
|
||||
white: 'oklch(99% 0 0)',
|
||||
};
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css.
|
||||
// Quiet neutral elevation: no gold halo ring (gold is reserved for the brand
|
||||
// mark and the active control, not the container outline).
|
||||
const PICKER_SHADOW =
|
||||
'0 0 0 1px oklch(78% 0.12 82 / 0.18), 0 10px 28px oklch(0% 0 0 / 0.28)';
|
||||
'0 16px 36px -12px oklch(0% 0 0 / 0.6)';
|
||||
const FONT = 'system-ui, -apple-system, sans-serif';
|
||||
const MONO = 'ui-monospace, SFMono-Regular, Menlo, monospace';
|
||||
// z-index: detect overlays use 99999, so our UI must be above them
|
||||
@@ -995,8 +997,8 @@
|
||||
transform: 'translateY(6px)',
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
background: BP.surface,
|
||||
border: '1.5px solid ' + BP.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + BP.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: BP.shadow,
|
||||
transition: 'box-shadow 0.2s ease, opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
fontFamily: FONT, fontSize: '13px', color: BP.text,
|
||||
@@ -1071,7 +1073,7 @@
|
||||
barEl.innerHTML = '';
|
||||
// Reset bar styling to the kinpaku picker palette
|
||||
barEl.style.background = BP.surface;
|
||||
barEl.style.border = '1.5px solid ' + BP.border;
|
||||
barEl.style.border = '1px solid ' + BP.border;
|
||||
barEl.style.boxShadow = BP.shadow;
|
||||
if (mode === 'configure') {
|
||||
barEl.appendChild(configureKind === 'insert' ? buildInsertConfigureRow() : buildConfigureRow());
|
||||
@@ -2339,8 +2341,8 @@
|
||||
transformOrigin: 'bottom left',
|
||||
transition: 'opacity 0.18s ' + EASE + ', transform 0.2s ' + EASE,
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
padding: '6px',
|
||||
fontFamily: FONT,
|
||||
@@ -6122,8 +6124,15 @@ void main() {
|
||||
return {
|
||||
surface: C.ink,
|
||||
surfaceDeep: C.ink,
|
||||
border: C.brand,
|
||||
hairline: 'oklch(58% 0.065 82 / 0.48)',
|
||||
// Quiet neutral hairline (was the loud kinpaku gold border). Gold lives on
|
||||
// the brand mark and the active control instead.
|
||||
border: 'oklch(92% 0 0 / 0.13)',
|
||||
// Crisp graphite pill behind the active toggle (was a murky kinpaku-dim
|
||||
// wash); the gold text/icon carries the "selected" signal.
|
||||
toggleActive: 'oklch(27% 0 0)',
|
||||
// Neutral hairline for internal control borders / dividers (was a warm
|
||||
// gold rule that read as muddy champagne edges on the pill / input / count).
|
||||
hairline: 'oklch(92% 0 0 / 0.12)',
|
||||
text: 'oklch(84% 0.035 82)',
|
||||
textDim: 'oklch(63% 0.024 82)',
|
||||
accent: C.brand,
|
||||
@@ -7032,8 +7041,8 @@ void main() {
|
||||
display: 'flex', alignItems: 'stretch',
|
||||
gap: '0',
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
|
||||
opacity: '0',
|
||||
@@ -7443,7 +7452,7 @@ void main() {
|
||||
// Sync one toggle's active state, colors, and slide-label visibility.
|
||||
function sync(btn, active) {
|
||||
if (!btn) return;
|
||||
btn.style.background = active ? P.accentSoft : 'transparent';
|
||||
btn.style.background = active ? P.toggleActive : 'transparent';
|
||||
btn.style.color = active ? P.accent : P.textDim;
|
||||
btn.dataset.active = active ? 'true' : 'false';
|
||||
if (active && btn._expandLabel) btn._expandLabel();
|
||||
|
||||
@@ -46,9 +46,11 @@
|
||||
mist: 'oklch(90% 0.008 82 / 0.6)', // light hairline
|
||||
white: 'oklch(99% 0 0)',
|
||||
};
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css.
|
||||
// Quiet neutral elevation: no gold halo ring (gold is reserved for the brand
|
||||
// mark and the active control, not the container outline).
|
||||
const PICKER_SHADOW =
|
||||
'0 0 0 1px oklch(78% 0.12 82 / 0.18), 0 10px 28px oklch(0% 0 0 / 0.28)';
|
||||
'0 16px 36px -12px oklch(0% 0 0 / 0.6)';
|
||||
const FONT = 'system-ui, -apple-system, sans-serif';
|
||||
const MONO = 'ui-monospace, SFMono-Regular, Menlo, monospace';
|
||||
// z-index: detect overlays use 99999, so our UI must be above them
|
||||
@@ -995,8 +997,8 @@
|
||||
transform: 'translateY(6px)',
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
background: BP.surface,
|
||||
border: '1.5px solid ' + BP.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + BP.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: BP.shadow,
|
||||
transition: 'box-shadow 0.2s ease, opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
fontFamily: FONT, fontSize: '13px', color: BP.text,
|
||||
@@ -1071,7 +1073,7 @@
|
||||
barEl.innerHTML = '';
|
||||
// Reset bar styling to the kinpaku picker palette
|
||||
barEl.style.background = BP.surface;
|
||||
barEl.style.border = '1.5px solid ' + BP.border;
|
||||
barEl.style.border = '1px solid ' + BP.border;
|
||||
barEl.style.boxShadow = BP.shadow;
|
||||
if (mode === 'configure') {
|
||||
barEl.appendChild(configureKind === 'insert' ? buildInsertConfigureRow() : buildConfigureRow());
|
||||
@@ -2339,8 +2341,8 @@
|
||||
transformOrigin: 'bottom left',
|
||||
transition: 'opacity 0.18s ' + EASE + ', transform 0.2s ' + EASE,
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
padding: '6px',
|
||||
fontFamily: FONT,
|
||||
@@ -6122,8 +6124,15 @@ void main() {
|
||||
return {
|
||||
surface: C.ink,
|
||||
surfaceDeep: C.ink,
|
||||
border: C.brand,
|
||||
hairline: 'oklch(58% 0.065 82 / 0.48)',
|
||||
// Quiet neutral hairline (was the loud kinpaku gold border). Gold lives on
|
||||
// the brand mark and the active control instead.
|
||||
border: 'oklch(92% 0 0 / 0.13)',
|
||||
// Crisp graphite pill behind the active toggle (was a murky kinpaku-dim
|
||||
// wash); the gold text/icon carries the "selected" signal.
|
||||
toggleActive: 'oklch(27% 0 0)',
|
||||
// Neutral hairline for internal control borders / dividers (was a warm
|
||||
// gold rule that read as muddy champagne edges on the pill / input / count).
|
||||
hairline: 'oklch(92% 0 0 / 0.12)',
|
||||
text: 'oklch(84% 0.035 82)',
|
||||
textDim: 'oklch(63% 0.024 82)',
|
||||
accent: C.brand,
|
||||
@@ -7032,8 +7041,8 @@ void main() {
|
||||
display: 'flex', alignItems: 'stretch',
|
||||
gap: '0',
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
|
||||
opacity: '0',
|
||||
@@ -7443,7 +7452,7 @@ void main() {
|
||||
// Sync one toggle's active state, colors, and slide-label visibility.
|
||||
function sync(btn, active) {
|
||||
if (!btn) return;
|
||||
btn.style.background = active ? P.accentSoft : 'transparent';
|
||||
btn.style.background = active ? P.toggleActive : 'transparent';
|
||||
btn.style.color = active ? P.accent : P.textDim;
|
||||
btn.dataset.active = active ? 'true' : 'false';
|
||||
if (active && btn._expandLabel) btn._expandLabel();
|
||||
|
||||
@@ -46,9 +46,11 @@
|
||||
mist: 'oklch(90% 0.008 82 / 0.6)', // light hairline
|
||||
white: 'oklch(99% 0 0)',
|
||||
};
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css.
|
||||
// Quiet neutral elevation: no gold halo ring (gold is reserved for the brand
|
||||
// mark and the active control, not the container outline).
|
||||
const PICKER_SHADOW =
|
||||
'0 0 0 1px oklch(78% 0.12 82 / 0.18), 0 10px 28px oklch(0% 0 0 / 0.28)';
|
||||
'0 16px 36px -12px oklch(0% 0 0 / 0.6)';
|
||||
const FONT = 'system-ui, -apple-system, sans-serif';
|
||||
const MONO = 'ui-monospace, SFMono-Regular, Menlo, monospace';
|
||||
// z-index: detect overlays use 99999, so our UI must be above them
|
||||
@@ -995,8 +997,8 @@
|
||||
transform: 'translateY(6px)',
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
background: BP.surface,
|
||||
border: '1.5px solid ' + BP.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + BP.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: BP.shadow,
|
||||
transition: 'box-shadow 0.2s ease, opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
fontFamily: FONT, fontSize: '13px', color: BP.text,
|
||||
@@ -1071,7 +1073,7 @@
|
||||
barEl.innerHTML = '';
|
||||
// Reset bar styling to the kinpaku picker palette
|
||||
barEl.style.background = BP.surface;
|
||||
barEl.style.border = '1.5px solid ' + BP.border;
|
||||
barEl.style.border = '1px solid ' + BP.border;
|
||||
barEl.style.boxShadow = BP.shadow;
|
||||
if (mode === 'configure') {
|
||||
barEl.appendChild(configureKind === 'insert' ? buildInsertConfigureRow() : buildConfigureRow());
|
||||
@@ -2339,8 +2341,8 @@
|
||||
transformOrigin: 'bottom left',
|
||||
transition: 'opacity 0.18s ' + EASE + ', transform 0.2s ' + EASE,
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
padding: '6px',
|
||||
fontFamily: FONT,
|
||||
@@ -6122,8 +6124,15 @@ void main() {
|
||||
return {
|
||||
surface: C.ink,
|
||||
surfaceDeep: C.ink,
|
||||
border: C.brand,
|
||||
hairline: 'oklch(58% 0.065 82 / 0.48)',
|
||||
// Quiet neutral hairline (was the loud kinpaku gold border). Gold lives on
|
||||
// the brand mark and the active control instead.
|
||||
border: 'oklch(92% 0 0 / 0.13)',
|
||||
// Crisp graphite pill behind the active toggle (was a murky kinpaku-dim
|
||||
// wash); the gold text/icon carries the "selected" signal.
|
||||
toggleActive: 'oklch(27% 0 0)',
|
||||
// Neutral hairline for internal control borders / dividers (was a warm
|
||||
// gold rule that read as muddy champagne edges on the pill / input / count).
|
||||
hairline: 'oklch(92% 0 0 / 0.12)',
|
||||
text: 'oklch(84% 0.035 82)',
|
||||
textDim: 'oklch(63% 0.024 82)',
|
||||
accent: C.brand,
|
||||
@@ -7032,8 +7041,8 @@ void main() {
|
||||
display: 'flex', alignItems: 'stretch',
|
||||
gap: '0',
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
|
||||
opacity: '0',
|
||||
@@ -7443,7 +7452,7 @@ void main() {
|
||||
// Sync one toggle's active state, colors, and slide-label visibility.
|
||||
function sync(btn, active) {
|
||||
if (!btn) return;
|
||||
btn.style.background = active ? P.accentSoft : 'transparent';
|
||||
btn.style.background = active ? P.toggleActive : 'transparent';
|
||||
btn.style.color = active ? P.accent : P.textDim;
|
||||
btn.dataset.active = active ? 'true' : 'false';
|
||||
if (active && btn._expandLabel) btn._expandLabel();
|
||||
|
||||
@@ -46,9 +46,11 @@
|
||||
mist: 'oklch(90% 0.008 82 / 0.6)', // light hairline
|
||||
white: 'oklch(99% 0 0)',
|
||||
};
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css.
|
||||
// Quiet neutral elevation: no gold halo ring (gold is reserved for the brand
|
||||
// mark and the active control, not the container outline).
|
||||
const PICKER_SHADOW =
|
||||
'0 0 0 1px oklch(78% 0.12 82 / 0.18), 0 10px 28px oklch(0% 0 0 / 0.28)';
|
||||
'0 16px 36px -12px oklch(0% 0 0 / 0.6)';
|
||||
const FONT = 'system-ui, -apple-system, sans-serif';
|
||||
const MONO = 'ui-monospace, SFMono-Regular, Menlo, monospace';
|
||||
// z-index: detect overlays use 99999, so our UI must be above them
|
||||
@@ -995,8 +997,8 @@
|
||||
transform: 'translateY(6px)',
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
background: BP.surface,
|
||||
border: '1.5px solid ' + BP.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + BP.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: BP.shadow,
|
||||
transition: 'box-shadow 0.2s ease, opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
fontFamily: FONT, fontSize: '13px', color: BP.text,
|
||||
@@ -1071,7 +1073,7 @@
|
||||
barEl.innerHTML = '';
|
||||
// Reset bar styling to the kinpaku picker palette
|
||||
barEl.style.background = BP.surface;
|
||||
barEl.style.border = '1.5px solid ' + BP.border;
|
||||
barEl.style.border = '1px solid ' + BP.border;
|
||||
barEl.style.boxShadow = BP.shadow;
|
||||
if (mode === 'configure') {
|
||||
barEl.appendChild(configureKind === 'insert' ? buildInsertConfigureRow() : buildConfigureRow());
|
||||
@@ -2339,8 +2341,8 @@
|
||||
transformOrigin: 'bottom left',
|
||||
transition: 'opacity 0.18s ' + EASE + ', transform 0.2s ' + EASE,
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
padding: '6px',
|
||||
fontFamily: FONT,
|
||||
@@ -6122,8 +6124,15 @@ void main() {
|
||||
return {
|
||||
surface: C.ink,
|
||||
surfaceDeep: C.ink,
|
||||
border: C.brand,
|
||||
hairline: 'oklch(58% 0.065 82 / 0.48)',
|
||||
// Quiet neutral hairline (was the loud kinpaku gold border). Gold lives on
|
||||
// the brand mark and the active control instead.
|
||||
border: 'oklch(92% 0 0 / 0.13)',
|
||||
// Crisp graphite pill behind the active toggle (was a murky kinpaku-dim
|
||||
// wash); the gold text/icon carries the "selected" signal.
|
||||
toggleActive: 'oklch(27% 0 0)',
|
||||
// Neutral hairline for internal control borders / dividers (was a warm
|
||||
// gold rule that read as muddy champagne edges on the pill / input / count).
|
||||
hairline: 'oklch(92% 0 0 / 0.12)',
|
||||
text: 'oklch(84% 0.035 82)',
|
||||
textDim: 'oklch(63% 0.024 82)',
|
||||
accent: C.brand,
|
||||
@@ -7032,8 +7041,8 @@ void main() {
|
||||
display: 'flex', alignItems: 'stretch',
|
||||
gap: '0',
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
|
||||
opacity: '0',
|
||||
@@ -7443,7 +7452,7 @@ void main() {
|
||||
// Sync one toggle's active state, colors, and slide-label visibility.
|
||||
function sync(btn, active) {
|
||||
if (!btn) return;
|
||||
btn.style.background = active ? P.accentSoft : 'transparent';
|
||||
btn.style.background = active ? P.toggleActive : 'transparent';
|
||||
btn.style.color = active ? P.accent : P.textDim;
|
||||
btn.dataset.active = active ? 'true' : 'false';
|
||||
if (active && btn._expandLabel) btn._expandLabel();
|
||||
|
||||
@@ -46,9 +46,11 @@
|
||||
mist: 'oklch(90% 0.008 82 / 0.6)', // light hairline
|
||||
white: 'oklch(99% 0 0)',
|
||||
};
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css.
|
||||
// Quiet neutral elevation: no gold halo ring (gold is reserved for the brand
|
||||
// mark and the active control, not the container outline).
|
||||
const PICKER_SHADOW =
|
||||
'0 0 0 1px oklch(78% 0.12 82 / 0.18), 0 10px 28px oklch(0% 0 0 / 0.28)';
|
||||
'0 16px 36px -12px oklch(0% 0 0 / 0.6)';
|
||||
const FONT = 'system-ui, -apple-system, sans-serif';
|
||||
const MONO = 'ui-monospace, SFMono-Regular, Menlo, monospace';
|
||||
// z-index: detect overlays use 99999, so our UI must be above them
|
||||
@@ -995,8 +997,8 @@
|
||||
transform: 'translateY(6px)',
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
background: BP.surface,
|
||||
border: '1.5px solid ' + BP.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + BP.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: BP.shadow,
|
||||
transition: 'box-shadow 0.2s ease, opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
fontFamily: FONT, fontSize: '13px', color: BP.text,
|
||||
@@ -1071,7 +1073,7 @@
|
||||
barEl.innerHTML = '';
|
||||
// Reset bar styling to the kinpaku picker palette
|
||||
barEl.style.background = BP.surface;
|
||||
barEl.style.border = '1.5px solid ' + BP.border;
|
||||
barEl.style.border = '1px solid ' + BP.border;
|
||||
barEl.style.boxShadow = BP.shadow;
|
||||
if (mode === 'configure') {
|
||||
barEl.appendChild(configureKind === 'insert' ? buildInsertConfigureRow() : buildConfigureRow());
|
||||
@@ -2339,8 +2341,8 @@
|
||||
transformOrigin: 'bottom left',
|
||||
transition: 'opacity 0.18s ' + EASE + ', transform 0.2s ' + EASE,
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
padding: '6px',
|
||||
fontFamily: FONT,
|
||||
@@ -6122,8 +6124,15 @@ void main() {
|
||||
return {
|
||||
surface: C.ink,
|
||||
surfaceDeep: C.ink,
|
||||
border: C.brand,
|
||||
hairline: 'oklch(58% 0.065 82 / 0.48)',
|
||||
// Quiet neutral hairline (was the loud kinpaku gold border). Gold lives on
|
||||
// the brand mark and the active control instead.
|
||||
border: 'oklch(92% 0 0 / 0.13)',
|
||||
// Crisp graphite pill behind the active toggle (was a murky kinpaku-dim
|
||||
// wash); the gold text/icon carries the "selected" signal.
|
||||
toggleActive: 'oklch(27% 0 0)',
|
||||
// Neutral hairline for internal control borders / dividers (was a warm
|
||||
// gold rule that read as muddy champagne edges on the pill / input / count).
|
||||
hairline: 'oklch(92% 0 0 / 0.12)',
|
||||
text: 'oklch(84% 0.035 82)',
|
||||
textDim: 'oklch(63% 0.024 82)',
|
||||
accent: C.brand,
|
||||
@@ -7032,8 +7041,8 @@ void main() {
|
||||
display: 'flex', alignItems: 'stretch',
|
||||
gap: '0',
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
|
||||
opacity: '0',
|
||||
@@ -7443,7 +7452,7 @@ void main() {
|
||||
// Sync one toggle's active state, colors, and slide-label visibility.
|
||||
function sync(btn, active) {
|
||||
if (!btn) return;
|
||||
btn.style.background = active ? P.accentSoft : 'transparent';
|
||||
btn.style.background = active ? P.toggleActive : 'transparent';
|
||||
btn.style.color = active ? P.accent : P.textDim;
|
||||
btn.dataset.active = active ? 'true' : 'false';
|
||||
if (active && btn._expandLabel) btn._expandLabel();
|
||||
|
||||
@@ -46,9 +46,11 @@
|
||||
mist: 'oklch(90% 0.008 82 / 0.6)', // light hairline
|
||||
white: 'oklch(99% 0 0)',
|
||||
};
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css.
|
||||
// Quiet neutral elevation: no gold halo ring (gold is reserved for the brand
|
||||
// mark and the active control, not the container outline).
|
||||
const PICKER_SHADOW =
|
||||
'0 0 0 1px oklch(78% 0.12 82 / 0.18), 0 10px 28px oklch(0% 0 0 / 0.28)';
|
||||
'0 16px 36px -12px oklch(0% 0 0 / 0.6)';
|
||||
const FONT = 'system-ui, -apple-system, sans-serif';
|
||||
const MONO = 'ui-monospace, SFMono-Regular, Menlo, monospace';
|
||||
// z-index: detect overlays use 99999, so our UI must be above them
|
||||
@@ -995,8 +997,8 @@
|
||||
transform: 'translateY(6px)',
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
background: BP.surface,
|
||||
border: '1.5px solid ' + BP.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + BP.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: BP.shadow,
|
||||
transition: 'box-shadow 0.2s ease, opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
fontFamily: FONT, fontSize: '13px', color: BP.text,
|
||||
@@ -1071,7 +1073,7 @@
|
||||
barEl.innerHTML = '';
|
||||
// Reset bar styling to the kinpaku picker palette
|
||||
barEl.style.background = BP.surface;
|
||||
barEl.style.border = '1.5px solid ' + BP.border;
|
||||
barEl.style.border = '1px solid ' + BP.border;
|
||||
barEl.style.boxShadow = BP.shadow;
|
||||
if (mode === 'configure') {
|
||||
barEl.appendChild(configureKind === 'insert' ? buildInsertConfigureRow() : buildConfigureRow());
|
||||
@@ -2339,8 +2341,8 @@
|
||||
transformOrigin: 'bottom left',
|
||||
transition: 'opacity 0.18s ' + EASE + ', transform 0.2s ' + EASE,
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
padding: '6px',
|
||||
fontFamily: FONT,
|
||||
@@ -6122,8 +6124,15 @@ void main() {
|
||||
return {
|
||||
surface: C.ink,
|
||||
surfaceDeep: C.ink,
|
||||
border: C.brand,
|
||||
hairline: 'oklch(58% 0.065 82 / 0.48)',
|
||||
// Quiet neutral hairline (was the loud kinpaku gold border). Gold lives on
|
||||
// the brand mark and the active control instead.
|
||||
border: 'oklch(92% 0 0 / 0.13)',
|
||||
// Crisp graphite pill behind the active toggle (was a murky kinpaku-dim
|
||||
// wash); the gold text/icon carries the "selected" signal.
|
||||
toggleActive: 'oklch(27% 0 0)',
|
||||
// Neutral hairline for internal control borders / dividers (was a warm
|
||||
// gold rule that read as muddy champagne edges on the pill / input / count).
|
||||
hairline: 'oklch(92% 0 0 / 0.12)',
|
||||
text: 'oklch(84% 0.035 82)',
|
||||
textDim: 'oklch(63% 0.024 82)',
|
||||
accent: C.brand,
|
||||
@@ -7032,8 +7041,8 @@ void main() {
|
||||
display: 'flex', alignItems: 'stretch',
|
||||
gap: '0',
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
|
||||
opacity: '0',
|
||||
@@ -7443,7 +7452,7 @@ void main() {
|
||||
// Sync one toggle's active state, colors, and slide-label visibility.
|
||||
function sync(btn, active) {
|
||||
if (!btn) return;
|
||||
btn.style.background = active ? P.accentSoft : 'transparent';
|
||||
btn.style.background = active ? P.toggleActive : 'transparent';
|
||||
btn.style.color = active ? P.accent : P.textDim;
|
||||
btn.dataset.active = active ? 'true' : 'false';
|
||||
if (active && btn._expandLabel) btn._expandLabel();
|
||||
|
||||
@@ -46,9 +46,11 @@
|
||||
mist: 'oklch(90% 0.008 82 / 0.6)', // light hairline
|
||||
white: 'oklch(99% 0 0)',
|
||||
};
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css.
|
||||
// Quiet neutral elevation: no gold halo ring (gold is reserved for the brand
|
||||
// mark and the active control, not the container outline).
|
||||
const PICKER_SHADOW =
|
||||
'0 0 0 1px oklch(78% 0.12 82 / 0.18), 0 10px 28px oklch(0% 0 0 / 0.28)';
|
||||
'0 16px 36px -12px oklch(0% 0 0 / 0.6)';
|
||||
const FONT = 'system-ui, -apple-system, sans-serif';
|
||||
const MONO = 'ui-monospace, SFMono-Regular, Menlo, monospace';
|
||||
// z-index: detect overlays use 99999, so our UI must be above them
|
||||
@@ -995,8 +997,8 @@
|
||||
transform: 'translateY(6px)',
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
background: BP.surface,
|
||||
border: '1.5px solid ' + BP.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + BP.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: BP.shadow,
|
||||
transition: 'box-shadow 0.2s ease, opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
fontFamily: FONT, fontSize: '13px', color: BP.text,
|
||||
@@ -1071,7 +1073,7 @@
|
||||
barEl.innerHTML = '';
|
||||
// Reset bar styling to the kinpaku picker palette
|
||||
barEl.style.background = BP.surface;
|
||||
barEl.style.border = '1.5px solid ' + BP.border;
|
||||
barEl.style.border = '1px solid ' + BP.border;
|
||||
barEl.style.boxShadow = BP.shadow;
|
||||
if (mode === 'configure') {
|
||||
barEl.appendChild(configureKind === 'insert' ? buildInsertConfigureRow() : buildConfigureRow());
|
||||
@@ -2339,8 +2341,8 @@
|
||||
transformOrigin: 'bottom left',
|
||||
transition: 'opacity 0.18s ' + EASE + ', transform 0.2s ' + EASE,
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
padding: '6px',
|
||||
fontFamily: FONT,
|
||||
@@ -6122,8 +6124,15 @@ void main() {
|
||||
return {
|
||||
surface: C.ink,
|
||||
surfaceDeep: C.ink,
|
||||
border: C.brand,
|
||||
hairline: 'oklch(58% 0.065 82 / 0.48)',
|
||||
// Quiet neutral hairline (was the loud kinpaku gold border). Gold lives on
|
||||
// the brand mark and the active control instead.
|
||||
border: 'oklch(92% 0 0 / 0.13)',
|
||||
// Crisp graphite pill behind the active toggle (was a murky kinpaku-dim
|
||||
// wash); the gold text/icon carries the "selected" signal.
|
||||
toggleActive: 'oklch(27% 0 0)',
|
||||
// Neutral hairline for internal control borders / dividers (was a warm
|
||||
// gold rule that read as muddy champagne edges on the pill / input / count).
|
||||
hairline: 'oklch(92% 0 0 / 0.12)',
|
||||
text: 'oklch(84% 0.035 82)',
|
||||
textDim: 'oklch(63% 0.024 82)',
|
||||
accent: C.brand,
|
||||
@@ -7032,8 +7041,8 @@ void main() {
|
||||
display: 'flex', alignItems: 'stretch',
|
||||
gap: '0',
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
|
||||
opacity: '0',
|
||||
@@ -7443,7 +7452,7 @@ void main() {
|
||||
// Sync one toggle's active state, colors, and slide-label visibility.
|
||||
function sync(btn, active) {
|
||||
if (!btn) return;
|
||||
btn.style.background = active ? P.accentSoft : 'transparent';
|
||||
btn.style.background = active ? P.toggleActive : 'transparent';
|
||||
btn.style.color = active ? P.accent : P.textDim;
|
||||
btn.dataset.active = active ? 'true' : 'false';
|
||||
if (active && btn._expandLabel) btn._expandLabel();
|
||||
|
||||
@@ -46,9 +46,11 @@
|
||||
mist: 'oklch(90% 0.008 82 / 0.6)', // light hairline
|
||||
white: 'oklch(99% 0 0)',
|
||||
};
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css.
|
||||
// Quiet neutral elevation: no gold halo ring (gold is reserved for the brand
|
||||
// mark and the active control, not the container outline).
|
||||
const PICKER_SHADOW =
|
||||
'0 0 0 1px oklch(78% 0.12 82 / 0.18), 0 10px 28px oklch(0% 0 0 / 0.28)';
|
||||
'0 16px 36px -12px oklch(0% 0 0 / 0.6)';
|
||||
const FONT = 'system-ui, -apple-system, sans-serif';
|
||||
const MONO = 'ui-monospace, SFMono-Regular, Menlo, monospace';
|
||||
// z-index: detect overlays use 99999, so our UI must be above them
|
||||
@@ -995,8 +997,8 @@
|
||||
transform: 'translateY(6px)',
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
background: BP.surface,
|
||||
border: '1.5px solid ' + BP.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + BP.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: BP.shadow,
|
||||
transition: 'box-shadow 0.2s ease, opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
fontFamily: FONT, fontSize: '13px', color: BP.text,
|
||||
@@ -1071,7 +1073,7 @@
|
||||
barEl.innerHTML = '';
|
||||
// Reset bar styling to the kinpaku picker palette
|
||||
barEl.style.background = BP.surface;
|
||||
barEl.style.border = '1.5px solid ' + BP.border;
|
||||
barEl.style.border = '1px solid ' + BP.border;
|
||||
barEl.style.boxShadow = BP.shadow;
|
||||
if (mode === 'configure') {
|
||||
barEl.appendChild(configureKind === 'insert' ? buildInsertConfigureRow() : buildConfigureRow());
|
||||
@@ -2339,8 +2341,8 @@
|
||||
transformOrigin: 'bottom left',
|
||||
transition: 'opacity 0.18s ' + EASE + ', transform 0.2s ' + EASE,
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
padding: '6px',
|
||||
fontFamily: FONT,
|
||||
@@ -6122,8 +6124,15 @@ void main() {
|
||||
return {
|
||||
surface: C.ink,
|
||||
surfaceDeep: C.ink,
|
||||
border: C.brand,
|
||||
hairline: 'oklch(58% 0.065 82 / 0.48)',
|
||||
// Quiet neutral hairline (was the loud kinpaku gold border). Gold lives on
|
||||
// the brand mark and the active control instead.
|
||||
border: 'oklch(92% 0 0 / 0.13)',
|
||||
// Crisp graphite pill behind the active toggle (was a murky kinpaku-dim
|
||||
// wash); the gold text/icon carries the "selected" signal.
|
||||
toggleActive: 'oklch(27% 0 0)',
|
||||
// Neutral hairline for internal control borders / dividers (was a warm
|
||||
// gold rule that read as muddy champagne edges on the pill / input / count).
|
||||
hairline: 'oklch(92% 0 0 / 0.12)',
|
||||
text: 'oklch(84% 0.035 82)',
|
||||
textDim: 'oklch(63% 0.024 82)',
|
||||
accent: C.brand,
|
||||
@@ -7032,8 +7041,8 @@ void main() {
|
||||
display: 'flex', alignItems: 'stretch',
|
||||
gap: '0',
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
|
||||
opacity: '0',
|
||||
@@ -7443,7 +7452,7 @@ void main() {
|
||||
// Sync one toggle's active state, colors, and slide-label visibility.
|
||||
function sync(btn, active) {
|
||||
if (!btn) return;
|
||||
btn.style.background = active ? P.accentSoft : 'transparent';
|
||||
btn.style.background = active ? P.toggleActive : 'transparent';
|
||||
btn.style.color = active ? P.accent : P.textDim;
|
||||
btn.dataset.active = active ? 'true' : 'false';
|
||||
if (active && btn._expandLabel) btn._expandLabel();
|
||||
|
||||
@@ -46,9 +46,11 @@
|
||||
mist: 'oklch(90% 0.008 82 / 0.6)', // light hairline
|
||||
white: 'oklch(99% 0 0)',
|
||||
};
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css.
|
||||
// Quiet neutral elevation: no gold halo ring (gold is reserved for the brand
|
||||
// mark and the active control, not the container outline).
|
||||
const PICKER_SHADOW =
|
||||
'0 0 0 1px oklch(78% 0.12 82 / 0.18), 0 10px 28px oklch(0% 0 0 / 0.28)';
|
||||
'0 16px 36px -12px oklch(0% 0 0 / 0.6)';
|
||||
const FONT = 'system-ui, -apple-system, sans-serif';
|
||||
const MONO = 'ui-monospace, SFMono-Regular, Menlo, monospace';
|
||||
// z-index: detect overlays use 99999, so our UI must be above them
|
||||
@@ -995,8 +997,8 @@
|
||||
transform: 'translateY(6px)',
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
background: BP.surface,
|
||||
border: '1.5px solid ' + BP.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + BP.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: BP.shadow,
|
||||
transition: 'box-shadow 0.2s ease, opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
fontFamily: FONT, fontSize: '13px', color: BP.text,
|
||||
@@ -1071,7 +1073,7 @@
|
||||
barEl.innerHTML = '';
|
||||
// Reset bar styling to the kinpaku picker palette
|
||||
barEl.style.background = BP.surface;
|
||||
barEl.style.border = '1.5px solid ' + BP.border;
|
||||
barEl.style.border = '1px solid ' + BP.border;
|
||||
barEl.style.boxShadow = BP.shadow;
|
||||
if (mode === 'configure') {
|
||||
barEl.appendChild(configureKind === 'insert' ? buildInsertConfigureRow() : buildConfigureRow());
|
||||
@@ -2339,8 +2341,8 @@
|
||||
transformOrigin: 'bottom left',
|
||||
transition: 'opacity 0.18s ' + EASE + ', transform 0.2s ' + EASE,
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
padding: '6px',
|
||||
fontFamily: FONT,
|
||||
@@ -6122,8 +6124,15 @@ void main() {
|
||||
return {
|
||||
surface: C.ink,
|
||||
surfaceDeep: C.ink,
|
||||
border: C.brand,
|
||||
hairline: 'oklch(58% 0.065 82 / 0.48)',
|
||||
// Quiet neutral hairline (was the loud kinpaku gold border). Gold lives on
|
||||
// the brand mark and the active control instead.
|
||||
border: 'oklch(92% 0 0 / 0.13)',
|
||||
// Crisp graphite pill behind the active toggle (was a murky kinpaku-dim
|
||||
// wash); the gold text/icon carries the "selected" signal.
|
||||
toggleActive: 'oklch(27% 0 0)',
|
||||
// Neutral hairline for internal control borders / dividers (was a warm
|
||||
// gold rule that read as muddy champagne edges on the pill / input / count).
|
||||
hairline: 'oklch(92% 0 0 / 0.12)',
|
||||
text: 'oklch(84% 0.035 82)',
|
||||
textDim: 'oklch(63% 0.024 82)',
|
||||
accent: C.brand,
|
||||
@@ -7032,8 +7041,8 @@ void main() {
|
||||
display: 'flex', alignItems: 'stretch',
|
||||
gap: '0',
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
|
||||
opacity: '0',
|
||||
@@ -7443,7 +7452,7 @@ void main() {
|
||||
// Sync one toggle's active state, colors, and slide-label visibility.
|
||||
function sync(btn, active) {
|
||||
if (!btn) return;
|
||||
btn.style.background = active ? P.accentSoft : 'transparent';
|
||||
btn.style.background = active ? P.toggleActive : 'transparent';
|
||||
btn.style.color = active ? P.accent : P.textDim;
|
||||
btn.dataset.active = active ? 'true' : 'false';
|
||||
if (active && btn._expandLabel) btn._expandLabel();
|
||||
|
||||
@@ -46,9 +46,11 @@
|
||||
mist: 'oklch(90% 0.008 82 / 0.6)', // light hairline
|
||||
white: 'oklch(99% 0 0)',
|
||||
};
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css.
|
||||
// Quiet neutral elevation: no gold halo ring (gold is reserved for the brand
|
||||
// mark and the active control, not the container outline).
|
||||
const PICKER_SHADOW =
|
||||
'0 0 0 1px oklch(78% 0.12 82 / 0.18), 0 10px 28px oklch(0% 0 0 / 0.28)';
|
||||
'0 16px 36px -12px oklch(0% 0 0 / 0.6)';
|
||||
const FONT = 'system-ui, -apple-system, sans-serif';
|
||||
const MONO = 'ui-monospace, SFMono-Regular, Menlo, monospace';
|
||||
// z-index: detect overlays use 99999, so our UI must be above them
|
||||
@@ -995,8 +997,8 @@
|
||||
transform: 'translateY(6px)',
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
background: BP.surface,
|
||||
border: '1.5px solid ' + BP.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + BP.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: BP.shadow,
|
||||
transition: 'box-shadow 0.2s ease, opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
fontFamily: FONT, fontSize: '13px', color: BP.text,
|
||||
@@ -1071,7 +1073,7 @@
|
||||
barEl.innerHTML = '';
|
||||
// Reset bar styling to the kinpaku picker palette
|
||||
barEl.style.background = BP.surface;
|
||||
barEl.style.border = '1.5px solid ' + BP.border;
|
||||
barEl.style.border = '1px solid ' + BP.border;
|
||||
barEl.style.boxShadow = BP.shadow;
|
||||
if (mode === 'configure') {
|
||||
barEl.appendChild(configureKind === 'insert' ? buildInsertConfigureRow() : buildConfigureRow());
|
||||
@@ -2339,8 +2341,8 @@
|
||||
transformOrigin: 'bottom left',
|
||||
transition: 'opacity 0.18s ' + EASE + ', transform 0.2s ' + EASE,
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
padding: '6px',
|
||||
fontFamily: FONT,
|
||||
@@ -6122,8 +6124,15 @@ void main() {
|
||||
return {
|
||||
surface: C.ink,
|
||||
surfaceDeep: C.ink,
|
||||
border: C.brand,
|
||||
hairline: 'oklch(58% 0.065 82 / 0.48)',
|
||||
// Quiet neutral hairline (was the loud kinpaku gold border). Gold lives on
|
||||
// the brand mark and the active control instead.
|
||||
border: 'oklch(92% 0 0 / 0.13)',
|
||||
// Crisp graphite pill behind the active toggle (was a murky kinpaku-dim
|
||||
// wash); the gold text/icon carries the "selected" signal.
|
||||
toggleActive: 'oklch(27% 0 0)',
|
||||
// Neutral hairline for internal control borders / dividers (was a warm
|
||||
// gold rule that read as muddy champagne edges on the pill / input / count).
|
||||
hairline: 'oklch(92% 0 0 / 0.12)',
|
||||
text: 'oklch(84% 0.035 82)',
|
||||
textDim: 'oklch(63% 0.024 82)',
|
||||
accent: C.brand,
|
||||
@@ -7032,8 +7041,8 @@ void main() {
|
||||
display: 'flex', alignItems: 'stretch',
|
||||
gap: '0',
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
|
||||
opacity: '0',
|
||||
@@ -7443,7 +7452,7 @@ void main() {
|
||||
// Sync one toggle's active state, colors, and slide-label visibility.
|
||||
function sync(btn, active) {
|
||||
if (!btn) return;
|
||||
btn.style.background = active ? P.accentSoft : 'transparent';
|
||||
btn.style.background = active ? P.toggleActive : 'transparent';
|
||||
btn.style.color = active ? P.accent : P.textDim;
|
||||
btn.dataset.active = active ? 'true' : 'false';
|
||||
if (active && btn._expandLabel) btn._expandLabel();
|
||||
|
||||
@@ -46,9 +46,11 @@
|
||||
mist: 'oklch(90% 0.008 82 / 0.6)', // light hairline
|
||||
white: 'oklch(99% 0 0)',
|
||||
};
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css.
|
||||
// Quiet neutral elevation: no gold halo ring (gold is reserved for the brand
|
||||
// mark and the active control, not the container outline).
|
||||
const PICKER_SHADOW =
|
||||
'0 0 0 1px oklch(78% 0.12 82 / 0.18), 0 10px 28px oklch(0% 0 0 / 0.28)';
|
||||
'0 16px 36px -12px oklch(0% 0 0 / 0.6)';
|
||||
const FONT = 'system-ui, -apple-system, sans-serif';
|
||||
const MONO = 'ui-monospace, SFMono-Regular, Menlo, monospace';
|
||||
// z-index: detect overlays use 99999, so our UI must be above them
|
||||
@@ -995,8 +997,8 @@
|
||||
transform: 'translateY(6px)',
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
background: BP.surface,
|
||||
border: '1.5px solid ' + BP.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + BP.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: BP.shadow,
|
||||
transition: 'box-shadow 0.2s ease, opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
fontFamily: FONT, fontSize: '13px', color: BP.text,
|
||||
@@ -1071,7 +1073,7 @@
|
||||
barEl.innerHTML = '';
|
||||
// Reset bar styling to the kinpaku picker palette
|
||||
barEl.style.background = BP.surface;
|
||||
barEl.style.border = '1.5px solid ' + BP.border;
|
||||
barEl.style.border = '1px solid ' + BP.border;
|
||||
barEl.style.boxShadow = BP.shadow;
|
||||
if (mode === 'configure') {
|
||||
barEl.appendChild(configureKind === 'insert' ? buildInsertConfigureRow() : buildConfigureRow());
|
||||
@@ -2339,8 +2341,8 @@
|
||||
transformOrigin: 'bottom left',
|
||||
transition: 'opacity 0.18s ' + EASE + ', transform 0.2s ' + EASE,
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
padding: '6px',
|
||||
fontFamily: FONT,
|
||||
@@ -6122,8 +6124,15 @@ void main() {
|
||||
return {
|
||||
surface: C.ink,
|
||||
surfaceDeep: C.ink,
|
||||
border: C.brand,
|
||||
hairline: 'oklch(58% 0.065 82 / 0.48)',
|
||||
// Quiet neutral hairline (was the loud kinpaku gold border). Gold lives on
|
||||
// the brand mark and the active control instead.
|
||||
border: 'oklch(92% 0 0 / 0.13)',
|
||||
// Crisp graphite pill behind the active toggle (was a murky kinpaku-dim
|
||||
// wash); the gold text/icon carries the "selected" signal.
|
||||
toggleActive: 'oklch(27% 0 0)',
|
||||
// Neutral hairline for internal control borders / dividers (was a warm
|
||||
// gold rule that read as muddy champagne edges on the pill / input / count).
|
||||
hairline: 'oklch(92% 0 0 / 0.12)',
|
||||
text: 'oklch(84% 0.035 82)',
|
||||
textDim: 'oklch(63% 0.024 82)',
|
||||
accent: C.brand,
|
||||
@@ -7032,8 +7041,8 @@ void main() {
|
||||
display: 'flex', alignItems: 'stretch',
|
||||
gap: '0',
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
|
||||
opacity: '0',
|
||||
@@ -7443,7 +7452,7 @@ void main() {
|
||||
// Sync one toggle's active state, colors, and slide-label visibility.
|
||||
function sync(btn, active) {
|
||||
if (!btn) return;
|
||||
btn.style.background = active ? P.accentSoft : 'transparent';
|
||||
btn.style.background = active ? P.toggleActive : 'transparent';
|
||||
btn.style.color = active ? P.accent : P.textDim;
|
||||
btn.dataset.active = active ? 'true' : 'false';
|
||||
if (active && btn._expandLabel) btn._expandLabel();
|
||||
|
||||
@@ -46,9 +46,11 @@
|
||||
mist: 'oklch(90% 0.008 82 / 0.6)', // light hairline
|
||||
white: 'oklch(99% 0 0)',
|
||||
};
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css.
|
||||
// Quiet neutral elevation: no gold halo ring (gold is reserved for the brand
|
||||
// mark and the active control, not the container outline).
|
||||
const PICKER_SHADOW =
|
||||
'0 0 0 1px oklch(78% 0.12 82 / 0.18), 0 10px 28px oklch(0% 0 0 / 0.28)';
|
||||
'0 16px 36px -12px oklch(0% 0 0 / 0.6)';
|
||||
const FONT = 'system-ui, -apple-system, sans-serif';
|
||||
const MONO = 'ui-monospace, SFMono-Regular, Menlo, monospace';
|
||||
// z-index: detect overlays use 99999, so our UI must be above them
|
||||
@@ -995,8 +997,8 @@
|
||||
transform: 'translateY(6px)',
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
background: BP.surface,
|
||||
border: '1.5px solid ' + BP.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + BP.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: BP.shadow,
|
||||
transition: 'box-shadow 0.2s ease, opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
fontFamily: FONT, fontSize: '13px', color: BP.text,
|
||||
@@ -1071,7 +1073,7 @@
|
||||
barEl.innerHTML = '';
|
||||
// Reset bar styling to the kinpaku picker palette
|
||||
barEl.style.background = BP.surface;
|
||||
barEl.style.border = '1.5px solid ' + BP.border;
|
||||
barEl.style.border = '1px solid ' + BP.border;
|
||||
barEl.style.boxShadow = BP.shadow;
|
||||
if (mode === 'configure') {
|
||||
barEl.appendChild(configureKind === 'insert' ? buildInsertConfigureRow() : buildConfigureRow());
|
||||
@@ -2339,8 +2341,8 @@
|
||||
transformOrigin: 'bottom left',
|
||||
transition: 'opacity 0.18s ' + EASE + ', transform 0.2s ' + EASE,
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
padding: '6px',
|
||||
fontFamily: FONT,
|
||||
@@ -6122,8 +6124,15 @@ void main() {
|
||||
return {
|
||||
surface: C.ink,
|
||||
surfaceDeep: C.ink,
|
||||
border: C.brand,
|
||||
hairline: 'oklch(58% 0.065 82 / 0.48)',
|
||||
// Quiet neutral hairline (was the loud kinpaku gold border). Gold lives on
|
||||
// the brand mark and the active control instead.
|
||||
border: 'oklch(92% 0 0 / 0.13)',
|
||||
// Crisp graphite pill behind the active toggle (was a murky kinpaku-dim
|
||||
// wash); the gold text/icon carries the "selected" signal.
|
||||
toggleActive: 'oklch(27% 0 0)',
|
||||
// Neutral hairline for internal control borders / dividers (was a warm
|
||||
// gold rule that read as muddy champagne edges on the pill / input / count).
|
||||
hairline: 'oklch(92% 0 0 / 0.12)',
|
||||
text: 'oklch(84% 0.035 82)',
|
||||
textDim: 'oklch(63% 0.024 82)',
|
||||
accent: C.brand,
|
||||
@@ -7032,8 +7041,8 @@ void main() {
|
||||
display: 'flex', alignItems: 'stretch',
|
||||
gap: '0',
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
|
||||
opacity: '0',
|
||||
@@ -7443,7 +7452,7 @@ void main() {
|
||||
// Sync one toggle's active state, colors, and slide-label visibility.
|
||||
function sync(btn, active) {
|
||||
if (!btn) return;
|
||||
btn.style.background = active ? P.accentSoft : 'transparent';
|
||||
btn.style.background = active ? P.toggleActive : 'transparent';
|
||||
btn.style.color = active ? P.accent : P.textDim;
|
||||
btn.dataset.active = active ? 'true' : 'false';
|
||||
if (active && btn._expandLabel) btn._expandLabel();
|
||||
|
||||
@@ -18,18 +18,18 @@ colors:
|
||||
graphite-2: "oklch(19% 0.008 95)" # one step up from graphite
|
||||
|
||||
# Text
|
||||
champagne: "oklch(84% 0.035 82)" # headlines, <strong>
|
||||
text-warm: "oklch(81% 0.03 82)" # body
|
||||
text-muted: "oklch(63% 0.024 82)" # captions, meta
|
||||
text-faint: "oklch(52% 0.018 82)" # subdued
|
||||
text-mute-deep: "oklch(48% 0.018 82)" # disabled
|
||||
champagne: "oklch(91% 0 0)" # headlines, <strong> — neutral white (name kept for compat)
|
||||
text-warm: "oklch(88% 0 0)" # body — neutral near-white
|
||||
text-muted: "oklch(72% 0 0)" # captions, meta
|
||||
text-faint: "oklch(62% 0 0)" # subdued
|
||||
text-mute-deep: "oklch(52% 0 0)" # disabled
|
||||
|
||||
# Gold ramp
|
||||
kinpaku-pale: "oklch(86% 0.07 84)" # hover lift, pale fills
|
||||
kinpaku-rich: "oklch(77% 0.13 82)" # active CTA, severity-medium
|
||||
kinpaku-deep: "oklch(61% 0.085 78)" # borders against the brand
|
||||
gold-hairline: "oklch(58% 0.065 82 / 0.32)" # default rule
|
||||
gold-hairline-strong: "oklch(74% 0.09 82 / 0.6)" # active rule
|
||||
gold-hairline: "oklch(78% 0 0 / 0.16)" # default rule — neutral (name kept for compat)
|
||||
gold-hairline-strong: "oklch(74% 0.09 82 / 0.6)" # active rule — gold
|
||||
|
||||
# Patina ramp
|
||||
patina-pale: "oklch(82% 0.07 188)" # hover lift on patina
|
||||
@@ -272,16 +272,16 @@ Do not hand-type oklch values or font sizes in page CSS. If a value isn't in the
|
||||
- **Kinpaku Rich** (`oklch(77% 0.13 82)`): Active CTA fill and severity-medium markers.
|
||||
- **Kinpaku Deep** (`oklch(61% 0.085 78)`): Secondary gold for borders, subdued icons, and large technical diagrams.
|
||||
- **Kinpaku Pale** (`oklch(86% 0.07 84)`): Hover lift and pale fills.
|
||||
- **Gold Hairline** (`oklch(58% 0.065 82 / 0.32)`): Default border and divider. The homepage's busier surfaces lift this to alpha 0.48 locally.
|
||||
- **Strong Gold Hairline** (`oklch(74% 0.09 82 / 0.6)`): Active borders, focus outlines, and structural anchors.
|
||||
- **Default Hairline** (`oklch(78% 0 0 / 0.16)`): Default border and divider. Neutral, so borders and labels don't carry warmth (token name `gold-hairline` / `--ks-rule` is legacy).
|
||||
- **Strong Gold Hairline** (`oklch(74% 0.09 82 / 0.6)`): Active borders, focus outlines, and structural anchors. Stays gold — this is where the hairline is meant to read as brand.
|
||||
|
||||
### Text
|
||||
|
||||
- **Champagne** (`oklch(84% 0.035 82)`): Headlines, `<strong>`, important labels.
|
||||
- **Warm Text** (`oklch(81% 0.03 82)`): Body copy on dark surfaces.
|
||||
- **Muted Text** (`oklch(63% 0.024 82)`): Metadata, captions, secondary labels. The homepage lifts this to 65% on busier tile backgrounds.
|
||||
- **Faint Text** (`oklch(52% 0.018 82)`): Subdued labels.
|
||||
- **Mute Deep** (`oklch(48% 0.018 82)`): Disabled copy.
|
||||
- **Champagne** (`oklch(91% 0 0)`): Headlines, `<strong>`, important labels. The brightest text tier, fully neutral (token name is legacy). Text carries no warmth at any tier; the gold accents and surfaces do.
|
||||
- **Body Text** (`oklch(88% 0 0)`): Body copy on dark surfaces. Neutral and bright so reading copy reads crisp, not mushy.
|
||||
- **Muted Text** (`oklch(72% 0 0)`): Metadata, captions, secondary labels.
|
||||
- **Faint Text** (`oklch(62% 0 0)`): Subdued labels.
|
||||
- **Mute Deep** (`oklch(52% 0 0)`): Disabled copy.
|
||||
|
||||
### Secondary and State
|
||||
|
||||
@@ -387,16 +387,16 @@ The footer can carry the strongest oxidation accent. Use the gold seam plus pati
|
||||
The global bottom bar and the contextual bar (configure / cycling / accept) share one chrome treatment. Source of truth: `skill/scripts/live-browser.js` (`barPaletteForTheme`, `initGlobalBar`, `initBar`). Homepage and `/live-mode` demos mirror it via `.live-demo-gbar` and `.live-demo-ctx` in `site/styles/kinpaku-kit.css`.
|
||||
|
||||
- **Surface:** Lacquer Deep (`oklch(4% 0.004 95)`), always. Picker chrome does not adapt to the host page's light/dark theme.
|
||||
- **Border:** 1.5px solid Kinpaku Gold (`oklch(84% 0.19 80.46)`).
|
||||
- **Shadow:** `0 0 0 1px oklch(78% 0.12 82 / 0.18), 0 10px 28px oklch(0% 0 0 / 0.28)` (kinpaku halo + drop shadow).
|
||||
- **Border:** 1px solid neutral hairline (`oklch(92% 0 0 / 0.13)`), radius 8px. The bar reads as a quiet precise tool; gold is reserved for the brand mark and the active control, not the container outline.
|
||||
- **Shadow:** `0 16px 36px -12px oklch(0% 0 0 / 0.6)` (tight neutral drop, no gold halo ring).
|
||||
- **Brand mark:** Impeccable carved-tile icon (same SVG paths as `site/components/Header.astro` / `favicon.svg`), kinpaku fill on transparent ground. Not a "/" slash or rounded-square placeholder.
|
||||
- **Default controls:** Champagne labels at rest (`oklch(84% 0.035 82)`), muted icons (`oklch(63% 0.024 82)`).
|
||||
- **Active toggle:** Kinpaku-dim pill background (`oklch(78% 0.12 82 / 0.18)`) with kinpaku text.
|
||||
- **Active toggle:** Crisp graphite pill (`oklch(27% 0 0)`) with kinpaku text/icon. The gold carries the "selected" signal; the pill itself is neutral, not a kinpaku-dim wash.
|
||||
- **Exit hover:** Vermilion (`oklch(58% 0.15 35)`), not a neutral gray lift.
|
||||
- **Context bar internals:** Graphite-2 pills, gold hairline dividers, kinpaku Go/Accept CTAs with lacquer-deep text.
|
||||
- **DESIGN.md toggle icon:** Four-quadrant swatch; bottom-right uses warm charcoal (`oklch(34% 0.014 82)`) so the tile reads against lacquer-deep, not void-black.
|
||||
|
||||
**The Picker Is Brand Rule.** Live mode UI is Impeccable product chrome, not host-page chrome. It always ships the full kinpaku border, lacquer-deep fill, and carved-tile mark.
|
||||
**The Picker Is Brand Rule.** Live mode UI is Impeccable product chrome, not host-page chrome. It always ships the lacquer-deep fill, the carved-tile mark, and gold on the mark + active control. Brand reads through the mark and the gold accent rather than a gold border ringing the bar; the container itself stays a quiet neutral-edged tool.
|
||||
|
||||
## 7. Do and Do Not
|
||||
|
||||
|
||||
@@ -46,9 +46,11 @@
|
||||
mist: 'oklch(90% 0.008 82 / 0.6)', // light hairline
|
||||
white: 'oklch(99% 0 0)',
|
||||
};
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css.
|
||||
// Quiet neutral elevation: no gold halo ring (gold is reserved for the brand
|
||||
// mark and the active control, not the container outline).
|
||||
const PICKER_SHADOW =
|
||||
'0 0 0 1px oklch(78% 0.12 82 / 0.18), 0 10px 28px oklch(0% 0 0 / 0.28)';
|
||||
'0 16px 36px -12px oklch(0% 0 0 / 0.6)';
|
||||
const FONT = 'system-ui, -apple-system, sans-serif';
|
||||
const MONO = 'ui-monospace, SFMono-Regular, Menlo, monospace';
|
||||
// z-index: detect overlays use 99999, so our UI must be above them
|
||||
@@ -995,8 +997,8 @@
|
||||
transform: 'translateY(6px)',
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
background: BP.surface,
|
||||
border: '1.5px solid ' + BP.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + BP.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: BP.shadow,
|
||||
transition: 'box-shadow 0.2s ease, opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
fontFamily: FONT, fontSize: '13px', color: BP.text,
|
||||
@@ -1071,7 +1073,7 @@
|
||||
barEl.innerHTML = '';
|
||||
// Reset bar styling to the kinpaku picker palette
|
||||
barEl.style.background = BP.surface;
|
||||
barEl.style.border = '1.5px solid ' + BP.border;
|
||||
barEl.style.border = '1px solid ' + BP.border;
|
||||
barEl.style.boxShadow = BP.shadow;
|
||||
if (mode === 'configure') {
|
||||
barEl.appendChild(configureKind === 'insert' ? buildInsertConfigureRow() : buildConfigureRow());
|
||||
@@ -2339,8 +2341,8 @@
|
||||
transformOrigin: 'bottom left',
|
||||
transition: 'opacity 0.18s ' + EASE + ', transform 0.2s ' + EASE,
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
padding: '6px',
|
||||
fontFamily: FONT,
|
||||
@@ -6122,8 +6124,15 @@ void main() {
|
||||
return {
|
||||
surface: C.ink,
|
||||
surfaceDeep: C.ink,
|
||||
border: C.brand,
|
||||
hairline: 'oklch(58% 0.065 82 / 0.48)',
|
||||
// Quiet neutral hairline (was the loud kinpaku gold border). Gold lives on
|
||||
// the brand mark and the active control instead.
|
||||
border: 'oklch(92% 0 0 / 0.13)',
|
||||
// Crisp graphite pill behind the active toggle (was a murky kinpaku-dim
|
||||
// wash); the gold text/icon carries the "selected" signal.
|
||||
toggleActive: 'oklch(27% 0 0)',
|
||||
// Neutral hairline for internal control borders / dividers (was a warm
|
||||
// gold rule that read as muddy champagne edges on the pill / input / count).
|
||||
hairline: 'oklch(92% 0 0 / 0.12)',
|
||||
text: 'oklch(84% 0.035 82)',
|
||||
textDim: 'oklch(63% 0.024 82)',
|
||||
accent: C.brand,
|
||||
@@ -7032,8 +7041,8 @@ void main() {
|
||||
display: 'flex', alignItems: 'stretch',
|
||||
gap: '0',
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
|
||||
opacity: '0',
|
||||
@@ -7443,7 +7452,7 @@ void main() {
|
||||
// Sync one toggle's active state, colors, and slide-label visibility.
|
||||
function sync(btn, active) {
|
||||
if (!btn) return;
|
||||
btn.style.background = active ? P.accentSoft : 'transparent';
|
||||
btn.style.background = active ? P.toggleActive : 'transparent';
|
||||
btn.style.color = active ? P.accent : P.textDim;
|
||||
btn.dataset.active = active ? 'true' : 'false';
|
||||
if (active && btn._expandLabel) btn._expandLabel();
|
||||
|
||||
@@ -34,9 +34,25 @@ const { activeNav } = Astro.props;
|
||||
<a href="/slop" data-nav="slop" aria-current={activeNav === 'slop' ? 'page' : undefined}>Slop</a>
|
||||
<a href="/live-mode" data-nav="live" aria-current={activeNav === 'live' ? 'page' : undefined}>Live</a>
|
||||
</nav>
|
||||
<a href="https://github.com/pbakaus/impeccable" class="site-header-github" target="_blank" rel="noopener" aria-label="Impeccable on GitHub, 30k stars">
|
||||
<button
|
||||
type="button"
|
||||
class="theme-toggle"
|
||||
data-theme-toggle
|
||||
aria-label="Switch to light mode"
|
||||
title="Light mode"
|
||||
data-next-theme="light"
|
||||
>
|
||||
<svg class="theme-toggle-icon--light" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true">
|
||||
<circle cx="12" cy="12" r="4.5"/>
|
||||
<path d="M12 2v2M12 20v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M2 12h2M20 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/>
|
||||
</svg>
|
||||
<svg class="theme-toggle-icon--dark" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true">
|
||||
<path d="M21 14.5A8.5 8.5 0 0 1 9.5 3a7 7 0 1 0 11.5 11.5z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<a href="https://github.com/pbakaus/impeccable" class="site-header-github" target="_blank" rel="noopener" aria-label="Impeccable on GitHub, 31k stars">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"/></svg>
|
||||
<span class="site-header-github-label">30k</span>
|
||||
<span class="site-header-github-label">31k</span>
|
||||
<svg class="site-header-github-star" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.76 6.36L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l7.24-.91L12 2z"/></svg>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,6 @@ const rowB = all.slice(half);
|
||||
---
|
||||
|
||||
<section class="testimonials-section" id="testimonials" aria-label="What people say about Impeccable">
|
||||
<div class="t-plinth t-plinth--shelf">
|
||||
<div class="t-marquee" aria-hidden="false">
|
||||
|
||||
<div class="t-marquee-row">
|
||||
@@ -71,5 +70,4 @@ const rowB = all.slice(half);
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -6,6 +6,7 @@ import Footer from '../components/Footer.astro';
|
||||
// to re-import from page-level stylesheets.
|
||||
import '../styles/kinpaku-tokens.css';
|
||||
import '../styles/kinpaku-kit.css';
|
||||
import '../styles/light-mode.css';
|
||||
import '../styles/footer.css';
|
||||
|
||||
interface Props {
|
||||
@@ -63,6 +64,21 @@ const resolvedOgDescription = ogDescription || description;
|
||||
<title>{title}</title>
|
||||
<meta name="description" content={description}>
|
||||
<meta name="theme-color" content="#010101">
|
||||
<script is:inline>
|
||||
(function () {
|
||||
try {
|
||||
var t = localStorage.getItem('impeccable-theme');
|
||||
var root = document.documentElement;
|
||||
if (t === 'light') {
|
||||
root.classList.add('light');
|
||||
var meta = document.querySelector('meta[name="theme-color"]');
|
||||
if (meta) meta.setAttribute('content', '#f7f4ef');
|
||||
} else {
|
||||
root.classList.add('dark');
|
||||
}
|
||||
} catch (e) {}
|
||||
})();
|
||||
</script>
|
||||
{noIndex && <meta name="robots" content="noindex">}
|
||||
{canonical && <link rel="canonical" href={canonical}>}
|
||||
|
||||
@@ -97,5 +113,9 @@ const resolvedOgDescription = ogDescription || description;
|
||||
</main>
|
||||
{!hideFooter && <Footer />}
|
||||
<slot name="scripts" />
|
||||
<script>
|
||||
import { initThemeToggle } from '../scripts/utils/theme.js';
|
||||
initThemeToggle();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -41,6 +41,22 @@ import '../../styles/design-system.css';
|
||||
<a href="#components">Components</a>
|
||||
<a href="#proof">Proof</a>
|
||||
</nav>
|
||||
<button
|
||||
type="button"
|
||||
class="theme-toggle"
|
||||
data-theme-toggle
|
||||
aria-label="Switch to light mode"
|
||||
title="Light mode"
|
||||
data-next-theme="light"
|
||||
>
|
||||
<svg class="theme-toggle-icon--light" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true">
|
||||
<circle cx="12" cy="12" r="4.5"/>
|
||||
<path d="M12 2v2M12 20v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M2 12h2M20 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/>
|
||||
</svg>
|
||||
<svg class="theme-toggle-icon--dark" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true">
|
||||
<path d="M21 14.5A8.5 8.5 0 0 1 9.5 3a7 7 0 1 0 11.5 11.5z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<a class="ks-button ks-button-primary" href="#actions">
|
||||
Start audit
|
||||
<span class="ks-button-arrow" aria-hidden="true">
|
||||
|
||||
@@ -391,17 +391,27 @@ import '../../styles/designing-kinpaku.css';
|
||||
<div class="designing-phase-body">
|
||||
<div class="ks-bento designing-lanes">
|
||||
<article class="ks-bento-tile ks-bento-tile--span-6">
|
||||
<p class="designing-lane-rule">Design IS the product. Marketing, landing, editorial, long-form, portfolio.</p>
|
||||
<p class="designing-lane-rule"><strong>Brand.</strong> Design is the deliverable: landing pages, campaigns, editorial, portfolios. Distinctive type, committed palette, image-led heroes. The impression is the product.</p>
|
||||
<div class="designing-lane-mock designing-lane-mock--brand" aria-hidden="true">
|
||||
<span class="designing-lane-mock-label">No. 04 · Dispatch</span>
|
||||
<span class="designing-lane-mock-title">Letters, occasionally.</span>
|
||||
<span class="designing-lane-mock-label">Issue 04 · Dispatch</span>
|
||||
<span class="designing-lane-mock-title"><span class="designing-lane-mock-accent">Shape</span> the story.</span>
|
||||
</div>
|
||||
</article>
|
||||
<article class="ks-bento-tile ks-bento-tile--span-6">
|
||||
<p class="designing-lane-rule">Design serves the task. App UI, admin, dashboards, tools.</p>
|
||||
<p class="designing-lane-rule"><strong>Product.</strong> Design serves the task: app UI, admin, dashboards, tools. Fluent density, semantic states, repeatable components. Users are here to finish something.</p>
|
||||
<div class="designing-lane-mock designing-lane-mock--product" aria-hidden="true">
|
||||
<span class="designing-lane-mock-label">Newsletter</span>
|
||||
<span class="designing-lane-mock-title">Subscribe to updates</span>
|
||||
<div class="designing-lane-product-row">
|
||||
<span class="designing-lane-product-k">Users</span>
|
||||
<span class="designing-lane-product-v">12,482</span>
|
||||
</div>
|
||||
<div class="designing-lane-product-row">
|
||||
<span class="designing-lane-product-k">Active now</span>
|
||||
<span class="designing-lane-product-v">1,207</span>
|
||||
</div>
|
||||
<div class="designing-lane-product-row">
|
||||
<span class="designing-lane-product-k">Conversion</span>
|
||||
<span class="designing-lane-product-v">4.8%</span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
+10
-23
@@ -71,7 +71,7 @@ import '../styles/testimonials.css';
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
<a href="/designing" class="ks-button ks-button-secondary">How it works</a>
|
||||
<a href="/designing" class="ks-button ks-button-ghost">How it works</a>
|
||||
</div>
|
||||
|
||||
<div class="hero-rebuild-logos" aria-label="AI coding harnesses Impeccable works with">
|
||||
@@ -250,7 +250,7 @@ import '../styles/testimonials.css';
|
||||
<div class="slop-teaser-head">
|
||||
<h2 id="slop-teaser-title" class="slop-teaser-title">Desloppification</h2>
|
||||
<p class="slop-teaser-body">
|
||||
Skills can't make a model fundamentally better at design. What they can do is remove inherent bias: the AI slop tells, the bad defaults, across every design discipline. That's what Impeccable does.
|
||||
Impeccable strips the AI slop tells and bad defaults out of every design discipline, from type to motion to copy. A skill can't make the model a better designer; it can clear the reflexes that make its output look generated.
|
||||
</p>
|
||||
<div class="slop-teaser-actions">
|
||||
<a class="slop-teaser-cta-primary" href="/slop">
|
||||
@@ -541,11 +541,13 @@ import '../styles/testimonials.css';
|
||||
<span class="why-live-pick-note">more elegant<span class="why-live-pick-caret"></span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="why-live-gbar">
|
||||
<span class="why-live-gbar-brand">/</span>
|
||||
<span class="why-live-gbar-cmd">bolder</span>
|
||||
<span class="why-live-gbar-count">×3</span>
|
||||
<span class="why-live-gbar-go">Go →</span>
|
||||
<div class="why-live-ctx live-demo-ctx" data-phase="configuring">
|
||||
<div class="live-demo-ctx-row live-demo-ctx-row--configure">
|
||||
<span class="live-demo-ctx-pill">bolder<span class="live-demo-ctx-pill-caret" aria-hidden="true">▾</span></span>
|
||||
<span class="live-demo-ctx-input"><span class="live-demo-ctx-caret"></span></span>
|
||||
<span class="live-demo-ctx-count">×3</span>
|
||||
<span class="live-demo-ctx-go">Go <span aria-hidden="true">→</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -659,22 +661,7 @@ import '../styles/testimonials.css';
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ol class="downloads-rebuild-examples">
|
||||
<li>
|
||||
<code><span class="downloads-rebuild-slash">/</span>impeccable redo this hero</code>
|
||||
<span>Let the skill pick the approach. No command names to memorize.</span>
|
||||
</li>
|
||||
<li>
|
||||
<code><span class="downloads-rebuild-slash">/</span>impeccable audit checkout</code>
|
||||
<span>Reach for a command by name. Type <code>/impeccable</code> alone to see all 23.</span>
|
||||
</li>
|
||||
<li>
|
||||
<code><span class="downloads-rebuild-slash">/</span>impeccable pin audit</code>
|
||||
<span>Pin your favorites. <code>/audit</code> becomes a standalone shortcut.</span>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p class="downloads-rebuild-more">Go deeper: <a href="/designing">Designing with Impeccable</a> · <a href="/docs">the command docs</a></p>
|
||||
<p class="downloads-rebuild-more">Get started: <a href="/designing">Designing with Impeccable</a> · <a href="/docs">the command docs</a></p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.8 MiB |
@@ -240,15 +240,13 @@ export class PeriodicTable {
|
||||
el.style.cssText = `
|
||||
width: 56px;
|
||||
height: 64px;
|
||||
background: ${colors.bg};
|
||||
border: 1.5px solid ${colors.border};
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
||||
transition: transform 0.15s ease, border-color 0.15s ease;
|
||||
position: relative;
|
||||
font-family: inherit;
|
||||
padding: 0;
|
||||
@@ -328,19 +326,16 @@ export class PeriodicTable {
|
||||
// Hover/focus: show tooltip
|
||||
const activate = () => {
|
||||
el.style.transform = 'translateY(-2px)';
|
||||
el.style.boxShadow = `0 4px 12px ${colors.border}40`;
|
||||
this.showTooltip(el, cmd);
|
||||
|
||||
if (this.activeElement && this.activeElement !== el) {
|
||||
this.activeElement.style.transform = 'translateY(0)';
|
||||
this.activeElement.style.boxShadow = 'none';
|
||||
}
|
||||
this.activeElement = el;
|
||||
};
|
||||
|
||||
const deactivate = () => {
|
||||
el.style.transform = 'translateY(0)';
|
||||
el.style.boxShadow = 'none';
|
||||
this.hideTooltip();
|
||||
};
|
||||
|
||||
|
||||
@@ -9,6 +9,11 @@ let sourceCache = {}; // Cache fetched source content
|
||||
|
||||
const MOBILE_BREAKPOINT = 900;
|
||||
|
||||
// Setup / management commands that aren't "steering" verbs. They're kept off
|
||||
// the command palette (fisheye + mobile carousel) but still appear in the
|
||||
// periodic table (rendered separately by framework-viz.js).
|
||||
const PALETTE_EXCLUDED = new Set(['impeccable', 'init', 'extract', 'document', 'live']);
|
||||
|
||||
function isMobile() {
|
||||
return window.innerWidth <= MOBILE_BREAKPOINT;
|
||||
}
|
||||
@@ -75,7 +80,7 @@ function renderDesktopLayout(container, commands) {
|
||||
// too (when they were rendered as 'impeccable craft' etc.) but are now
|
||||
// first-class sub-commands that should appear in the gallery.
|
||||
const deprecated = new Set(['teach-impeccable', 'frontend-design', 'arrange', 'normalize', 'onboard', 'impeccable craft', 'impeccable teach', 'impeccable extract']);
|
||||
const filteredCommands = commands.filter(c => !deprecated.has(c.id));
|
||||
const filteredCommands = commands.filter(c => !deprecated.has(c.id) && !PALETTE_EXCLUDED.has(c.id));
|
||||
|
||||
const categoryOrder = ['create', 'evaluate', 'refine', 'simplify', 'harden', 'system'];
|
||||
const categoryLabelsShort = {
|
||||
@@ -308,7 +313,7 @@ function setupFisheyeList(commands, headerIndices = []) {
|
||||
// to a fractional "center index" which drives everything.
|
||||
|
||||
const BASE_H = 36; // height of the center (scale=1) item
|
||||
const MIN_SCALE = 0.35;
|
||||
const MIN_SCALE = 0.52; // off-center items stay legibly sized, not microscopic
|
||||
const RADIUS = 5;
|
||||
const count = items.length;
|
||||
const listH = list.clientHeight;
|
||||
@@ -367,7 +372,10 @@ function setupFisheyeList(commands, headerIndices = []) {
|
||||
items.forEach((item, i) => {
|
||||
const h = heights[i];
|
||||
const scale = getScale(Math.abs(i - center));
|
||||
const opacity = 0.25 + (scale - MIN_SCALE) / (1 - MIN_SCALE) * 0.75;
|
||||
// Floor at 0.62 so off-center command names stay readable (WCAG): the
|
||||
// full vocabulary is the point of this view. Focus still reads clearly
|
||||
// via scale + the gold/weight active state, not by crushing legibility.
|
||||
const opacity = 0.62 + (scale - MIN_SCALE) / (1 - MIN_SCALE) * 0.38;
|
||||
|
||||
item.style.top = `${y}px`;
|
||||
item.style.transform = `scale(${scale})`;
|
||||
@@ -478,6 +486,9 @@ function truncateDescription(text, maxLen = 120) {
|
||||
// ============================================
|
||||
|
||||
function renderMobileLayout(container, commands) {
|
||||
// Keep setup/management commands off the palette (they stay in the periodic
|
||||
// table); match the desktop fisheye filter.
|
||||
commands = commands.filter(c => !PALETTE_EXCLUDED.has(c.id));
|
||||
// Build carousel pills
|
||||
// Carousel pills show bare command names for sub-commands, and /impeccable
|
||||
// for the root entry.
|
||||
|
||||
@@ -34,13 +34,13 @@ export const skillFocusAreas = {
|
||||
// detail line communicates what bad-default we catch — not what we teach.
|
||||
export const slopFocusAreas = {
|
||||
'impeccable': [
|
||||
{ area: 'Typography', detail: 'No Inter monoculture. No flat hierarchy. No all-caps body.' },
|
||||
{ area: 'Color & Contrast', detail: 'No purple gradients. No sub-WCAG text. No washed pastels.' },
|
||||
{ area: 'Spatial Design', detail: 'No cards in cards. No identical grids. No template layouts.' },
|
||||
{ area: 'Responsive', detail: 'No stiff breakpoints. No mobile-as-afterthought.' },
|
||||
{ area: 'Interaction', detail: 'No modal abuse. No generic CTAs. No gradient text.' },
|
||||
{ area: 'Motion', detail: 'No bouncy easing. No decorative fades. No spring overshoot.' },
|
||||
{ area: 'UX Writing', detail: 'No "Welcome to our platform." No em dashes. No "let\'s dive in".' }
|
||||
{ area: 'Typography', detail: 'A type scale with real contrast, set in a face chosen on purpose, not Inter by reflex.' },
|
||||
{ area: 'Color & Contrast', detail: 'Palettes that clear WCAG and commit to a hue. The purple-gradient default never ships.' },
|
||||
{ area: 'Spatial Design', detail: 'Structure from spacing and rhythm, not a grid of identical cards nested in more cards.' },
|
||||
{ area: 'Responsive', detail: 'Built for the small screen first, with breakpoints that follow the content.' },
|
||||
{ area: 'Interaction', detail: 'Honest states and clear affordances, without defaulting to a modal or gradient text.' },
|
||||
{ area: 'Motion', detail: 'Motion that eases like physics and settles. Nothing bounces or springs past its mark.' },
|
||||
{ area: 'UX Writing', detail: 'Specific copy that names what the thing does, not "Welcome to our platform."' }
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
+22
-34
@@ -1,56 +1,44 @@
|
||||
// Theme toggle - supports light, dark, and system preference
|
||||
// Theme toggle — light / dark with localStorage persistence.
|
||||
|
||||
const STORAGE_KEY = 'impeccable-theme';
|
||||
|
||||
function getStoredTheme() {
|
||||
export function getStoredTheme() {
|
||||
return localStorage.getItem(STORAGE_KEY);
|
||||
}
|
||||
|
||||
function setStoredTheme(theme) {
|
||||
export function setStoredTheme(theme) {
|
||||
localStorage.setItem(STORAGE_KEY, theme);
|
||||
}
|
||||
|
||||
function applyTheme(theme) {
|
||||
export function applyTheme(theme) {
|
||||
const html = document.documentElement;
|
||||
const resolved = theme === 'light' ? 'light' : 'dark';
|
||||
|
||||
// Remove both classes first
|
||||
html.classList.remove('light', 'dark');
|
||||
html.classList.add(resolved);
|
||||
|
||||
if (theme === 'light') {
|
||||
html.classList.add('light');
|
||||
} else if (theme === 'dark') {
|
||||
html.classList.add('dark');
|
||||
const meta = document.querySelector('meta[name="theme-color"]');
|
||||
if (meta) {
|
||||
meta.setAttribute('content', resolved === 'light' ? '#f7f4ef' : '#010101');
|
||||
}
|
||||
// 'system' = no class, falls back to media query
|
||||
|
||||
// Update active state on buttons
|
||||
document.querySelectorAll('.theme-toggle-btn').forEach(btn => {
|
||||
btn.classList.toggle('active', btn.dataset.theme === theme);
|
||||
document.querySelectorAll('[data-theme-toggle]').forEach((btn) => {
|
||||
const next = resolved === 'light' ? 'dark' : 'light';
|
||||
btn.setAttribute('aria-label', resolved === 'light' ? 'Switch to dark mode' : 'Switch to light mode');
|
||||
btn.setAttribute('title', resolved === 'light' ? 'Dark mode' : 'Light mode');
|
||||
btn.dataset.nextTheme = next;
|
||||
});
|
||||
}
|
||||
|
||||
export function initThemeToggle() {
|
||||
const toggle = document.querySelector('.theme-toggle');
|
||||
if (!toggle) return;
|
||||
const stored = getStoredTheme();
|
||||
applyTheme(stored === 'light' ? 'light' : 'dark');
|
||||
|
||||
// Get stored theme or default to system
|
||||
const storedTheme = getStoredTheme() || 'system';
|
||||
applyTheme(storedTheme);
|
||||
|
||||
// Handle button clicks
|
||||
toggle.addEventListener('click', (e) => {
|
||||
const btn = e.target.closest('.theme-toggle-btn');
|
||||
if (!btn) return;
|
||||
|
||||
const theme = btn.dataset.theme;
|
||||
setStoredTheme(theme);
|
||||
applyTheme(theme);
|
||||
});
|
||||
|
||||
// Listen for system preference changes (only matters when in 'system' mode)
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
|
||||
if (getStoredTheme() === 'system' || !getStoredTheme()) {
|
||||
applyTheme('system');
|
||||
}
|
||||
document.querySelectorAll('[data-theme-toggle]').forEach((btn) => {
|
||||
btn.addEventListener('click', () => {
|
||||
const next = btn.dataset.nextTheme || (document.documentElement.classList.contains('light') ? 'dark' : 'light');
|
||||
setStoredTheme(next);
|
||||
applyTheme(next);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -98,10 +98,11 @@
|
||||
.cf-items strong { color: var(--ks-champagne); font-weight: 600; }
|
||||
.cf-items code {
|
||||
font-family: var(--ks-mono);
|
||||
font-size: 0.92em;
|
||||
color: var(--ks-kinpaku);
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
font-size: 0.84em;
|
||||
color: var(--ks-code-fg);
|
||||
background: var(--ks-code-bg);
|
||||
padding: var(--ks-code-pad);
|
||||
border-radius: var(--ks-code-radius);
|
||||
}
|
||||
.cf-items a {
|
||||
color: var(--ks-patina);
|
||||
@@ -329,10 +330,11 @@
|
||||
.cf-faq-answer strong { color: var(--ks-champagne); font-weight: 600; }
|
||||
.cf-faq-answer code {
|
||||
font-family: var(--ks-mono);
|
||||
font-size: 0.92em;
|
||||
color: var(--ks-kinpaku);
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
font-size: 0.84em;
|
||||
color: var(--ks-code-fg);
|
||||
background: var(--ks-code-bg);
|
||||
padding: var(--ks-code-pad);
|
||||
border-radius: var(--ks-code-radius);
|
||||
}
|
||||
.cf-faq-answer a {
|
||||
color: var(--ks-patina);
|
||||
|
||||
@@ -46,11 +46,22 @@
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.kinpaku-system-page a {
|
||||
.kinpaku-system-page a:not(.ks-brand) {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Brand lockup — kinpaku gold on dark surfaces; html.light swaps to ink
|
||||
(see light-mode.css) to match impeccable-logo-on-light.svg. */
|
||||
.kinpaku-system-page a.ks-brand {
|
||||
color: var(--ks-kinpaku);
|
||||
}
|
||||
|
||||
.kinpaku-system-page a.ks-brand .ks-mark,
|
||||
.kinpaku-system-page a.ks-brand .ks-wordmark {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.kinpaku-system-page button,
|
||||
.kinpaku-system-page input,
|
||||
.kinpaku-system-page select {
|
||||
|
||||
@@ -47,10 +47,12 @@
|
||||
|
||||
.designing-kinpaku code {
|
||||
font-family: var(--ks-mono);
|
||||
color: var(--ks-kinpaku);
|
||||
background: transparent;
|
||||
font-size: 0.84em;
|
||||
color: var(--ks-code-fg);
|
||||
background: var(--ks-code-bg);
|
||||
border: 0;
|
||||
padding: 0;
|
||||
padding: var(--ks-code-pad);
|
||||
border-radius: var(--ks-code-radius);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
@@ -272,8 +274,10 @@
|
||||
|
||||
.designing-kinpaku .designing-loop-name {
|
||||
color: var(--ks-champagne);
|
||||
font-family: var(--ks-font-display);
|
||||
font-weight: 300;
|
||||
/* Pinstripe is single-weight and reads broken at ~1.5–2rem; wordmark
|
||||
carries real stroke weight at compass-label scale (cf. iterate-name). */
|
||||
font-family: var(--ks-font-wordmark);
|
||||
font-weight: 600;
|
||||
font-size: clamp(1.5rem, 2.2vw, 2rem);
|
||||
line-height: 1.05;
|
||||
letter-spacing: 0.01em;
|
||||
@@ -444,7 +448,7 @@
|
||||
============================================================================ */
|
||||
|
||||
.designing-kinpaku .designing-phase-sub code {
|
||||
color: var(--ks-kinpaku);
|
||||
color: var(--ks-code-fg);
|
||||
}
|
||||
|
||||
.designing-kinpaku .designing-phase-commands {
|
||||
@@ -459,7 +463,7 @@
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 8px 16px;
|
||||
background: oklch(11% 0.006 95);
|
||||
background: oklch(11% 0 0);
|
||||
border: 1px solid var(--ks-rule);
|
||||
border-radius: 2px;
|
||||
color: var(--ks-kinpaku);
|
||||
@@ -530,7 +534,7 @@
|
||||
.designing-kinpaku .docs-viz-file-header {
|
||||
padding: 14px 18px;
|
||||
border-bottom: 1px solid var(--ks-rule);
|
||||
background: oklch(13% 0.006 95);
|
||||
background: oklch(13% 0 0);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
@@ -740,7 +744,7 @@
|
||||
frame opposite it. */
|
||||
.designing-kinpaku .designing-iterate-terminal {
|
||||
padding: 20px 22px;
|
||||
background: oklch(13% 0.006 95);
|
||||
background: oklch(13% 0 0);
|
||||
border: 1px solid var(--ks-rule);
|
||||
border-radius: 4px;
|
||||
font-family: var(--ks-mono);
|
||||
@@ -763,7 +767,7 @@
|
||||
|
||||
/* Live frame mock — restyle docs-viz-live-* on dark surface */
|
||||
.designing-kinpaku .docs-viz-live-frame {
|
||||
background: oklch(13% 0.006 95);
|
||||
background: oklch(13% 0 0);
|
||||
border: 1px solid var(--ks-rule);
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
@@ -774,7 +778,7 @@
|
||||
gap: 8px;
|
||||
padding: 10px 14px;
|
||||
border-bottom: 1px solid var(--ks-rule);
|
||||
background: oklch(11% 0.006 95);
|
||||
background: oklch(11% 0 0);
|
||||
}
|
||||
.designing-kinpaku .docs-viz-live-dot {
|
||||
width: 9px;
|
||||
@@ -804,7 +808,7 @@
|
||||
}
|
||||
.designing-kinpaku .docs-viz-live-target {
|
||||
width: 100%;
|
||||
background: oklch(11% 0.006 95);
|
||||
background: oklch(11% 0 0);
|
||||
border: 1px solid var(--ks-rule);
|
||||
border-radius: 4px;
|
||||
padding: 20px;
|
||||
@@ -832,7 +836,7 @@
|
||||
.designing-kinpaku .docs-viz-live-btn {
|
||||
align-self: start;
|
||||
padding: 8px 14px;
|
||||
background: var(--ks-kinpaku-pale);
|
||||
background: var(--ks-kinpaku);
|
||||
color: var(--ks-lacquer-deep);
|
||||
border: 0;
|
||||
border-radius: 2px;
|
||||
@@ -846,8 +850,7 @@
|
||||
position: absolute;
|
||||
inset: 14px 14px 108px;
|
||||
border: 1.5px solid var(--ks-kinpaku);
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 0 0 4px oklch(78% 0.12 82 / 0.1);
|
||||
border-radius: 3px;
|
||||
pointer-events: none;
|
||||
}
|
||||
/* top: auto is required — the base/legacy rule sets top: 16px, and leaving it
|
||||
@@ -863,11 +866,9 @@
|
||||
gap: 6px;
|
||||
padding: 6px;
|
||||
background: var(--ks-lacquer-deep);
|
||||
border: 1.5px solid var(--ks-kinpaku);
|
||||
border-radius: 6px;
|
||||
box-shadow:
|
||||
0 0 0 1px oklch(78% 0.12 82 / 0.18),
|
||||
0 6px 18px oklch(0% 0 0 / 0.4);
|
||||
border: 1px solid oklch(92% 0 0 / 0.13);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 6px 18px -4px oklch(0% 0 0 / 0.5);
|
||||
}
|
||||
.designing-kinpaku .docs-viz-live-ctx-nav,
|
||||
.designing-kinpaku .docs-viz-live-ctx-discard,
|
||||
@@ -885,7 +886,7 @@
|
||||
padding: 4px 6px;
|
||||
}
|
||||
.designing-kinpaku .docs-viz-live-ctx-accept {
|
||||
background: var(--ks-kinpaku-pale);
|
||||
background: var(--ks-kinpaku);
|
||||
color: var(--ks-lacquer-deep);
|
||||
border-radius: 3px;
|
||||
font-weight: 500;
|
||||
@@ -916,11 +917,9 @@
|
||||
padding: 5px 7px;
|
||||
max-width: calc(100% - 24px);
|
||||
background: var(--ks-lacquer-deep);
|
||||
border: 1.5px solid var(--ks-kinpaku);
|
||||
border-radius: 9px;
|
||||
box-shadow:
|
||||
0 0 0 1px oklch(78% 0.12 82 / 0.18),
|
||||
0 10px 28px oklch(0% 0 0 / 0.28);
|
||||
border: 1px solid oklch(92% 0 0 / 0.13);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 10px 28px -6px oklch(0% 0 0 / 0.5);
|
||||
}
|
||||
.designing-kinpaku .docs-viz-live-gbar-mark {
|
||||
display: inline-flex;
|
||||
@@ -944,7 +943,7 @@
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.designing-kinpaku .docs-viz-live-gbar-btn.is-active {
|
||||
background: oklch(78% 0.12 82 / 0.18);
|
||||
background: oklch(27% 0 0);
|
||||
color: var(--ks-kinpaku);
|
||||
}
|
||||
.designing-kinpaku .docs-viz-live-gbar-btn-mono {
|
||||
@@ -1029,13 +1028,12 @@
|
||||
the 3-col grid below, not as a card competing with them. */
|
||||
.designing-kinpaku .designing-polish-band {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
grid-template-columns: auto 1fr;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
padding: 18px 0;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-top: 1px solid var(--ks-rule);
|
||||
border-bottom: 1px solid var(--ks-rule);
|
||||
border-radius: 0;
|
||||
margin-bottom: 36px;
|
||||
@@ -1061,16 +1059,18 @@
|
||||
text-underline-offset: 4px;
|
||||
}
|
||||
.designing-kinpaku .designing-polish-band-meta {
|
||||
color: var(--ks-muted);
|
||||
font-family: var(--ks-mono);
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.18em;
|
||||
display: none; /* cryptic "03 · 04" step counter — removed */
|
||||
}
|
||||
|
||||
.designing-kinpaku .designing-polish-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 24px;
|
||||
/* Flatten the legacy outer box (docs-visuals adds a cream bg + L/R/B border +
|
||||
padding); the cards are the only surface, no box-in-box. */
|
||||
background: none;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
@media (max-width: 900px) {
|
||||
.designing-kinpaku .designing-polish-grid { grid-template-columns: 1fr; }
|
||||
@@ -1131,7 +1131,7 @@
|
||||
gap: 10px;
|
||||
margin: 2px 0;
|
||||
padding: 11px 14px;
|
||||
background: oklch(13% 0.006 95);
|
||||
background: oklch(13% 0 0);
|
||||
border: 1px solid var(--ks-rule);
|
||||
border-radius: 4px;
|
||||
font-family: var(--ks-mono);
|
||||
@@ -1150,10 +1150,11 @@
|
||||
}
|
||||
|
||||
.designing-kinpaku .designing-maintain-stage {
|
||||
background: var(--ks-lacquer-raised);
|
||||
border: 1px solid var(--ks-rule);
|
||||
border-radius: 4px;
|
||||
padding: 28px;
|
||||
/* No inner box — the demo sits directly in the bento tile (removing the
|
||||
box-in-box: plinth > tile > stage). */
|
||||
background: transparent;
|
||||
border: 0;
|
||||
padding: 8px 0;
|
||||
min-height: 180px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
@@ -1211,7 +1212,7 @@
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 5px 11px;
|
||||
background: oklch(13% 0.006 95);
|
||||
background: oklch(13% 0 0);
|
||||
border: 1px solid var(--ks-rule);
|
||||
border-radius: 3px;
|
||||
color: var(--ks-muted);
|
||||
@@ -1226,7 +1227,7 @@
|
||||
.designing-kinpaku .designing-extract-after {
|
||||
justify-self: end;
|
||||
padding: 8px 18px;
|
||||
background: var(--ks-kinpaku-pale);
|
||||
background: var(--ks-kinpaku);
|
||||
color: var(--ks-lacquer-deep);
|
||||
border-radius: 2px;
|
||||
font-family: var(--ks-font);
|
||||
@@ -1269,6 +1270,26 @@
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
/* Flatten the bento plinth: drop the 0.17 plinth fill + 8px gutter (which drew
|
||||
the weird gutter "borders") and the 0.07 tile fill. The two lanes sit on the
|
||||
page, split by a single center hairline. */
|
||||
.designing-kinpaku .ks-bento.designing-lanes {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
gap: 0;
|
||||
}
|
||||
.designing-kinpaku .designing-lanes .ks-bento-tile {
|
||||
background: transparent;
|
||||
padding: 0 clamp(20px, 3.5vw, 44px);
|
||||
}
|
||||
.designing-kinpaku .designing-lanes .ks-bento-tile:first-child {
|
||||
padding-left: 0;
|
||||
}
|
||||
.designing-kinpaku .designing-lanes .ks-bento-tile + .ks-bento-tile {
|
||||
border-left: 1px solid var(--ks-rule);
|
||||
}
|
||||
|
||||
.designing-kinpaku .designing-lane-kind {
|
||||
color: var(--ks-kinpaku);
|
||||
font-family: var(--ks-mono);
|
||||
@@ -1283,41 +1304,85 @@
|
||||
.designing-kinpaku .designing-lane-rule {
|
||||
color: var(--ks-text);
|
||||
font-size: 1rem;
|
||||
line-height: 1.6;
|
||||
line-height: 1.65;
|
||||
margin: 0;
|
||||
text-wrap: pretty;
|
||||
}
|
||||
.designing-kinpaku .designing-lane-rule strong {
|
||||
color: var(--ks-champagne);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* The brand mock title used the pinstripe display face at ~1.6rem, which reads
|
||||
broken/washed at that size (Two-Face rule); use the clean body face. */
|
||||
.designing-kinpaku .designing-lane-mock-title {
|
||||
font-family: var(--ks-font);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.designing-kinpaku .designing-lane-mock {
|
||||
margin-top: 6px;
|
||||
padding: 24px;
|
||||
background: oklch(11% 0.006 95);
|
||||
margin-top: 18px;
|
||||
padding: 20px 18px;
|
||||
background: var(--ks-lacquer-raised);
|
||||
border: 1px solid var(--ks-rule);
|
||||
border-radius: 4px;
|
||||
min-height: 110px;
|
||||
min-height: 120px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
justify-content: center;
|
||||
}
|
||||
.designing-kinpaku .designing-lane-mock--brand {
|
||||
align-items: flex-start;
|
||||
}
|
||||
.designing-kinpaku .designing-lane-mock--product {
|
||||
align-items: flex-start;
|
||||
align-items: stretch;
|
||||
padding: 0;
|
||||
gap: 0;
|
||||
}
|
||||
.designing-kinpaku .designing-lane-mock-label {
|
||||
color: var(--ks-patina);
|
||||
font-family: var(--ks-mono);
|
||||
font-size: 0.66rem;
|
||||
font-size: 0.62rem;
|
||||
letter-spacing: 0.2em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.designing-kinpaku .designing-lane-mock--brand .designing-lane-mock-title {
|
||||
color: var(--ks-champagne);
|
||||
font-family: var(--ks-font-display);
|
||||
font-weight: 300;
|
||||
font-size: 1.6rem;
|
||||
font-family: var(--ks-font);
|
||||
font-weight: 500;
|
||||
font-size: 1.35rem;
|
||||
line-height: 1.15;
|
||||
}
|
||||
.designing-kinpaku .designing-lane-mock-accent {
|
||||
color: var(--ks-kinpaku);
|
||||
}
|
||||
.designing-kinpaku .designing-lane-product-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
gap: 16px;
|
||||
padding: 12px 16px;
|
||||
border-bottom: 1px solid var(--ks-rule);
|
||||
}
|
||||
.designing-kinpaku .designing-lane-product-row:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
.designing-kinpaku .designing-lane-product-k {
|
||||
font-family: var(--ks-mono);
|
||||
font-size: 0.62rem;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
color: var(--ks-text-muted);
|
||||
}
|
||||
.designing-kinpaku .designing-lane-product-v {
|
||||
font-family: var(--ks-font);
|
||||
font-size: 0.92rem;
|
||||
font-weight: 500;
|
||||
color: var(--ks-champagne);
|
||||
}
|
||||
|
||||
/* Legacy single-line product mock title — kept for any downstream refs. */
|
||||
.designing-kinpaku .designing-lane-mock--product .designing-lane-mock-title {
|
||||
color: var(--ks-champagne);
|
||||
font-family: var(--ks-font);
|
||||
@@ -1344,16 +1409,20 @@
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: grid;
|
||||
gap: 18px;
|
||||
gap: 0; /* divided list: items separated by hairlines, not gaps */
|
||||
}
|
||||
.designing-kinpaku .designing-avoid li {
|
||||
display: grid;
|
||||
grid-template-columns: 28px 1fr;
|
||||
gap: 14px;
|
||||
padding: 22px 24px;
|
||||
background: var(--ks-lacquer-raised);
|
||||
border: 1px solid var(--ks-rule);
|
||||
border-radius: 2px;
|
||||
padding: 22px 0;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-bottom: 1px solid var(--ks-rule);
|
||||
border-radius: 0;
|
||||
}
|
||||
.designing-kinpaku .designing-avoid li:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
.designing-kinpaku .designing-avoid-x {
|
||||
color: var(--ks-vermilion);
|
||||
@@ -1370,7 +1439,7 @@
|
||||
font-size: 1rem;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.designing-kinpaku .designing-avoid-title code { color: var(--ks-kinpaku); }
|
||||
.designing-kinpaku .designing-avoid-title code { color: var(--ks-code-fg); }
|
||||
.designing-kinpaku .designing-avoid-desc {
|
||||
color: var(--ks-text);
|
||||
font-size: 0.94rem;
|
||||
|
||||
@@ -396,7 +396,7 @@
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background: transparent;
|
||||
color: var(--ks-champagne);
|
||||
color: var(--ks-code-fg);
|
||||
font-family: var(--ks-mono);
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
@@ -471,7 +471,7 @@
|
||||
.detector-table-panel td code {
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
color: var(--ks-champagne);
|
||||
color: var(--ks-code-fg);
|
||||
font-family: var(--ks-mono);
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
|
||||
@@ -1044,17 +1044,17 @@
|
||||
.docs-kinpaku .prose code {
|
||||
font-family: var(--ks-mono);
|
||||
font-size: 0.84em;
|
||||
color: var(--ks-champagne);
|
||||
background: var(--ks-graphite-2);
|
||||
color: var(--ks-code-fg);
|
||||
background: var(--ks-code-bg);
|
||||
border: 0;
|
||||
padding: 4px 7px;
|
||||
border-radius: 3px;
|
||||
padding: var(--ks-code-pad);
|
||||
border-radius: var(--ks-code-radius);
|
||||
}
|
||||
|
||||
/* Inline code that is itself a link — get the kinpaku cue back, since
|
||||
the link semantic is the meaningful one. */
|
||||
.docs-kinpaku .prose a code {
|
||||
color: var(--ks-kinpaku);
|
||||
color: var(--ks-code-cmd);
|
||||
}
|
||||
|
||||
/* Fenced code blocks — deep lacquer terminal. Shiki injects inline
|
||||
@@ -1067,10 +1067,10 @@
|
||||
.docs-kinpaku .prose pre.astro-code {
|
||||
margin: 0;
|
||||
padding: 22px 24px;
|
||||
background: var(--ks-lacquer-deep) !important;
|
||||
color: oklch(86% 0.025 82) !important;
|
||||
border: 1px solid var(--ks-rule);
|
||||
border-radius: 2px;
|
||||
background: var(--ks-code-block-bg) !important;
|
||||
color: var(--ks-code-block-fg) !important;
|
||||
border: 1px solid var(--ks-code-block-border);
|
||||
border-radius: var(--ks-code-block-radius);
|
||||
overflow-x: auto;
|
||||
font-family: var(--ks-mono);
|
||||
font-size: 0.84rem;
|
||||
@@ -1227,7 +1227,7 @@
|
||||
background: var(--ks-lacquer-raised);
|
||||
}
|
||||
|
||||
.docs-kinpaku .docs-command-demo .split-comparison {
|
||||
.docs-kinpaku .docs-command-demo :is(.split-comparison, .demo-split-comparison) {
|
||||
max-width: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@@ -1253,6 +1253,9 @@
|
||||
}
|
||||
|
||||
.docs-kinpaku .docs-command-demo .split-after {
|
||||
/* Doc.astro initSplitCompare uses skewAngle: 0 — vertical seam, not the
|
||||
angled default from sub-pages.css / main.css. */
|
||||
clip-path: polygon(50% 0%, 100% 0%, 100% 100%, 50% 100%);
|
||||
background:
|
||||
linear-gradient(90deg, oklch(8% 0.006 95 / 0.92), oklch(10% 0.006 95 / 0.96)),
|
||||
radial-gradient(circle at 82% 26%, oklch(78% 0.12 82 / 0.14), transparent 12rem);
|
||||
@@ -1261,6 +1264,7 @@
|
||||
.docs-kinpaku .docs-command-demo .split-divider {
|
||||
background: var(--ks-kinpaku);
|
||||
box-shadow: 0 0 20px oklch(78% 0.12 82 / 0.4);
|
||||
transform: translateX(-50%) !important;
|
||||
}
|
||||
|
||||
.docs-kinpaku .docs-command-demo .demo-caption {
|
||||
|
||||
@@ -3347,10 +3347,10 @@
|
||||
.neon-case-command .code-block {
|
||||
margin: 0;
|
||||
padding: var(--spacing-md);
|
||||
background: var(--ks-lacquer);
|
||||
color: var(--ks-champagne);
|
||||
border: 1px solid var(--ks-rule);
|
||||
border-radius: 2px;
|
||||
background: var(--ks-code-block-bg);
|
||||
color: var(--ks-code-block-fg);
|
||||
border: 1px solid var(--ks-code-block-border);
|
||||
border-radius: var(--ks-code-block-radius);
|
||||
overflow-x: auto;
|
||||
font-family: var(--ks-mono);
|
||||
font-size: 0.8125rem;
|
||||
|
||||
+247
-185
@@ -6,18 +6,12 @@
|
||||
@import "./kinpaku-tokens.css";
|
||||
|
||||
.home-kinpaku {
|
||||
/* Intentional overrides: the homepage uses brighter rule alphas because
|
||||
bento tile borders need to read against busy backgrounds. The default
|
||||
--ks-rule from kinpaku-tokens.css is the quieter doctrinal value used
|
||||
on /design-system and elsewhere. */
|
||||
--ks-rule: oklch(58% 0.065 82 / 0.48);
|
||||
--ks-rule-strong: oklch(74% 0.09 82 / 0.68);
|
||||
/* --ks-rule / --ks-rule-strong inherit the global tokens (neutral default,
|
||||
gold strong); the homepage no longer diverges on border color. */
|
||||
|
||||
/* Slightly lighter muted text on the homepage's busier surfaces. The
|
||||
default --ks-text-muted (63% L) is used everywhere else; here we lift
|
||||
to 65% so captions stay readable against bento tile fills. Kept under
|
||||
the old --ks-muted name for code-churn reasons. */
|
||||
--ks-muted: oklch(65% 0.024 82);
|
||||
/* Legacy alias — homepage code reads --ks-muted; map it to the global muted
|
||||
text token (no divergent value). */
|
||||
--ks-muted: var(--ks-text-muted);
|
||||
|
||||
/* Legacy alias — homepage code still reads --ks-faint and --ks-oxide. The
|
||||
forward names live in kinpaku-tokens.css as --ks-text-faint and
|
||||
@@ -98,12 +92,13 @@
|
||||
(3) keep the chip treatment subtle so it doesn't drag attention off the
|
||||
prose. */
|
||||
.home-kinpaku code {
|
||||
color: oklch(82% 0.11 82);
|
||||
background: oklch(78% 0.12 82 / 0.08);
|
||||
border: 1px solid oklch(78% 0.12 82 / 0.14);
|
||||
border-radius: 3px;
|
||||
color: var(--ks-code-fg);
|
||||
background: var(--ks-code-bg);
|
||||
border: 0;
|
||||
border-radius: var(--ks-code-radius);
|
||||
font-family: var(--ks-mono);
|
||||
font-size: 0.88em;
|
||||
padding: 0.05em 0.4em;
|
||||
padding: var(--ks-code-pad);
|
||||
}
|
||||
|
||||
.home-kinpaku ::selection {
|
||||
@@ -214,7 +209,7 @@
|
||||
|
||||
.home-kinpaku .section-lead,
|
||||
.home-kinpaku .section-subtitle {
|
||||
max-width: 68ch;
|
||||
max-width: 62ch; /* 68ch rendered ~86 actual chars/line; tighten into the band */
|
||||
color: var(--ks-text);
|
||||
font-size: 1.02rem;
|
||||
line-height: 1.8;
|
||||
@@ -233,7 +228,6 @@
|
||||
.home-kinpaku .downloads-rebuild-note,
|
||||
.home-kinpaku .why-panel-title,
|
||||
.home-kinpaku .live-demo-support-v,
|
||||
.home-kinpaku .downloads-rebuild-examples span,
|
||||
.home-kinpaku .downloads-rebuild-extras strong,
|
||||
.home-kinpaku .downloads-rebuild-extras span {
|
||||
text-wrap: balance;
|
||||
@@ -907,7 +901,10 @@
|
||||
padding: 24px;
|
||||
border: 1px solid var(--ks-rule);
|
||||
border-radius: 4px;
|
||||
background: oklch(9% 0.006 95 / 0.92);
|
||||
/* Was 9% on a 7% ground (~1 level in sRGB): the card body vanished into the
|
||||
page and only the hairline hinted at an edge. Lift to a clear raised
|
||||
neutral tone so the specimen card reads as a crisp object. */
|
||||
background: oklch(15% 0 0);
|
||||
}
|
||||
|
||||
.home-kinpaku .foundation-column:hover .foundation-card {
|
||||
@@ -940,15 +937,11 @@
|
||||
|
||||
.home-kinpaku .foundation-plinth {
|
||||
border-color: var(--ks-rule);
|
||||
/* Neutral hatch (was kinpaku gold, which washed the section champagne) on a
|
||||
neutral base, for a crisp pedestal that matches the de-warmed section. */
|
||||
background:
|
||||
repeating-linear-gradient(45deg, oklch(78% 0.12 82 / 0.12), oklch(78% 0.12 82 / 0.12) 1px, transparent 1px, transparent 9px),
|
||||
oklch(10% 0.006 95 / 0.42);
|
||||
/* Soften the bottom so the plinth fades into the section bg like a real
|
||||
shadow instead of terminating in a hard horizontal line. Mask fades the
|
||||
bottom 45% of the element, taking the diagonal stripes + side borders
|
||||
down with it. */
|
||||
-webkit-mask-image: linear-gradient(to bottom, black 0%, black 55%, transparent 100%);
|
||||
mask-image: linear-gradient(to bottom, black 0%, black 55%, transparent 100%);
|
||||
repeating-linear-gradient(45deg, oklch(80% 0 0 / 0.07), oklch(80% 0 0 / 0.07) 1px, transparent 1px, transparent 9px),
|
||||
oklch(10% 0 0 / 0.42);
|
||||
}
|
||||
|
||||
.home-kinpaku .language-intro-row {
|
||||
@@ -982,6 +975,8 @@
|
||||
surface (flat oklch(0.17 0 0), no border, no shadow). All inner demo
|
||||
surfaces sit transparently on top — no plinth-in-plinth, no nested rings. */
|
||||
.home-kinpaku .magazine-container {
|
||||
/* Solid panel, no border. The demo preview inside gets its own thin border
|
||||
(see .spread-demo-area below) and inherits this fill. */
|
||||
border: 0;
|
||||
border-radius: 2px;
|
||||
background: oklch(0.17 0 0);
|
||||
@@ -989,7 +984,7 @@
|
||||
}
|
||||
|
||||
.home-kinpaku .fisheye-item {
|
||||
color: var(--ks-muted);
|
||||
color: var(--ks-text);
|
||||
font-family: var(--ks-font);
|
||||
font-size: 1.18rem;
|
||||
}
|
||||
@@ -1018,13 +1013,23 @@
|
||||
}
|
||||
|
||||
.home-kinpaku .spread-flow-cmd {
|
||||
color: var(--ks-kinpaku);
|
||||
background: oklch(78% 0.12 82 / 0.08);
|
||||
border: 1px solid oklch(78% 0.12 82 / 0.18);
|
||||
color: var(--ks-code-cmd);
|
||||
background: var(--ks-code-bg);
|
||||
border: 0;
|
||||
border-radius: var(--ks-code-radius);
|
||||
}
|
||||
|
||||
/* Inner demo surfaces are transparent — the plinth lives on the outer
|
||||
.magazine-container; these sit on top with no chrome of their own. */
|
||||
/* The demo's frame is the .split-container's own border; the caption sits
|
||||
outside it. Strip the leftover chrome: no grid ::before, no inner shadow. */
|
||||
.home-kinpaku .spread-demo-area .split-container {
|
||||
box-shadow: none;
|
||||
}
|
||||
.home-kinpaku .spread-demo-area .split-container::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Inner demo surfaces are transparent — they sit on the panel inside the
|
||||
framed .split-container, with no chrome of their own. */
|
||||
.home-kinpaku .spread-demo-area .demo-split-comparison .split-container,
|
||||
.home-kinpaku .terminal-preview .demo-split-comparison .split-container,
|
||||
.home-kinpaku .demo-container,
|
||||
@@ -1115,14 +1120,16 @@
|
||||
--ptable-accent: var(--ks-kinpaku);
|
||||
width: clamp(64px, 5vw, 76px) !important;
|
||||
height: clamp(76px, 5.8vw, 90px) !important;
|
||||
border-width: 1px !important;
|
||||
/* Crisp neutral card. Was a category-tinted gradient bg + strong colored
|
||||
border + muddy multi-inset shadow that read as dim blobs; now a clean
|
||||
graphite tile with a neutral hairline. Category is cued by the group label
|
||||
and the accent line below, not a muddy fill. */
|
||||
background: oklch(15% 0 0) !important;
|
||||
border: 1px solid var(--ks-rule) !important;
|
||||
border-radius: 4px !important;
|
||||
overflow: hidden;
|
||||
isolation: isolate;
|
||||
box-shadow:
|
||||
inset 0 0 0 1px oklch(100% 0 0 / 0.035),
|
||||
inset 0 -18px 34px oklch(2% 0.004 95 / 0.28),
|
||||
0 18px 42px oklch(2% 0.004 95 / 0.22) !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.home-kinpaku #framework-viz-container .ptable-element--create {
|
||||
@@ -1149,40 +1156,20 @@
|
||||
--ptable-accent: var(--cat-system-text);
|
||||
}
|
||||
|
||||
/* No gold-leaf texture overlay (was washing the tile bg) and no bottom accent
|
||||
line — the tile is a clean flat neutral surface. */
|
||||
.home-kinpaku #framework-viz-container .ptable-element::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: -1;
|
||||
background:
|
||||
radial-gradient(circle at 74% 12%, oklch(100% 0 0 / 0.09), transparent 32%),
|
||||
url("/assets/neo-kinpaku/kinpaku-gold-leaf.png") center / 190px auto;
|
||||
mix-blend-mode: screen;
|
||||
opacity: 0.055;
|
||||
pointer-events: none;
|
||||
content: none;
|
||||
}
|
||||
|
||||
.home-kinpaku #framework-viz-container .ptable-element::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
right: 12px;
|
||||
bottom: 9px;
|
||||
z-index: 0;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, transparent, var(--ptable-accent), transparent);
|
||||
opacity: 0.24;
|
||||
pointer-events: none;
|
||||
content: none;
|
||||
}
|
||||
|
||||
.home-kinpaku #framework-viz-container .ptable-element:is(:hover, :focus-visible) {
|
||||
transform: translateY(-3px) !important;
|
||||
border-color: var(--ptable-accent) !important;
|
||||
box-shadow:
|
||||
inset 0 0 0 1px oklch(100% 0 0 / 0.05),
|
||||
0 0 0 1px oklch(78% 0.12 82 / 0.12),
|
||||
0 22px 48px oklch(2% 0.004 95 / 0.36),
|
||||
0 0 26px oklch(78% 0.12 82 / 0.16) !important;
|
||||
border-color: oklch(85% 0 0 / 0.4) !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.home-kinpaku #framework-viz-container .ptable-number,
|
||||
@@ -1201,16 +1188,17 @@
|
||||
|
||||
.home-kinpaku #framework-viz-container .ptable-symbol {
|
||||
font-size: clamp(1.45rem, 1.8vw, 1.8rem) !important;
|
||||
font-weight: 300 !important;
|
||||
font-weight: 400 !important;
|
||||
letter-spacing: 0.01em;
|
||||
color: var(--ks-champagne) !important;
|
||||
}
|
||||
|
||||
.home-kinpaku #framework-viz-container .ptable-name {
|
||||
max-width: 64px !important;
|
||||
color: var(--ptable-accent) !important;
|
||||
font-size: 0.54rem !important;
|
||||
color: var(--ks-text-muted) !important;
|
||||
font-size: 0.56rem !important;
|
||||
letter-spacing: 0.04em;
|
||||
opacity: 0.72 !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.home-kinpaku #framework-viz-container .ptable-alpha {
|
||||
@@ -1222,12 +1210,14 @@
|
||||
|
||||
.home-kinpaku .spread-demo-area .demo-split-comparison .split-before,
|
||||
.home-kinpaku .terminal-preview .demo-split-comparison .split-before {
|
||||
background: oklch(10% 0.006 95);
|
||||
/* Left half inherits the panel fill — no separate background. */
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.home-kinpaku .spread-demo-area .demo-split-comparison .split-after,
|
||||
.home-kinpaku .terminal-preview .demo-split-comparison .split-after {
|
||||
background: oklch(8% 0.006 95);
|
||||
/* Right half is near-black: the clean before/after contrast. */
|
||||
background: oklch(2% 0 0);
|
||||
}
|
||||
|
||||
.home-kinpaku .demo-caption,
|
||||
@@ -1262,12 +1252,12 @@
|
||||
}
|
||||
|
||||
.home-kinpaku :is(.spread-demo-area, .terminal-preview, .mobile-demo-area) .demo-split-comparison .split-container {
|
||||
background:
|
||||
linear-gradient(90deg, oklch(78% 0.12 82 / 0.028) 1px, transparent 1px),
|
||||
linear-gradient(180deg, oklch(78% 0.12 82 / 0.022) 1px, transparent 1px),
|
||||
radial-gradient(circle at 74% 48%, oklch(70% 0.105 190 / 0.055), transparent 18rem),
|
||||
oklch(7% 0.005 95);
|
||||
background-size: 36px 36px, 36px 36px, auto, auto;
|
||||
/* No grid lines, no radial glow — the container is transparent so the before
|
||||
half shows the panel fill and the after half its own near-black. A thin
|
||||
neutral border frames the demo itself (the caption sits outside it). */
|
||||
background: transparent;
|
||||
border: 1px solid var(--ks-rule);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.home-kinpaku :is(.spread-demo-area, .terminal-preview, .mobile-demo-area) .demo-split-comparison .split-before,
|
||||
@@ -1490,7 +1480,6 @@
|
||||
— dropped, the bento structure carries the brand voice now. */
|
||||
.home-kinpaku .why-terminal,
|
||||
.home-kinpaku .why-productmd-file,
|
||||
.home-kinpaku .why-register,
|
||||
.home-kinpaku .why-ci-window,
|
||||
.home-kinpaku .why-browser,
|
||||
.home-kinpaku .why-dm-grid,
|
||||
@@ -1501,6 +1490,104 @@
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.home-kinpaku .why-register {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.home-kinpaku .why-register-label {
|
||||
color: var(--ks-text-muted);
|
||||
font-family: var(--ks-mono);
|
||||
font-size: 0.62rem;
|
||||
letter-spacing: 0.2em;
|
||||
}
|
||||
|
||||
.home-kinpaku .why-register-mock--brand,
|
||||
.home-kinpaku .why-register-mock--product {
|
||||
border: 1px solid var(--ks-rule);
|
||||
border-radius: 4px;
|
||||
background: var(--ks-lacquer-raised);
|
||||
}
|
||||
|
||||
.home-kinpaku .why-brand-hero-mono {
|
||||
color: var(--ks-text-muted);
|
||||
}
|
||||
|
||||
.home-kinpaku .why-brand-hero-title {
|
||||
color: var(--ks-champagne);
|
||||
font-family: var(--ks-font-wordmark);
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.home-kinpaku .why-brand-hero-title em {
|
||||
color: var(--ks-kinpaku);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.home-kinpaku .why-product-k {
|
||||
color: var(--ks-text-muted);
|
||||
}
|
||||
|
||||
.home-kinpaku .why-product-v {
|
||||
color: var(--ks-champagne);
|
||||
}
|
||||
|
||||
.home-kinpaku .why-product-row {
|
||||
border-color: var(--ks-rule);
|
||||
}
|
||||
|
||||
.home-kinpaku .why-productmd-file,
|
||||
.home-kinpaku .why-terminal {
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--ks-rule);
|
||||
}
|
||||
|
||||
.home-kinpaku .why-productmd-header,
|
||||
.home-kinpaku .why-productmd-footer,
|
||||
.home-kinpaku .why-terminal-header {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
/* Bento window chrome dots — one subtle traffic-light set across mocks. */
|
||||
.home-kinpaku :is(
|
||||
.why-terminal-dot,
|
||||
.why-live-dot,
|
||||
.why-visual--extension .why-browser-dot,
|
||||
.why-visual--v2 .v2-new-browser-dot
|
||||
) {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
opacity: 0.5;
|
||||
background: oklch(58% 0.012 95);
|
||||
}
|
||||
|
||||
.home-kinpaku :is(
|
||||
.why-terminal-dot,
|
||||
.why-live-dot,
|
||||
.why-visual--extension .why-browser-dot,
|
||||
.why-visual--v2 .v2-new-browser-dot
|
||||
):nth-child(1) {
|
||||
background: var(--ks-kinpaku-deep);
|
||||
}
|
||||
|
||||
.home-kinpaku :is(
|
||||
.why-terminal-dot,
|
||||
.why-live-dot,
|
||||
.why-visual--extension .why-browser-dot,
|
||||
.why-visual--v2 .v2-new-browser-dot
|
||||
):nth-child(2) {
|
||||
background: var(--ks-patina-deep);
|
||||
}
|
||||
|
||||
.home-kinpaku .why-terminal-header,
|
||||
.home-kinpaku .why-live-chrome {
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.home-kinpaku .why-panel-title {
|
||||
color: var(--ks-champagne);
|
||||
font-size: 2rem;
|
||||
@@ -1519,8 +1606,7 @@
|
||||
.home-kinpaku .why-productmd-k,
|
||||
.home-kinpaku .why-terminal-ok,
|
||||
.home-kinpaku .why-terminal-path,
|
||||
.home-kinpaku .why-dm-badge,
|
||||
.home-kinpaku .why-ci-status {
|
||||
.home-kinpaku .why-dm-badge {
|
||||
color: var(--ks-patina);
|
||||
}
|
||||
|
||||
@@ -1550,6 +1636,9 @@
|
||||
|
||||
.home-kinpaku .why-ci-header {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-height: 54px;
|
||||
padding: 14px 18px 14px 72px;
|
||||
border-bottom: 1px solid var(--ks-rule);
|
||||
@@ -1561,29 +1650,35 @@
|
||||
position: absolute;
|
||||
left: 22px;
|
||||
top: 50%;
|
||||
width: 34px;
|
||||
height: 9px;
|
||||
width: 31px;
|
||||
height: 7px;
|
||||
transform: translateY(-50%);
|
||||
background:
|
||||
radial-gradient(circle at 4px 50%, var(--ks-kinpaku) 0 3px, transparent 3.5px),
|
||||
radial-gradient(circle at 17px 50%, var(--ks-patina) 0 3px, transparent 3.5px),
|
||||
radial-gradient(circle at 30px 50%, var(--ks-kinpaku-deep) 0 3px, transparent 3.5px);
|
||||
opacity: 0.88;
|
||||
radial-gradient(circle at 3.5px 50%, var(--ks-kinpaku-deep) 0 3.5px, transparent 3.6px),
|
||||
radial-gradient(circle at 13.5px 50%, var(--ks-patina-deep) 0 3.5px, transparent 3.6px),
|
||||
radial-gradient(circle at 23.5px 50%, oklch(58% 0.012 95) 0 3.5px, transparent 3.6px);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.home-kinpaku .why-ci-branch {
|
||||
font-family: var(--ks-mono);
|
||||
color: var(--ks-champagne);
|
||||
font-size: 0.78rem;
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
|
||||
.home-kinpaku .why-ci-status {
|
||||
.home-kinpaku .why-ci-status,
|
||||
.home-kinpaku .why-ci-status--fail {
|
||||
font-family: var(--ks-mono);
|
||||
font-size: 0.62rem;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
padding: 5px 13px;
|
||||
border: 1px solid oklch(58% 0.15 35 / 0.3);
|
||||
color: var(--ks-patina);
|
||||
background:
|
||||
linear-gradient(90deg, oklch(58% 0.15 35 / 0.22), oklch(58% 0.15 35 / 0.1));
|
||||
box-shadow: inset 0 0 0 1px oklch(100% 0 0 / 0.02);
|
||||
border-radius: 999px;
|
||||
border: 1px solid oklch(58% 0.15 35 / 0.42);
|
||||
color: oklch(74% 0.14 35);
|
||||
background: oklch(58% 0.15 35 / 0.14);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.home-kinpaku .why-ci-body {
|
||||
@@ -1652,9 +1747,13 @@
|
||||
}
|
||||
|
||||
.home-kinpaku .why-visual--live {
|
||||
padding: 0;
|
||||
flex: 1;
|
||||
padding: clamp(16px, 2vw, 22px);
|
||||
overflow: hidden;
|
||||
min-height: 240px;
|
||||
min-height: min(280px, 42vw);
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
justify-content: center;
|
||||
background:
|
||||
linear-gradient(90deg, oklch(78% 0.12 82 / 0.018) 1px, transparent 1px),
|
||||
linear-gradient(180deg, oklch(78% 0.12 82 / 0.015) 1px, transparent 1px),
|
||||
@@ -1665,7 +1764,8 @@
|
||||
|
||||
.home-kinpaku .why-live-frame {
|
||||
position: relative;
|
||||
margin: 24px clamp(20px, 3vw, 32px) 0;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
border: 1px solid oklch(78% 0.12 82 / 0.22);
|
||||
border-radius: 6px;
|
||||
background:
|
||||
@@ -1675,25 +1775,17 @@
|
||||
inset 0 0 0 1px oklch(100% 0 0 / 0.02),
|
||||
0 18px 50px oklch(2% 0.004 95 / 0.32);
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.home-kinpaku .why-live-chrome {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
padding: 9px 14px;
|
||||
border-bottom: 1px solid var(--ks-rule);
|
||||
background: oklch(13% 0.006 95);
|
||||
}
|
||||
.home-kinpaku .why-live-dot {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 50%;
|
||||
background: oklch(58% 0.018 82);
|
||||
opacity: 0.55;
|
||||
}
|
||||
.home-kinpaku .why-live-dot:nth-child(1) { background: var(--ks-kinpaku-deep); }
|
||||
.home-kinpaku .why-live-dot:nth-child(2) { background: var(--ks-patina-deep); }
|
||||
.home-kinpaku .why-live-url {
|
||||
margin-left: 12px;
|
||||
padding: 3px 10px;
|
||||
@@ -1707,8 +1799,12 @@
|
||||
|
||||
.home-kinpaku .why-live-stage {
|
||||
position: relative;
|
||||
min-height: 130px;
|
||||
padding: 24px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 148px;
|
||||
padding: 32px 28px;
|
||||
background:
|
||||
repeating-linear-gradient(0deg, transparent 0 9px, oklch(100% 0 0 / 0.012) 9px 10px),
|
||||
oklch(8% 0.006 95);
|
||||
@@ -1717,9 +1813,9 @@
|
||||
.home-kinpaku .why-live-pick {
|
||||
position: relative;
|
||||
width: max-content;
|
||||
max-width: calc(100% - 8px);
|
||||
padding: 18px 22px;
|
||||
margin: 12px auto 4px;
|
||||
max-width: min(100%, 320px);
|
||||
padding: 20px 24px;
|
||||
margin: 0;
|
||||
border: 2px solid var(--ks-kinpaku);
|
||||
border-radius: 3px;
|
||||
background:
|
||||
@@ -1732,20 +1828,20 @@
|
||||
.home-kinpaku .why-live-pick-tag {
|
||||
display: block;
|
||||
font-family: var(--ks-mono);
|
||||
font-size: 0.7rem;
|
||||
font-size: 0.74rem;
|
||||
letter-spacing: 0.06em;
|
||||
color: var(--ks-kinpaku);
|
||||
}
|
||||
.home-kinpaku .why-live-pick-note {
|
||||
position: absolute;
|
||||
top: -14px;
|
||||
right: -18px;
|
||||
padding: 5px 10px;
|
||||
top: -12px;
|
||||
right: -14px;
|
||||
padding: 6px 11px;
|
||||
background: var(--ks-kinpaku);
|
||||
border-radius: 2px;
|
||||
color: oklch(8% 0.006 95);
|
||||
font-family: var(--ks-mono);
|
||||
font-size: 0.7rem;
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.02em;
|
||||
white-space: nowrap;
|
||||
box-shadow: 0 4px 14px oklch(78% 0.12 82 / 0.25);
|
||||
@@ -1763,46 +1859,35 @@
|
||||
50% { opacity: 0; }
|
||||
}
|
||||
|
||||
.home-kinpaku .why-live-gbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
.home-kinpaku .why-live-frame > .why-live-ctx.live-demo-ctx {
|
||||
position: static;
|
||||
left: auto;
|
||||
transform: none;
|
||||
display: block;
|
||||
opacity: 1;
|
||||
z-index: auto;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
padding: 10px 14px;
|
||||
border: 0;
|
||||
border-top: 1px solid var(--ks-rule);
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
background: oklch(13% 0.006 95);
|
||||
font-family: var(--ks-mono);
|
||||
font-size: 0.74rem;
|
||||
}
|
||||
.home-kinpaku .why-live-gbar-brand {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--ks-kinpaku);
|
||||
color: oklch(8% 0.006 95);
|
||||
border-radius: 3px;
|
||||
font-weight: 600;
|
||||
|
||||
.home-kinpaku .why-live-frame > .why-live-ctx .live-demo-ctx-row--configure {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
}
|
||||
.home-kinpaku .why-live-gbar-cmd {
|
||||
padding: 3px 10px;
|
||||
border: 1px solid oklch(78% 0.12 82 / 0.3);
|
||||
border-radius: 3px;
|
||||
color: var(--ks-kinpaku);
|
||||
|
||||
.home-kinpaku .why-live-frame > .why-live-ctx .live-demo-ctx-input {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
.home-kinpaku .why-live-gbar-count {
|
||||
padding: 3px 8px;
|
||||
border: 1px solid var(--ks-rule);
|
||||
border-radius: 3px;
|
||||
color: var(--ks-text-muted);
|
||||
}
|
||||
.home-kinpaku .why-live-gbar-go {
|
||||
margin-left: auto;
|
||||
padding: 4px 12px;
|
||||
background: var(--ks-kinpaku);
|
||||
color: oklch(8% 0.006 95);
|
||||
border-radius: 3px;
|
||||
font-weight: 500;
|
||||
|
||||
.home-kinpaku .why-live-frame > .why-live-ctx .live-demo-ctx-caret {
|
||||
animation: why-live-caret 1s steps(2, end) infinite;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
@@ -1908,20 +1993,6 @@
|
||||
linear-gradient(180deg, oklch(13% 0.006 95), oklch(8% 0.005 95));
|
||||
}
|
||||
|
||||
.home-kinpaku .why-visual--extension .why-browser-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background: var(--ks-kinpaku-deep);
|
||||
}
|
||||
|
||||
.home-kinpaku .why-visual--extension .why-browser-dot:nth-child(2) {
|
||||
background: var(--ks-patina);
|
||||
}
|
||||
|
||||
.home-kinpaku .why-visual--extension .why-browser-dot:nth-child(3) {
|
||||
background: var(--ks-kinpaku);
|
||||
}
|
||||
|
||||
.home-kinpaku .why-visual--extension .why-browser-url {
|
||||
min-height: 30px;
|
||||
display: flex;
|
||||
@@ -2024,14 +2095,11 @@
|
||||
}
|
||||
|
||||
.home-kinpaku .why-visual--designmd-v2 {
|
||||
gap: 16px;
|
||||
padding: clamp(18px, 2vw, 26px);
|
||||
overflow: hidden;
|
||||
background:
|
||||
radial-gradient(circle at 13% 24%, oklch(78% 0.12 82 / 0.055), transparent 18rem),
|
||||
radial-gradient(circle at 88% 18%, oklch(70% 0.105 190 / 0.06), transparent 18rem),
|
||||
linear-gradient(135deg, oklch(78% 0.12 82 / 0.035), transparent 46%),
|
||||
oklch(6% 0.005 95 / 0.92);
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.home-kinpaku .why-dm-header {
|
||||
@@ -2058,11 +2126,9 @@
|
||||
}
|
||||
|
||||
.home-kinpaku .why-dm-tile {
|
||||
border-color: var(--ks-rule);
|
||||
background:
|
||||
linear-gradient(135deg, oklch(100% 0 0 / 0.024), transparent 38%),
|
||||
oklch(5% 0.004 95 / 0.78);
|
||||
box-shadow: inset 0 0 0 1px oklch(78% 0.12 82 / 0.026);
|
||||
border: 1px solid var(--ks-rule);
|
||||
background: var(--ks-lacquer-raised);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.home-kinpaku .why-dm-tile-meta {
|
||||
@@ -2298,20 +2364,14 @@
|
||||
}
|
||||
|
||||
.home-kinpaku .why-visual--v2 .v2-new-browser-dots {
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
border-bottom: 1px solid var(--ks-rule);
|
||||
background:
|
||||
linear-gradient(90deg, oklch(78% 0.12 82 / 0.08), transparent),
|
||||
oklch(8% 0.006 95);
|
||||
}
|
||||
|
||||
.home-kinpaku .why-visual--v2 .v2-new-browser-dot {
|
||||
background: var(--ks-kinpaku-deep);
|
||||
}
|
||||
|
||||
.home-kinpaku .why-visual--v2 .v2-new-browser-dot:nth-child(2) {
|
||||
background: var(--ks-patina);
|
||||
}
|
||||
|
||||
.home-kinpaku .why-visual--v2 .v2-new-browser-frame {
|
||||
background:
|
||||
linear-gradient(90deg, oklch(78% 0.12 82 / 0.035) 1px, transparent 1px),
|
||||
@@ -2385,10 +2445,12 @@
|
||||
}
|
||||
|
||||
.home-kinpaku .live-demo-frame {
|
||||
border: 1px solid var(--ks-rule);
|
||||
border: 1px solid oklch(92% 0 0 / 0.1);
|
||||
border-radius: 4px;
|
||||
background: var(--ks-lacquer-raised);
|
||||
box-shadow: 0 30px 84px oklch(2% 0.004 95 / 0.42);
|
||||
box-shadow:
|
||||
inset 0 1px 0 oklch(100% 0 0 / 0.05),
|
||||
0 20px 48px -14px oklch(0% 0 0 / 0.6);
|
||||
}
|
||||
|
||||
/* Picker chrome (chrome bar, gbar, ctx, outline, comment, stroke, etc.)
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
never tucks under the nav; on tall viewports the content still centers. */
|
||||
padding: 113px 0 96px;
|
||||
overflow: hidden;
|
||||
/* Hairline divider into the testimonials below, matching the testimonial
|
||||
card border color. */
|
||||
border-bottom: 1px solid oklch(0.64 0 0 / 0.22);
|
||||
}
|
||||
|
||||
/* Header sits on top of the hero image like the /design-system topbar:
|
||||
@@ -55,10 +58,7 @@
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
/* Top scrim darkens the band behind the overlaid nav so the links stay
|
||||
legible over the bright kintsugi gold, fading out before the hero copy. */
|
||||
background:
|
||||
linear-gradient(180deg, oklch(7% 0.006 95 / 0.9) 0%, oklch(7% 0.006 95 / 0.5) 8%, transparent 18%),
|
||||
url("/assets/neo-kinpaku/candidates/finalists/m-01-v2-01.png") center / cover no-repeat;
|
||||
filter: saturate(1.2) contrast(1.08);
|
||||
}
|
||||
@@ -116,7 +116,9 @@
|
||||
|
||||
/* Hero CTAs migrated to .ks-button.ks-button-primary / .ks-button-secondary
|
||||
(see kinpaku-kit.css). The .hero-rebuild-arrow class is gone too — the
|
||||
arrow now lives in .ks-button-arrow inside the button. */
|
||||
arrow now lives in .ks-button-arrow inside the button.
|
||||
"How it works" is the kit ghost variant: plain champagne (white) text, no
|
||||
border or fill, hovering to gold. */
|
||||
|
||||
.hero-rebuild-meta {
|
||||
margin: 24px 0 0;
|
||||
@@ -497,13 +499,13 @@
|
||||
than .home-kinpaku code alone). Keeps the CLI block in the softer code-gold
|
||||
so the line reads as a terminal command, not a pumpkin headline. */
|
||||
.home-kinpaku code.slop-teaser-cli {
|
||||
color: oklch(82% 0.11 82);
|
||||
color: var(--ks-code-block-fg);
|
||||
font-family: var(--ks-mono);
|
||||
font-size: 0.86rem;
|
||||
background: var(--ks-lacquer-raised);
|
||||
background: var(--ks-code-block-bg);
|
||||
padding: 10px 16px;
|
||||
border: 1px solid var(--ks-rule);
|
||||
border-radius: 2px;
|
||||
border: 1px solid var(--ks-code-block-border);
|
||||
border-radius: var(--ks-code-block-radius);
|
||||
user-select: all;
|
||||
}
|
||||
|
||||
@@ -553,8 +555,8 @@
|
||||
--card-fg-strong: var(--ks-champagne);
|
||||
--card-fg-muted: var(--ks-muted);
|
||||
--card-accent: var(--ks-kinpaku);
|
||||
--card-cmd-bg: oklch(0.11 0 0);
|
||||
--card-cmd-fg: var(--ks-champagne);
|
||||
--card-cmd-bg: var(--ks-code-block-bg);
|
||||
--card-cmd-fg: var(--ks-code-block-fg);
|
||||
--card-copy-border: var(--ks-rule);
|
||||
--card-copy-fg: var(--ks-kinpaku);
|
||||
--card-copy-hover-bg: oklch(77% 0.14 82 / 0.08);
|
||||
@@ -711,6 +713,7 @@
|
||||
.downloads-rebuild-alts {
|
||||
grid-column: 1 / -1;
|
||||
margin: 2px 0 0;
|
||||
text-align: center;
|
||||
}
|
||||
.downloads-rebuild-alts-summary {
|
||||
display: inline-flex;
|
||||
@@ -771,7 +774,9 @@
|
||||
|
||||
.downloads-rebuild-note {
|
||||
grid-column: 1 / -1;
|
||||
margin: 0;
|
||||
margin: 0 auto;
|
||||
max-width: 64ch;
|
||||
text-align: center;
|
||||
color: var(--card-fg-muted);
|
||||
font-size: 0.88rem;
|
||||
}
|
||||
@@ -782,6 +787,7 @@
|
||||
.downloads-rebuild-secondary {
|
||||
grid-column: 1 / -1;
|
||||
margin: 6px 0 0;
|
||||
text-align: center;
|
||||
font-size: 0.84rem;
|
||||
color: var(--ks-text-muted);
|
||||
}
|
||||
@@ -795,8 +801,7 @@
|
||||
border-bottom-color: var(--ks-patina-pale);
|
||||
}
|
||||
|
||||
/* Closing "go deeper" links under the usage examples — point to the full
|
||||
workflow page and the command docs. */
|
||||
/* Closing links under the setup extras — workflow + command docs. */
|
||||
.downloads-rebuild-more {
|
||||
margin: 30px auto 0;
|
||||
max-width: 720px;
|
||||
@@ -814,62 +819,6 @@
|
||||
border-bottom-color: var(--ks-patina-pale);
|
||||
}
|
||||
|
||||
/* Center-aligned examples: each row is a vertical stack — the command line
|
||||
on top, the description below, both centered horizontally. */
|
||||
/* Usage examples now sit after the extras (the logical next step once the
|
||||
skill, extension, CLI, and subscriptions are set up), so the separating
|
||||
gap moves to the top. */
|
||||
.downloads-rebuild-examples {
|
||||
list-style: none;
|
||||
margin: 48px auto 0;
|
||||
padding: 48px 0 0;
|
||||
/* Subtle hairline marking the "now use it" step after the setup block. */
|
||||
border-top: 1px solid var(--ks-rule);
|
||||
display: grid;
|
||||
gap: 22px;
|
||||
max-width: 720px;
|
||||
}
|
||||
|
||||
.downloads-rebuild-examples li {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 6px;
|
||||
justify-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Strip the global .home-kinpaku code chrome for these example rows. */
|
||||
.home-kinpaku .downloads-rebuild-examples > li > code {
|
||||
font-family: var(--ks-mono);
|
||||
color: var(--card-accent);
|
||||
font-size: 1rem;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
letter-spacing: 0.005em;
|
||||
}
|
||||
|
||||
.downloads-rebuild-slash {
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
.downloads-rebuild-examples span {
|
||||
color: var(--card-fg);
|
||||
font-size: 0.94rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.home-kinpaku .downloads-rebuild-examples span code {
|
||||
color: var(--card-fg-strong);
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
font-family: var(--ks-mono);
|
||||
font-size: 0.86rem;
|
||||
}
|
||||
|
||||
.downloads-rebuild-extras {
|
||||
list-style: none;
|
||||
margin: 0 auto;
|
||||
@@ -950,7 +899,6 @@
|
||||
@media (max-width: 720px) {
|
||||
.downloads-rebuild { padding: 64px 0; }
|
||||
.downloads-rebuild-install { grid-template-columns: 1fr; }
|
||||
.downloads-rebuild-examples li { grid-template-columns: 1fr; gap: 8px; }
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
@@ -1014,6 +962,12 @@
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* The hero-scoped demo-chrome refinements (crisp outline, neutral chrome dots /
|
||||
URL, quiet gbar border, crisp active-Pick pill, tighter radii, refined frame
|
||||
elevation) were promoted into the shared picker chrome in kinpaku-kit.css /
|
||||
live-mode-kinpaku.css / home-kinpaku.css so /live-mode and the injected
|
||||
picker (skill/scripts/live-browser.js) match. Nothing hero-specific remains. */
|
||||
|
||||
/* The stage holds a full (fake) website now, not a centered card. */
|
||||
.hero-live-demo .live-demo-stage {
|
||||
display: block;
|
||||
|
||||
+52
-19
@@ -892,6 +892,17 @@
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.kinpaku-chrome .theme-toggle,
|
||||
.kinpaku-chrome .site-header-github {
|
||||
height: 36px;
|
||||
min-height: 36px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.kinpaku-chrome .site-header-github {
|
||||
padding: 0 12px 0 10px;
|
||||
}
|
||||
|
||||
.kinpaku-chrome .site-header-nav a,
|
||||
.kinpaku-chrome .site-header-github {
|
||||
color: var(--ks-champagne);
|
||||
@@ -904,7 +915,7 @@
|
||||
|
||||
/* GitHub star pill. Previously home-only; now every kinpaku page gets it. */
|
||||
.kinpaku-chrome .site-header-github {
|
||||
border: 1px solid var(--ks-rule);
|
||||
border: 1px solid oklch(80% 0 0);
|
||||
border-radius: 999px;
|
||||
background: oklch(10% 0.006 95 / 0.74);
|
||||
}
|
||||
@@ -1099,16 +1110,21 @@
|
||||
constants are kept in sync with these tokens by hand.
|
||||
============================================================ */
|
||||
|
||||
/* Browser-chrome bar at the top of the mock (URL pill + dots). */
|
||||
/* Browser-chrome bar at the top of the mock (URL pill + dots). Refined to read
|
||||
like a precise tool, not a stock screenshot frame: slimmer bar, small uniform
|
||||
neutral dots, and a clean neutral-edged URL pill (no warm gold hairline). */
|
||||
.home-kinpaku .live-demo-chrome,
|
||||
.live-mode-kinpaku .live-demo-chrome {
|
||||
padding: 9px 14px;
|
||||
background: var(--ks-graphite);
|
||||
border-bottom: 1px solid var(--ks-rule);
|
||||
border-bottom: 1px solid oklch(92% 0 0 / 0.07);
|
||||
}
|
||||
|
||||
.home-kinpaku .live-demo-dot,
|
||||
.live-mode-kinpaku .live-demo-dot {
|
||||
background: oklch(28% 0.01 95);
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background: oklch(34% 0 0);
|
||||
}
|
||||
|
||||
.home-kinpaku .live-demo-url,
|
||||
@@ -1119,7 +1135,7 @@
|
||||
color: var(--ks-text-muted);
|
||||
letter-spacing: 0.04em;
|
||||
background: transparent;
|
||||
border: 1px solid var(--ks-rule);
|
||||
border: 1px solid oklch(92% 0 0 / 0.08);
|
||||
}
|
||||
|
||||
/* Active control surfaces — the bottom picker bar and the context bar
|
||||
@@ -1131,10 +1147,12 @@
|
||||
.home-kinpaku .live-demo-ctx,
|
||||
.live-mode-kinpaku .live-demo-ctx {
|
||||
background: var(--ks-lacquer-deep);
|
||||
border: 1.5px solid var(--ks-kinpaku);
|
||||
box-shadow:
|
||||
0 0 0 1px oklch(78% 0.12 82 / 0.18),
|
||||
0 10px 28px oklch(0% 0 0 / 0.28);
|
||||
/* Quiet neutral hairline instead of the loud 1.5px gold border + gold halo.
|
||||
Gold is reserved for the brand mark and the active control, not the
|
||||
container outline. */
|
||||
border: 1px solid oklch(92% 0 0 / 0.13);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 16px 36px -12px oklch(0% 0 0 / 0.6);
|
||||
color: var(--ks-champagne);
|
||||
}
|
||||
|
||||
@@ -1150,13 +1168,14 @@
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Active state — soft kinpaku-dim pill with kinpaku text. The outer
|
||||
gbar border carries the loud signal; the active button is the
|
||||
quieter "currently selected" pill inside. */
|
||||
/* Active state — a crisp neutral pill with kinpaku text. The translucent
|
||||
kinpaku-dim wash read as a murky smudge; a solid graphite chip with gold
|
||||
text/icon makes the selected control precise. */
|
||||
.home-kinpaku .live-demo-gbar-btn.is-active,
|
||||
.live-mode-kinpaku .live-demo-gbar-btn.is-active {
|
||||
background: oklch(78% 0.12 82 / 0.18);
|
||||
background: oklch(27% 0 0);
|
||||
color: var(--ks-kinpaku);
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
/* Page chat — collapsed pill with chat + mic; expands on click. */
|
||||
@@ -1167,9 +1186,9 @@
|
||||
height: 28px;
|
||||
width: 88px;
|
||||
margin: 0 4px 0 6px;
|
||||
border-radius: 7px;
|
||||
border-radius: 5px;
|
||||
background: var(--ks-graphite);
|
||||
border: 1px solid var(--ks-rule);
|
||||
border: 1px solid oklch(92% 0 0 / 0.1);
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
@@ -1292,10 +1311,20 @@
|
||||
.home-kinpaku .live-demo-ctx-pill,
|
||||
.live-mode-kinpaku .live-demo-ctx-pill {
|
||||
background: var(--ks-graphite-2);
|
||||
border: 1px solid var(--ks-rule);
|
||||
border: 1px solid oklch(92% 0 0 / 0.12);
|
||||
color: var(--ks-champagne);
|
||||
}
|
||||
|
||||
/* Even heights across the configure row: the pill, input, count, and Go button
|
||||
share one 30px baseline instead of stepping up and down. */
|
||||
.home-kinpaku .live-demo-ctx-row--configure > *,
|
||||
.live-mode-kinpaku .live-demo-ctx-row--configure > * {
|
||||
height: 30px;
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.home-kinpaku .live-demo-ctx-pill-caret,
|
||||
.live-mode-kinpaku .live-demo-ctx-pill-caret {
|
||||
color: var(--ks-text-muted);
|
||||
@@ -1304,7 +1333,7 @@
|
||||
.home-kinpaku .live-demo-ctx-input,
|
||||
.live-mode-kinpaku .live-demo-ctx-input {
|
||||
background: var(--ks-graphite);
|
||||
border: 1px solid var(--ks-rule);
|
||||
border: 1px solid oklch(92% 0 0 / 0.12);
|
||||
color: var(--ks-champagne);
|
||||
}
|
||||
|
||||
@@ -1316,7 +1345,7 @@
|
||||
.home-kinpaku .live-demo-ctx-count,
|
||||
.live-mode-kinpaku .live-demo-ctx-count {
|
||||
background: var(--ks-graphite-2);
|
||||
border: 1px solid var(--ks-rule);
|
||||
border: 1px solid oklch(92% 0 0 / 0.12);
|
||||
color: var(--ks-text-muted);
|
||||
}
|
||||
|
||||
@@ -1377,8 +1406,12 @@
|
||||
.home-kinpaku .live-demo-outline,
|
||||
.live-mode-kinpaku .live-demo-outline {
|
||||
border-color: var(--ks-kinpaku);
|
||||
border-width: 1.5px;
|
||||
border-radius: 3px;
|
||||
color: var(--ks-kinpaku);
|
||||
box-shadow: 0 0 0 4px oklch(78% 0.12 82 / 0.16);
|
||||
/* No soft gold glow ring (off-brand accent halo); a crisp outline reads as a
|
||||
precise selection, not a highlighter. */
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.home-kinpaku .live-demo-annotations,
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
:root {
|
||||
/* color-scheme follows html.light / html.dark class on <html> */
|
||||
/* ============================================================
|
||||
Brand anchors. Two anchors carry the brand — kinpaku gold for
|
||||
commitment and brand voice, verdigris patina for state and
|
||||
@@ -45,22 +46,43 @@
|
||||
--ks-graphite-2: oklch(19% 0.008 95); /* one step up from graphite */
|
||||
|
||||
/* ============================================================
|
||||
Text. Warm champagne family. Body text reads at ≥0.92rem on
|
||||
lacquer; smaller than that loses to the warm noise floor.
|
||||
Text. The whole text ramp runs near-neutral and bright so copy,
|
||||
headings, and labels read crisp on lacquer instead of mushing
|
||||
into the warm floor. Warmth now lives only in the gold accents
|
||||
and the surfaces, not in the type. (--ks-champagne keeps its name
|
||||
for compatibility but is no longer warm.)
|
||||
============================================================ */
|
||||
--ks-champagne: oklch(84% 0.035 82); /* headlines, <strong> */
|
||||
--ks-text: oklch(81% 0.03 82); /* body */
|
||||
--ks-text-muted: oklch(63% 0.024 82); /* captions, meta */
|
||||
--ks-text-faint: oklch(52% 0.018 82); /* subdued */
|
||||
--ks-text-mute-deep: oklch(48% 0.018 82); /* disabled */
|
||||
--ks-champagne: oklch(91% 0 0); /* headlines, <strong> — neutral white */
|
||||
--ks-text: oklch(88% 0 0); /* body — neutral near-white */
|
||||
--ks-text-muted: oklch(72% 0 0); /* captions, meta */
|
||||
--ks-text-faint: oklch(62% 0 0); /* subdued */
|
||||
--ks-text-mute-deep: oklch(52% 0 0); /* disabled */
|
||||
|
||||
/* ============================================================
|
||||
Rules. Gold hairlines. Default is quiet; "strong" appears on
|
||||
focus, active state, and structural anchors.
|
||||
Rules. The default hairline is neutral so borders/dividers/labels
|
||||
don't carry warmth (warmth lives in the gold accents and surfaces).
|
||||
"strong" stays gold — it appears on focus, active state, and
|
||||
structural brand anchors where the gold is the signal.
|
||||
============================================================ */
|
||||
--ks-rule: oklch(58% 0.065 82 / 0.32);
|
||||
--ks-rule: oklch(78% 0 0 / 0.16);
|
||||
--ks-rule-strong: oklch(74% 0.09 82 / 0.6);
|
||||
|
||||
/* ============================================================
|
||||
Code. One treatment site-wide. Inline code is a neutral graphite
|
||||
chip; blocks / CLI commands are a deep lacquer terminal with a
|
||||
neutral hairline. Gold is only for code that is itself a command
|
||||
link (--ks-code-cmd). All code rules read these — don't hand-type.
|
||||
============================================================ */
|
||||
--ks-code-fg: oklch(91% 0 0); /* inline code text */
|
||||
--ks-code-bg: var(--ks-graphite-2); /* inline code chip */
|
||||
--ks-code-radius: 3px;
|
||||
--ks-code-pad: 0.3em 0.5em; /* inline code chip padding */
|
||||
--ks-code-block-fg: oklch(86% 0 0); /* block / CLI text */
|
||||
--ks-code-block-bg: var(--ks-lacquer-deep);
|
||||
--ks-code-block-border: var(--ks-rule);
|
||||
--ks-code-block-radius: 2px;
|
||||
--ks-code-cmd: var(--ks-kinpaku); /* code that's a command link */
|
||||
|
||||
/* ============================================================
|
||||
Typography — three faces.
|
||||
- --ks-font-display: Alumni Sans Pinstripe. Pinstripe horizontal
|
||||
@@ -124,3 +146,64 @@
|
||||
============================================================ */
|
||||
--ks-ease: cubic-bezier(0.2, 0.8, 0.2, 1);
|
||||
}
|
||||
|
||||
html.dark {
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
Light mode — warm paper surfaces, dark ink type, kinpaku gold
|
||||
accents deepened for contrast. Activated via html.light on
|
||||
<html> (set by theme.js + inline FOUC guard in Base.astro).
|
||||
============================================================ */
|
||||
html.light {
|
||||
color-scheme: light;
|
||||
|
||||
/* Brand gold — same fills as dark mode (logo, buttons, marks).
|
||||
Use --ks-kinpaku-ink for small text on paper where bright gold
|
||||
lacks contrast; never swap the core token to a muddy orange. */
|
||||
--ks-kinpaku: oklch(84% 0.19 80.46);
|
||||
--ks-kinpaku-pale: oklch(86% 0.07 84);
|
||||
--ks-kinpaku-rich: oklch(77% 0.13 82);
|
||||
--ks-kinpaku-deep: oklch(61% 0.085 78);
|
||||
--ks-kinpaku-ink: oklch(56% 0.11 82);
|
||||
|
||||
/* Text links + active nav on paper — patina, not fill gold. */
|
||||
--ks-link-on-paper: var(--ks-patina-deep);
|
||||
--ks-link-on-paper-hover: var(--ks-patina);
|
||||
--ks-link-on-paper-line: oklch(49% 0.08 188 / 0.42);
|
||||
--ks-nav-active: var(--ks-patina-deep);
|
||||
|
||||
/* Patina — brand values for fills; deep for text on paper. */
|
||||
--ks-patina: oklch(70% 0.12 188);
|
||||
--ks-patina-pale: oklch(82% 0.07 188);
|
||||
--ks-patina-deep: oklch(49% 0.08 188);
|
||||
|
||||
--ks-vermilion: oklch(52% 0.16 35);
|
||||
|
||||
/* Surfaces — warm paper and cream panels. */
|
||||
--ks-lacquer: oklch(97% 0.012 95);
|
||||
--ks-lacquer-deep: oklch(94% 0.014 95);
|
||||
--ks-lacquer-raised: oklch(99% 0.008 95);
|
||||
--ks-graphite: oklch(91% 0.012 95);
|
||||
--ks-graphite-2: oklch(88% 0.014 95);
|
||||
|
||||
/* Text — dark ink on paper. */
|
||||
--ks-champagne: oklch(18% 0.02 95);
|
||||
--ks-text: oklch(25% 0.018 95);
|
||||
--ks-text-muted: oklch(45% 0.015 95);
|
||||
--ks-text-faint: oklch(55% 0.012 95);
|
||||
--ks-text-mute-deep: oklch(65% 0.01 95);
|
||||
|
||||
/* Rules — dark hairlines. */
|
||||
--ks-rule: oklch(25% 0.02 95 / 0.12);
|
||||
--ks-rule-strong: oklch(61% 0.085 78 / 0.45);
|
||||
|
||||
/* Code — light chips, dark text. */
|
||||
--ks-code-fg: oklch(28% 0.02 95);
|
||||
--ks-code-bg: var(--ks-graphite);
|
||||
--ks-code-block-fg: oklch(30% 0.02 95);
|
||||
--ks-code-block-bg: var(--ks-lacquer-raised);
|
||||
--ks-code-block-border: var(--ks-rule);
|
||||
--ks-code-cmd: var(--ks-kinpaku-ink);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -190,10 +190,14 @@
|
||||
|
||||
.live-mode-kinpaku .live-demo-frame {
|
||||
background: var(--ks-lacquer-deep);
|
||||
border: 1px solid var(--ks-rule);
|
||||
/* Crisp neutral hairline + tighter, deeper shadow that registers, instead of
|
||||
a warm gold edge and a broad soft shadow that washes out on dark. */
|
||||
border: 1px solid oklch(92% 0 0 / 0.1);
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 32px 80px oklch(2% 0.004 95 / 0.55);
|
||||
box-shadow:
|
||||
inset 0 1px 0 oklch(100% 0 0 / 0.05),
|
||||
0 20px 48px -14px oklch(0% 0 0 / 0.6);
|
||||
}
|
||||
|
||||
/* All .live-demo-* picker chrome (chrome bar, gbar, ctx, outline,
|
||||
|
||||
@@ -10,68 +10,43 @@
|
||||
spans the full viewport. */
|
||||
width: 100vw;
|
||||
margin-left: calc(50% - 50vw);
|
||||
padding: 20px 0 clamp(56px, 7vw, 96px);
|
||||
background: var(--ks-lacquer);
|
||||
/* No background of its own: the body's lacquer gradient is the page ground,
|
||||
so the section sits on it directly and an opaque fill here would only
|
||||
duplicate (and, when overlapped, mask) it. */
|
||||
padding: 0 0 1em;
|
||||
color: var(--ks-text);
|
||||
border-top: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Flat dotted top divider (matches the hero → testimonials boundary). */
|
||||
.home-kinpaku .testimonials-section::before {
|
||||
/* Dotted accent at the bottom edge — a deliberate separator between the
|
||||
testimonials and the section below. Neutral dots, matching the de-warmed
|
||||
borders. (This is the dot rail that used to sit above the section.) */
|
||||
.home-kinpaku .testimonials-section::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
width: 100vw;
|
||||
height: 18px;
|
||||
transform: translateX(-50%);
|
||||
background-image: radial-gradient(circle, oklch(0.42 0.014 82) 0.9px, transparent 1.4px);
|
||||
background-image: radial-gradient(circle, oklch(0.45 0 0) 0.9px, transparent 1.4px);
|
||||
background-size: 7px 6px;
|
||||
background-position: 0 1px;
|
||||
background-repeat: repeat;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
Plinth — the tinted graphite shelf the marquee rides on
|
||||
--------------------------------------------------------------------------- */
|
||||
|
||||
.home-kinpaku .t-plinth {
|
||||
position: relative;
|
||||
width: 100vw;
|
||||
padding: 20px 0;
|
||||
background:
|
||||
linear-gradient(180deg, oklch(20% 0.01 78) 0%, oklch(17% 0.008 78) 100%);
|
||||
border-top: 1px solid oklch(78% 0.12 82 / 0.12);
|
||||
border-bottom: 1px solid oklch(78% 0.12 82 / 0.10);
|
||||
}
|
||||
.home-kinpaku .t-plinth--shelf::before,
|
||||
.home-kinpaku .t-plinth--shelf::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0; right: 0;
|
||||
height: 8px;
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
}
|
||||
.home-kinpaku .t-plinth--shelf::before {
|
||||
top: 0;
|
||||
background: linear-gradient(180deg, oklch(0% 0 0 / 0.18), transparent);
|
||||
}
|
||||
.home-kinpaku .t-plinth--shelf::after {
|
||||
bottom: 0;
|
||||
background: linear-gradient(0deg, oklch(0% 0 0 / 0.22), transparent);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
Marquee engine
|
||||
Marquee engine. The cards are outlined and ride directly on the section
|
||||
ground — the old graphite plinth wrapper was removed once it stopped being
|
||||
a visible shelf, so the marquee carries its own vertical inset here.
|
||||
--------------------------------------------------------------------------- */
|
||||
|
||||
.home-kinpaku .t-marquee {
|
||||
display: grid;
|
||||
gap: 14px;
|
||||
width: 100%;
|
||||
padding: 22px 0;
|
||||
}
|
||||
.home-kinpaku .t-marquee-row { overflow: hidden; }
|
||||
|
||||
@@ -119,14 +94,16 @@
|
||||
transition: transform 200ms ease, background 200ms ease, box-shadow 200ms ease, border-color 200ms ease;
|
||||
}
|
||||
|
||||
/* Plinth-resident card — borderless, slightly raised tone */
|
||||
/* Outlined card: no fill, just a solid neutral border on the page ground.
|
||||
On dark, a clean outline separates more honestly than a near-invisible
|
||||
fill or a dead drop-shadow ever did. */
|
||||
.home-kinpaku .t-card--plinth {
|
||||
background: oklch(13% 0.008 95);
|
||||
border: 1px solid transparent;
|
||||
box-shadow: 0 1px 0 0 oklch(78% 0.12 82 / 0.06) inset, 0 4px 12px -8px oklch(0% 0 0 / 0.6);
|
||||
background: none;
|
||||
border: 1px solid oklch(0.64 0 0 / 0.22);
|
||||
box-shadow: none;
|
||||
}
|
||||
.home-kinpaku .t-card--plinth:hover {
|
||||
background: oklch(15% 0.012 78);
|
||||
border-color: oklch(0.64 0 0 / 0.42);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
|
||||
@@ -106,3 +106,19 @@ button, input, textarea, select {
|
||||
--cat-system-border: #78716c;
|
||||
--cat-system-text: #44403c;
|
||||
}
|
||||
|
||||
/* Light mode legacy aliases — mirror html.light --ks-* tokens. */
|
||||
html.light {
|
||||
--color-ink: var(--ks-champagne);
|
||||
--color-text: var(--ks-text);
|
||||
--color-paper: var(--ks-lacquer);
|
||||
--color-cream: var(--ks-lacquer-raised);
|
||||
--color-charcoal: var(--ks-text);
|
||||
--color-ash: var(--ks-text-muted);
|
||||
--color-mist: var(--ks-rule);
|
||||
--color-bg: var(--ks-lacquer-raised);
|
||||
--color-accent: var(--ks-kinpaku);
|
||||
--color-accent-hover: var(--ks-kinpaku-pale);
|
||||
--color-accent-dim: oklch(77% 0.13 82 / 0.14);
|
||||
--color-accent-soft: oklch(77% 0.13 82 / 0.24);
|
||||
}
|
||||
|
||||
@@ -46,9 +46,11 @@
|
||||
mist: 'oklch(90% 0.008 82 / 0.6)', // light hairline
|
||||
white: 'oklch(99% 0 0)',
|
||||
};
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css
|
||||
// Picker bar chrome — mirrors .live-demo-gbar / .live-demo-ctx in kinpaku-kit.css.
|
||||
// Quiet neutral elevation: no gold halo ring (gold is reserved for the brand
|
||||
// mark and the active control, not the container outline).
|
||||
const PICKER_SHADOW =
|
||||
'0 0 0 1px oklch(78% 0.12 82 / 0.18), 0 10px 28px oklch(0% 0 0 / 0.28)';
|
||||
'0 16px 36px -12px oklch(0% 0 0 / 0.6)';
|
||||
const FONT = 'system-ui, -apple-system, sans-serif';
|
||||
const MONO = 'ui-monospace, SFMono-Regular, Menlo, monospace';
|
||||
// z-index: detect overlays use 99999, so our UI must be above them
|
||||
@@ -995,8 +997,8 @@
|
||||
transform: 'translateY(6px)',
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
background: BP.surface,
|
||||
border: '1.5px solid ' + BP.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + BP.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: BP.shadow,
|
||||
transition: 'box-shadow 0.2s ease, opacity 0.25s ' + EASE + ', transform 0.3s ' + EASE,
|
||||
fontFamily: FONT, fontSize: '13px', color: BP.text,
|
||||
@@ -1071,7 +1073,7 @@
|
||||
barEl.innerHTML = '';
|
||||
// Reset bar styling to the kinpaku picker palette
|
||||
barEl.style.background = BP.surface;
|
||||
barEl.style.border = '1.5px solid ' + BP.border;
|
||||
barEl.style.border = '1px solid ' + BP.border;
|
||||
barEl.style.boxShadow = BP.shadow;
|
||||
if (mode === 'configure') {
|
||||
barEl.appendChild(configureKind === 'insert' ? buildInsertConfigureRow() : buildConfigureRow());
|
||||
@@ -2339,8 +2341,8 @@
|
||||
transformOrigin: 'bottom left',
|
||||
transition: 'opacity 0.18s ' + EASE + ', transform 0.2s ' + EASE,
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
padding: '6px',
|
||||
fontFamily: FONT,
|
||||
@@ -6122,8 +6124,15 @@ void main() {
|
||||
return {
|
||||
surface: C.ink,
|
||||
surfaceDeep: C.ink,
|
||||
border: C.brand,
|
||||
hairline: 'oklch(58% 0.065 82 / 0.48)',
|
||||
// Quiet neutral hairline (was the loud kinpaku gold border). Gold lives on
|
||||
// the brand mark and the active control instead.
|
||||
border: 'oklch(92% 0 0 / 0.13)',
|
||||
// Crisp graphite pill behind the active toggle (was a murky kinpaku-dim
|
||||
// wash); the gold text/icon carries the "selected" signal.
|
||||
toggleActive: 'oklch(27% 0 0)',
|
||||
// Neutral hairline for internal control borders / dividers (was a warm
|
||||
// gold rule that read as muddy champagne edges on the pill / input / count).
|
||||
hairline: 'oklch(92% 0 0 / 0.12)',
|
||||
text: 'oklch(84% 0.035 82)',
|
||||
textDim: 'oklch(63% 0.024 82)',
|
||||
accent: C.brand,
|
||||
@@ -7032,8 +7041,8 @@ void main() {
|
||||
display: 'flex', alignItems: 'stretch',
|
||||
gap: '0',
|
||||
background: P.surface,
|
||||
border: '1.5px solid ' + P.border,
|
||||
borderRadius: '10px',
|
||||
border: '1px solid ' + P.border,
|
||||
borderRadius: '8px',
|
||||
boxShadow: P.shadow,
|
||||
fontFamily: FONT, fontSize: '12px', lineHeight: '1',
|
||||
opacity: '0',
|
||||
@@ -7443,7 +7452,7 @@ void main() {
|
||||
// Sync one toggle's active state, colors, and slide-label visibility.
|
||||
function sync(btn, active) {
|
||||
if (!btn) return;
|
||||
btn.style.background = active ? P.accentSoft : 'transparent';
|
||||
btn.style.background = active ? P.toggleActive : 'transparent';
|
||||
btn.style.color = active ? P.accent : P.textDim;
|
||||
btn.dataset.active = active ? 'true' : 'false';
|
||||
if (active && btn._expandLabel) btn._expandLabel();
|
||||
|
||||
Reference in New Issue
Block a user