mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-12 22:26:38 +03:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9fa46412c | ||
|
|
a20bbfc752 | ||
|
|
7501e67b55 | ||
|
|
9798bb7235 | ||
|
|
67e73f47a6 | ||
|
|
1fe9c41759 |
@@ -7928,7 +7928,7 @@ void main() {
|
||||
const barTopFromBottom = barRect && barRect.height > 0
|
||||
? Math.max(16, window.innerHeight - barRect.top + 12)
|
||||
: 16;
|
||||
toastEl = el('div', {
|
||||
const currentToast = el('div', {
|
||||
position: 'fixed', bottom: barTopFromBottom + 'px', left: '50%',
|
||||
transform: 'translateX(-50%) translateY(8px)',
|
||||
background: C.ink, color: C.white,
|
||||
@@ -7938,19 +7938,24 @@ void main() {
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.25s ' + EASE,
|
||||
pointerEvents: 'none', maxWidth: '420px', textAlign: 'center',
|
||||
});
|
||||
toastEl.id = PREFIX + '-toast';
|
||||
toastEl.textContent = message;
|
||||
uiAppend(toastEl);
|
||||
toastEl = currentToast;
|
||||
currentToast.id = PREFIX + '-toast';
|
||||
currentToast.textContent = message;
|
||||
uiAppend(currentToast);
|
||||
requestAnimationFrame(() => {
|
||||
toastEl.style.opacity = '1';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(0)';
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '1';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(0)';
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (toastEl) {
|
||||
toastEl.style.opacity = '0';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => { if (toastEl) { toastEl.remove(); toastEl = null; } }, 250);
|
||||
}
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '0';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => {
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.remove();
|
||||
toastEl = null;
|
||||
}, 250);
|
||||
}, duration);
|
||||
}
|
||||
|
||||
|
||||
@@ -7928,7 +7928,7 @@ void main() {
|
||||
const barTopFromBottom = barRect && barRect.height > 0
|
||||
? Math.max(16, window.innerHeight - barRect.top + 12)
|
||||
: 16;
|
||||
toastEl = el('div', {
|
||||
const currentToast = el('div', {
|
||||
position: 'fixed', bottom: barTopFromBottom + 'px', left: '50%',
|
||||
transform: 'translateX(-50%) translateY(8px)',
|
||||
background: C.ink, color: C.white,
|
||||
@@ -7938,19 +7938,24 @@ void main() {
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.25s ' + EASE,
|
||||
pointerEvents: 'none', maxWidth: '420px', textAlign: 'center',
|
||||
});
|
||||
toastEl.id = PREFIX + '-toast';
|
||||
toastEl.textContent = message;
|
||||
uiAppend(toastEl);
|
||||
toastEl = currentToast;
|
||||
currentToast.id = PREFIX + '-toast';
|
||||
currentToast.textContent = message;
|
||||
uiAppend(currentToast);
|
||||
requestAnimationFrame(() => {
|
||||
toastEl.style.opacity = '1';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(0)';
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '1';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(0)';
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (toastEl) {
|
||||
toastEl.style.opacity = '0';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => { if (toastEl) { toastEl.remove(); toastEl = null; } }, 250);
|
||||
}
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '0';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => {
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.remove();
|
||||
toastEl = null;
|
||||
}, 250);
|
||||
}, duration);
|
||||
}
|
||||
|
||||
|
||||
@@ -7928,7 +7928,7 @@ void main() {
|
||||
const barTopFromBottom = barRect && barRect.height > 0
|
||||
? Math.max(16, window.innerHeight - barRect.top + 12)
|
||||
: 16;
|
||||
toastEl = el('div', {
|
||||
const currentToast = el('div', {
|
||||
position: 'fixed', bottom: barTopFromBottom + 'px', left: '50%',
|
||||
transform: 'translateX(-50%) translateY(8px)',
|
||||
background: C.ink, color: C.white,
|
||||
@@ -7938,19 +7938,24 @@ void main() {
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.25s ' + EASE,
|
||||
pointerEvents: 'none', maxWidth: '420px', textAlign: 'center',
|
||||
});
|
||||
toastEl.id = PREFIX + '-toast';
|
||||
toastEl.textContent = message;
|
||||
uiAppend(toastEl);
|
||||
toastEl = currentToast;
|
||||
currentToast.id = PREFIX + '-toast';
|
||||
currentToast.textContent = message;
|
||||
uiAppend(currentToast);
|
||||
requestAnimationFrame(() => {
|
||||
toastEl.style.opacity = '1';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(0)';
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '1';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(0)';
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (toastEl) {
|
||||
toastEl.style.opacity = '0';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => { if (toastEl) { toastEl.remove(); toastEl = null; } }, 250);
|
||||
}
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '0';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => {
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.remove();
|
||||
toastEl = null;
|
||||
}, 250);
|
||||
}, duration);
|
||||
}
|
||||
|
||||
|
||||
@@ -7928,7 +7928,7 @@ void main() {
|
||||
const barTopFromBottom = barRect && barRect.height > 0
|
||||
? Math.max(16, window.innerHeight - barRect.top + 12)
|
||||
: 16;
|
||||
toastEl = el('div', {
|
||||
const currentToast = el('div', {
|
||||
position: 'fixed', bottom: barTopFromBottom + 'px', left: '50%',
|
||||
transform: 'translateX(-50%) translateY(8px)',
|
||||
background: C.ink, color: C.white,
|
||||
@@ -7938,19 +7938,24 @@ void main() {
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.25s ' + EASE,
|
||||
pointerEvents: 'none', maxWidth: '420px', textAlign: 'center',
|
||||
});
|
||||
toastEl.id = PREFIX + '-toast';
|
||||
toastEl.textContent = message;
|
||||
uiAppend(toastEl);
|
||||
toastEl = currentToast;
|
||||
currentToast.id = PREFIX + '-toast';
|
||||
currentToast.textContent = message;
|
||||
uiAppend(currentToast);
|
||||
requestAnimationFrame(() => {
|
||||
toastEl.style.opacity = '1';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(0)';
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '1';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(0)';
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (toastEl) {
|
||||
toastEl.style.opacity = '0';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => { if (toastEl) { toastEl.remove(); toastEl = null; } }, 250);
|
||||
}
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '0';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => {
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.remove();
|
||||
toastEl = null;
|
||||
}, 250);
|
||||
}, duration);
|
||||
}
|
||||
|
||||
|
||||
@@ -7928,7 +7928,7 @@ void main() {
|
||||
const barTopFromBottom = barRect && barRect.height > 0
|
||||
? Math.max(16, window.innerHeight - barRect.top + 12)
|
||||
: 16;
|
||||
toastEl = el('div', {
|
||||
const currentToast = el('div', {
|
||||
position: 'fixed', bottom: barTopFromBottom + 'px', left: '50%',
|
||||
transform: 'translateX(-50%) translateY(8px)',
|
||||
background: C.ink, color: C.white,
|
||||
@@ -7938,19 +7938,24 @@ void main() {
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.25s ' + EASE,
|
||||
pointerEvents: 'none', maxWidth: '420px', textAlign: 'center',
|
||||
});
|
||||
toastEl.id = PREFIX + '-toast';
|
||||
toastEl.textContent = message;
|
||||
uiAppend(toastEl);
|
||||
toastEl = currentToast;
|
||||
currentToast.id = PREFIX + '-toast';
|
||||
currentToast.textContent = message;
|
||||
uiAppend(currentToast);
|
||||
requestAnimationFrame(() => {
|
||||
toastEl.style.opacity = '1';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(0)';
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '1';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(0)';
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (toastEl) {
|
||||
toastEl.style.opacity = '0';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => { if (toastEl) { toastEl.remove(); toastEl = null; } }, 250);
|
||||
}
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '0';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => {
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.remove();
|
||||
toastEl = null;
|
||||
}, 250);
|
||||
}, duration);
|
||||
}
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ jobs:
|
||||
bun-version: latest
|
||||
|
||||
- name: Cache fixture npm downloads
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-fixture-npm-${{ hashFiles('tests/framework-fixtures/**/files/package.json') }}
|
||||
@@ -172,7 +172,7 @@ jobs:
|
||||
${{ runner.os }}-fixture-npm-
|
||||
|
||||
- name: Cache Playwright Chromium
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.cache/ms-playwright
|
||||
key: ${{ runner.os }}-playwright-chromium-${{ hashFiles('package.json', 'bun.lock') }}
|
||||
@@ -238,7 +238,7 @@ jobs:
|
||||
bun-version: latest
|
||||
|
||||
- name: Cache fixture npm downloads
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-fixture-npm-${{ hashFiles('tests/framework-fixtures/**/files/package.json') }}
|
||||
@@ -246,7 +246,7 @@ jobs:
|
||||
${{ runner.os }}-fixture-npm-
|
||||
|
||||
- name: Cache Playwright Chromium
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.cache/ms-playwright
|
||||
key: ${{ runner.os }}-playwright-chromium-${{ hashFiles('package.json', 'bun.lock') }}
|
||||
@@ -307,7 +307,7 @@ jobs:
|
||||
|
||||
- name: Cache fixture npm downloads
|
||||
if: ${{ env.ANTHROPIC_API_KEY != '' || env.DEEPSEEK_API_KEY != '' }}
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-fixture-npm-${{ hashFiles('tests/framework-fixtures/**/files/package.json') }}
|
||||
@@ -316,7 +316,7 @@ jobs:
|
||||
|
||||
- name: Cache Playwright Chromium
|
||||
if: ${{ env.ANTHROPIC_API_KEY != '' || env.DEEPSEEK_API_KEY != '' }}
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.cache/ms-playwright
|
||||
key: ${{ runner.os }}-playwright-chromium-${{ hashFiles('package.json', 'bun.lock') }}
|
||||
@@ -371,7 +371,7 @@ jobs:
|
||||
|
||||
- name: Cache fixture npm downloads
|
||||
if: ${{ env.DEEPSEEK_API_KEY != '' }}
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-fixture-npm-${{ hashFiles('tests/framework-fixtures/**/files/package.json') }}
|
||||
@@ -380,7 +380,7 @@ jobs:
|
||||
|
||||
- name: Cache Playwright Chromium
|
||||
if: ${{ env.DEEPSEEK_API_KEY != '' }}
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.cache/ms-playwright
|
||||
key: ${{ runner.os }}-playwright-chromium-${{ hashFiles('package.json', 'bun.lock') }}
|
||||
|
||||
@@ -174,15 +174,15 @@
|
||||
"typographyMeta": {
|
||||
"wordmark": {
|
||||
"displayName": "Wordmark",
|
||||
"purpose": "IMPECCABLE lockup only. Solid Alumni Sans, not pinstripe."
|
||||
"purpose": "IMPECCABLE lockup only. Alumni Sans at weight 400."
|
||||
},
|
||||
"display": {
|
||||
"displayName": "Display",
|
||||
"purpose": "Hero h1. Alumni Sans Pinstripe, weight 300."
|
||||
"purpose": "Hero h1. Alumni Sans, weight 100."
|
||||
},
|
||||
"headline": {
|
||||
"displayName": "Headline",
|
||||
"purpose": "Section h2. Pinstripe at weight 600, heavier than display."
|
||||
"purpose": "Section h2. Alumni Sans at weight 300, heavier than display."
|
||||
},
|
||||
"title": {
|
||||
"displayName": "Title",
|
||||
@@ -360,12 +360,12 @@
|
||||
{
|
||||
"name": "The Weight-Inversion Rule",
|
||||
"section": "typography",
|
||||
"body": "Section h2s read heavier (600) than the hero h1 (300). This is deliberate: the hero is elegant and thin so the page can breathe; section anchors carry more weight to ground each block."
|
||||
"body": "Section h2s read heavier (300) than the hero h1 (100). This is deliberate: the hero is elegant and thin so the page can breathe; section anchors carry more weight to ground each block."
|
||||
},
|
||||
{
|
||||
"name": "The Two-Face Rule",
|
||||
"section": "typography",
|
||||
"body": "Display sizes use Alumni Sans Pinstripe. Anything sized below 1.2rem uses Albert Sans. Pinstripe at small sizes loses its identity and reads as a bad rendering."
|
||||
"body": "Display sizes use Alumni Sans — thin (100) for the h1, heavier (300) for h2s. Anything sized below 1.2rem uses Albert Sans. The thin display cut reads too light at small sizes, so it never carries body or UI text."
|
||||
},
|
||||
{
|
||||
"name": "The Tracked Labels Are Short Rule",
|
||||
|
||||
@@ -7928,7 +7928,7 @@ void main() {
|
||||
const barTopFromBottom = barRect && barRect.height > 0
|
||||
? Math.max(16, window.innerHeight - barRect.top + 12)
|
||||
: 16;
|
||||
toastEl = el('div', {
|
||||
const currentToast = el('div', {
|
||||
position: 'fixed', bottom: barTopFromBottom + 'px', left: '50%',
|
||||
transform: 'translateX(-50%) translateY(8px)',
|
||||
background: C.ink, color: C.white,
|
||||
@@ -7938,19 +7938,24 @@ void main() {
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.25s ' + EASE,
|
||||
pointerEvents: 'none', maxWidth: '420px', textAlign: 'center',
|
||||
});
|
||||
toastEl.id = PREFIX + '-toast';
|
||||
toastEl.textContent = message;
|
||||
uiAppend(toastEl);
|
||||
toastEl = currentToast;
|
||||
currentToast.id = PREFIX + '-toast';
|
||||
currentToast.textContent = message;
|
||||
uiAppend(currentToast);
|
||||
requestAnimationFrame(() => {
|
||||
toastEl.style.opacity = '1';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(0)';
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '1';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(0)';
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (toastEl) {
|
||||
toastEl.style.opacity = '0';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => { if (toastEl) { toastEl.remove(); toastEl = null; } }, 250);
|
||||
}
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '0';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => {
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.remove();
|
||||
toastEl = null;
|
||||
}, 250);
|
||||
}, duration);
|
||||
}
|
||||
|
||||
|
||||
@@ -7928,7 +7928,7 @@ void main() {
|
||||
const barTopFromBottom = barRect && barRect.height > 0
|
||||
? Math.max(16, window.innerHeight - barRect.top + 12)
|
||||
: 16;
|
||||
toastEl = el('div', {
|
||||
const currentToast = el('div', {
|
||||
position: 'fixed', bottom: barTopFromBottom + 'px', left: '50%',
|
||||
transform: 'translateX(-50%) translateY(8px)',
|
||||
background: C.ink, color: C.white,
|
||||
@@ -7938,19 +7938,24 @@ void main() {
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.25s ' + EASE,
|
||||
pointerEvents: 'none', maxWidth: '420px', textAlign: 'center',
|
||||
});
|
||||
toastEl.id = PREFIX + '-toast';
|
||||
toastEl.textContent = message;
|
||||
uiAppend(toastEl);
|
||||
toastEl = currentToast;
|
||||
currentToast.id = PREFIX + '-toast';
|
||||
currentToast.textContent = message;
|
||||
uiAppend(currentToast);
|
||||
requestAnimationFrame(() => {
|
||||
toastEl.style.opacity = '1';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(0)';
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '1';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(0)';
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (toastEl) {
|
||||
toastEl.style.opacity = '0';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => { if (toastEl) { toastEl.remove(); toastEl = null; } }, 250);
|
||||
}
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '0';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => {
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.remove();
|
||||
toastEl = null;
|
||||
}, 250);
|
||||
}, duration);
|
||||
}
|
||||
|
||||
|
||||
@@ -7928,7 +7928,7 @@ void main() {
|
||||
const barTopFromBottom = barRect && barRect.height > 0
|
||||
? Math.max(16, window.innerHeight - barRect.top + 12)
|
||||
: 16;
|
||||
toastEl = el('div', {
|
||||
const currentToast = el('div', {
|
||||
position: 'fixed', bottom: barTopFromBottom + 'px', left: '50%',
|
||||
transform: 'translateX(-50%) translateY(8px)',
|
||||
background: C.ink, color: C.white,
|
||||
@@ -7938,19 +7938,24 @@ void main() {
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.25s ' + EASE,
|
||||
pointerEvents: 'none', maxWidth: '420px', textAlign: 'center',
|
||||
});
|
||||
toastEl.id = PREFIX + '-toast';
|
||||
toastEl.textContent = message;
|
||||
uiAppend(toastEl);
|
||||
toastEl = currentToast;
|
||||
currentToast.id = PREFIX + '-toast';
|
||||
currentToast.textContent = message;
|
||||
uiAppend(currentToast);
|
||||
requestAnimationFrame(() => {
|
||||
toastEl.style.opacity = '1';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(0)';
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '1';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(0)';
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (toastEl) {
|
||||
toastEl.style.opacity = '0';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => { if (toastEl) { toastEl.remove(); toastEl = null; } }, 250);
|
||||
}
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '0';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => {
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.remove();
|
||||
toastEl = null;
|
||||
}, 250);
|
||||
}, duration);
|
||||
}
|
||||
|
||||
|
||||
@@ -7928,7 +7928,7 @@ void main() {
|
||||
const barTopFromBottom = barRect && barRect.height > 0
|
||||
? Math.max(16, window.innerHeight - barRect.top + 12)
|
||||
: 16;
|
||||
toastEl = el('div', {
|
||||
const currentToast = el('div', {
|
||||
position: 'fixed', bottom: barTopFromBottom + 'px', left: '50%',
|
||||
transform: 'translateX(-50%) translateY(8px)',
|
||||
background: C.ink, color: C.white,
|
||||
@@ -7938,19 +7938,24 @@ void main() {
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.25s ' + EASE,
|
||||
pointerEvents: 'none', maxWidth: '420px', textAlign: 'center',
|
||||
});
|
||||
toastEl.id = PREFIX + '-toast';
|
||||
toastEl.textContent = message;
|
||||
uiAppend(toastEl);
|
||||
toastEl = currentToast;
|
||||
currentToast.id = PREFIX + '-toast';
|
||||
currentToast.textContent = message;
|
||||
uiAppend(currentToast);
|
||||
requestAnimationFrame(() => {
|
||||
toastEl.style.opacity = '1';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(0)';
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '1';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(0)';
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (toastEl) {
|
||||
toastEl.style.opacity = '0';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => { if (toastEl) { toastEl.remove(); toastEl = null; } }, 250);
|
||||
}
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '0';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => {
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.remove();
|
||||
toastEl = null;
|
||||
}, 250);
|
||||
}, duration);
|
||||
}
|
||||
|
||||
|
||||
@@ -7928,7 +7928,7 @@ void main() {
|
||||
const barTopFromBottom = barRect && barRect.height > 0
|
||||
? Math.max(16, window.innerHeight - barRect.top + 12)
|
||||
: 16;
|
||||
toastEl = el('div', {
|
||||
const currentToast = el('div', {
|
||||
position: 'fixed', bottom: barTopFromBottom + 'px', left: '50%',
|
||||
transform: 'translateX(-50%) translateY(8px)',
|
||||
background: C.ink, color: C.white,
|
||||
@@ -7938,19 +7938,24 @@ void main() {
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.25s ' + EASE,
|
||||
pointerEvents: 'none', maxWidth: '420px', textAlign: 'center',
|
||||
});
|
||||
toastEl.id = PREFIX + '-toast';
|
||||
toastEl.textContent = message;
|
||||
uiAppend(toastEl);
|
||||
toastEl = currentToast;
|
||||
currentToast.id = PREFIX + '-toast';
|
||||
currentToast.textContent = message;
|
||||
uiAppend(currentToast);
|
||||
requestAnimationFrame(() => {
|
||||
toastEl.style.opacity = '1';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(0)';
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '1';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(0)';
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (toastEl) {
|
||||
toastEl.style.opacity = '0';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => { if (toastEl) { toastEl.remove(); toastEl = null; } }, 250);
|
||||
}
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '0';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => {
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.remove();
|
||||
toastEl = null;
|
||||
}, 250);
|
||||
}, duration);
|
||||
}
|
||||
|
||||
|
||||
@@ -7928,7 +7928,7 @@ void main() {
|
||||
const barTopFromBottom = barRect && barRect.height > 0
|
||||
? Math.max(16, window.innerHeight - barRect.top + 12)
|
||||
: 16;
|
||||
toastEl = el('div', {
|
||||
const currentToast = el('div', {
|
||||
position: 'fixed', bottom: barTopFromBottom + 'px', left: '50%',
|
||||
transform: 'translateX(-50%) translateY(8px)',
|
||||
background: C.ink, color: C.white,
|
||||
@@ -7938,19 +7938,24 @@ void main() {
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.25s ' + EASE,
|
||||
pointerEvents: 'none', maxWidth: '420px', textAlign: 'center',
|
||||
});
|
||||
toastEl.id = PREFIX + '-toast';
|
||||
toastEl.textContent = message;
|
||||
uiAppend(toastEl);
|
||||
toastEl = currentToast;
|
||||
currentToast.id = PREFIX + '-toast';
|
||||
currentToast.textContent = message;
|
||||
uiAppend(currentToast);
|
||||
requestAnimationFrame(() => {
|
||||
toastEl.style.opacity = '1';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(0)';
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '1';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(0)';
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (toastEl) {
|
||||
toastEl.style.opacity = '0';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => { if (toastEl) { toastEl.remove(); toastEl = null; } }, 250);
|
||||
}
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '0';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => {
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.remove();
|
||||
toastEl = null;
|
||||
}, 250);
|
||||
}, duration);
|
||||
}
|
||||
|
||||
|
||||
@@ -7928,7 +7928,7 @@ void main() {
|
||||
const barTopFromBottom = barRect && barRect.height > 0
|
||||
? Math.max(16, window.innerHeight - barRect.top + 12)
|
||||
: 16;
|
||||
toastEl = el('div', {
|
||||
const currentToast = el('div', {
|
||||
position: 'fixed', bottom: barTopFromBottom + 'px', left: '50%',
|
||||
transform: 'translateX(-50%) translateY(8px)',
|
||||
background: C.ink, color: C.white,
|
||||
@@ -7938,19 +7938,24 @@ void main() {
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.25s ' + EASE,
|
||||
pointerEvents: 'none', maxWidth: '420px', textAlign: 'center',
|
||||
});
|
||||
toastEl.id = PREFIX + '-toast';
|
||||
toastEl.textContent = message;
|
||||
uiAppend(toastEl);
|
||||
toastEl = currentToast;
|
||||
currentToast.id = PREFIX + '-toast';
|
||||
currentToast.textContent = message;
|
||||
uiAppend(currentToast);
|
||||
requestAnimationFrame(() => {
|
||||
toastEl.style.opacity = '1';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(0)';
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '1';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(0)';
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (toastEl) {
|
||||
toastEl.style.opacity = '0';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => { if (toastEl) { toastEl.remove(); toastEl = null; } }, 250);
|
||||
}
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '0';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => {
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.remove();
|
||||
toastEl = null;
|
||||
}, 250);
|
||||
}, duration);
|
||||
}
|
||||
|
||||
|
||||
@@ -104,24 +104,24 @@ colors:
|
||||
|
||||
typography:
|
||||
wordmark:
|
||||
# Solid Alumni Sans (token --ks-font-wordmark), the weightable sibling of
|
||||
# the pinstripe display face. The pinstripe itself is single-weight and
|
||||
# reads too thin in the small lockup, so the wordmark uses the solid cut.
|
||||
fontFamily: "Alumni Sans, Alumni Sans Pinstripe, Albert Sans, Arial, sans-serif"
|
||||
# Alumni Sans (token --ks-font-wordmark), the same face as display, held
|
||||
# at weight 400 for the small brand lockup where the thin display cut
|
||||
# would read too light.
|
||||
fontFamily: "Alumni Sans, Albert Sans, Arial, sans-serif"
|
||||
fontSize: "1.3rem"
|
||||
fontWeight: 400
|
||||
letterSpacing: "0.15em"
|
||||
lineHeight: 1
|
||||
display:
|
||||
fontFamily: "Alumni Sans Pinstripe, Albert Sans, Arial, sans-serif"
|
||||
fontFamily: "Alumni Sans, Albert Sans, Arial, sans-serif"
|
||||
fontSize: "clamp(3.4rem, 6.5vw, 5.6rem)"
|
||||
fontWeight: 300
|
||||
fontWeight: 100
|
||||
letterSpacing: "-0.01em"
|
||||
lineHeight: 1.02
|
||||
headline:
|
||||
fontFamily: "Alumni Sans Pinstripe, Albert Sans, Arial, sans-serif"
|
||||
fontFamily: "Alumni Sans, Albert Sans, Arial, sans-serif"
|
||||
fontSize: "clamp(2.6rem, 4vw, 3.4rem)"
|
||||
fontWeight: 600
|
||||
fontWeight: 300
|
||||
letterSpacing: "0"
|
||||
lineHeight: 1.04
|
||||
title:
|
||||
@@ -262,7 +262,7 @@ Every class below is a global primitive. Drop it on any element on any page usin
|
||||
- `.ks-section` — page-level section container, 1320px max-width, kit gutters.
|
||||
- `.ks-section-head` — the section header block.
|
||||
- `.ks-section-eyebrow` — small mono eyebrow above the h2 (optional).
|
||||
- `.ks-section-head h2` — auto-styles any h2 inside `.ks-section-head` to the section title scale (weight 600, kit display family).
|
||||
- `.ks-section-head h2` — auto-styles any h2 inside `.ks-section-head` to the section title scale (weight 300, kit display family).
|
||||
- `.ks-section-sub` — subhead paragraph below the h2.
|
||||
- `.ks-subsection` — nested grouping inside a section.
|
||||
- `.ks-subsection-label` — small mono label above a subsection's content.
|
||||
@@ -376,17 +376,17 @@ Do not hand-type oklch values or font sizes in page CSS. If a value isn't in the
|
||||
|
||||
## 4. Typography: Two faces, weight inversion at the top
|
||||
|
||||
**Display font:** Alumni Sans Pinstripe, Albert Sans, Arial, sans-serif (pinstripe horizontal strikes carry the brand at display sizes)
|
||||
**Display font:** Alumni Sans, Albert Sans, Arial, sans-serif (a thin hairline cut carries the brand at display sizes)
|
||||
**Body and UI font:** Albert Sans, Avenir Next, Helvetica Neue, Arial, system-ui, sans-serif
|
||||
**Mono font:** SFMono-Regular, Roboto Mono, Consolas, monospace
|
||||
|
||||
The voice is geometric and restrained. The pinstripe display face is reserved for the hero h1 and section h2s; the brand wordmark uses its solid sibling (Alumni Sans). Everything else (body, UI labels, controls, code) uses Albert Sans. The faces pair cleanly because they share humanist proportions without fighting for attention.
|
||||
The voice is geometric and restrained. The Alumni Sans display face is reserved for the hero h1 and section h2s; the brand wordmark uses the same face at a heavier weight. Everything else (body, UI labels, controls, code) uses Albert Sans. The faces pair cleanly because they share humanist proportions without fighting for attention.
|
||||
|
||||
### Hierarchy
|
||||
|
||||
- **Wordmark**: solid Alumni Sans (`--ks-font-wordmark`), weight 400, uppercase, `1.3rem`, letter-spacing `0.15em`. Brand lockup only. The pinstripe sibling reads too thin at lockup size, so the wordmark uses the weightable cut.
|
||||
- **Display · h1**: Alumni Sans Pinstripe, `clamp(3.4rem, 6.5vw, 5.6rem)`, **weight 300**, line-height 1.02, letter-spacing `-0.01em`. Hero and major statements.
|
||||
- **Headline · h2**: Alumni Sans Pinstripe, `clamp(2.6rem, 4vw, 3.4rem)`, **weight 600**, line-height 1.04. Section titles.
|
||||
- **Wordmark**: Alumni Sans (`--ks-font-wordmark`), weight 400, uppercase, `1.3rem`, letter-spacing `0.15em`. Brand lockup only. The thin display cut reads too light at lockup size, so the wordmark holds weight 400.
|
||||
- **Display · h1**: Alumni Sans, `clamp(3.4rem, 6.5vw, 5.6rem)`, **weight 100**, line-height 1.02, letter-spacing `-0.01em`. Hero and major statements.
|
||||
- **Headline · h2**: Alumni Sans, `clamp(2.6rem, 4vw, 3.4rem)`, **weight 300**, line-height 1.04. Section titles.
|
||||
- **Title · h3**: Albert Sans, `1.18rem`, weight 500, line-height 1.35. Component and panel headings.
|
||||
- **Body**: Albert Sans, `1.02rem`, weight 400, line-height 1.8. Long copy on dark surfaces needs air.
|
||||
- **Eyebrow**: Mono, `0.7rem`, weight 500, uppercase, letter-spacing `0.18em`. Small markers above titles.
|
||||
@@ -394,9 +394,9 @@ The voice is geometric and restrained. The pinstripe display face is reserved fo
|
||||
|
||||
### Typography Rules
|
||||
|
||||
**The Weight-Inversion Rule.** Section h2s read heavier (600) than the hero h1 (300). This is deliberate: the hero is elegant and thin so the page can breathe; section anchors carry more weight to ground each block. Do not normalize the two weights.
|
||||
**The Weight-Inversion Rule.** Section h2s read heavier (300) than the hero h1 (100). This is deliberate: the hero is elegant and thin so the page can breathe; section anchors carry more weight to ground each block. Do not normalize the two weights.
|
||||
|
||||
**The Two-Face Rule.** Display sizes use Alumni Sans Pinstripe. Anything sized below `1.2rem` uses Albert Sans. Pinstripe at small sizes loses its identity and reads as a bad rendering.
|
||||
**The Two-Face Rule.** Display sizes use Alumni Sans — thin (100) for the h1, heavier (300) for h2s. Anything sized below `1.2rem` uses Albert Sans. The thin display cut reads too light at small sizes, so it never carries body or UI text.
|
||||
|
||||
**Tracked Labels Are Short Rule.** Tracked uppercase labels are for short system markers. Do not write full sentences in tracked caps.
|
||||
|
||||
@@ -446,7 +446,7 @@ The command table uses dark category cells. Kinpaku covers Create, Refine, and S
|
||||
|
||||
### DESIGN.md Panel
|
||||
|
||||
The DESIGN.md visualization must show kinpaku as the primary color, patina as the secondary color, Alumni Sans Pinstripe and Albert Sans as the display and body families, and dark component samples. Magenta is not representative of the current system.
|
||||
The DESIGN.md visualization must show kinpaku as the primary color, patina as the secondary color, Alumni Sans and Albert Sans as the display and body families, and dark component samples. Magenta is not representative of the current system.
|
||||
|
||||
### Dividers and Material Accents
|
||||
|
||||
|
||||
@@ -13,14 +13,14 @@
|
||||
"marked": "^18.0.5",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ai-sdk/anthropic": "^3.0.71",
|
||||
"@ai-sdk/google": "^3.0.75",
|
||||
"@ai-sdk/openai": "^3.0.53",
|
||||
"@ai-sdk/anthropic": "^4.0.7",
|
||||
"@ai-sdk/google": "^4.0.8",
|
||||
"@ai-sdk/openai": "^4.0.7",
|
||||
"@anthropic-ai/claude-agent-sdk": "^0.3.165",
|
||||
"@anthropic-ai/sdk": "^0.105.0",
|
||||
"@anthropic-ai/sdk": "^0.107.0",
|
||||
"@google/genai": "^2.8.0",
|
||||
"@paper-design/shaders": "^0.0.76",
|
||||
"ai": "^6.0.168",
|
||||
"ai": "^7.0.14",
|
||||
"archiver": "^8.0.0",
|
||||
"astro": "^7.0.0",
|
||||
"fontkit": "^2.0.4",
|
||||
@@ -37,37 +37,37 @@
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.85", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.30" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-fNeDB644l5wbRNQU0FnI+F7UTtOenMnPtACfMPUJaS2zJfuBlseEa1TMg+otHkETZgaJB+6Na51NQEv0+m7czw=="],
|
||||
"@ai-sdk/anthropic": ["@ai-sdk/anthropic@4.0.7", "", { "dependencies": { "@ai-sdk/provider": "4.0.2", "@ai-sdk/provider-utils": "5.0.5" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-PaUAERndv7dI2IUlXM58RPmOx5MRl1jtC9ECkXl5TTi/08R3Ht8fY3d6X9ihKV3fk+JcnrEznR8gbhb1nguRZg=="],
|
||||
|
||||
"@ai-sdk/gateway": ["@ai-sdk/gateway@3.0.133", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.30", "@vercel/oidc": "3.2.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-Ebs+7iS9zUgJu5B0RlxM2JmDWzq79Cpd6YdiqcCzB5qFdpfQJPUDiXutqlQP89F2XGjOdDeidulBTXUdXWzOxw=="],
|
||||
"@ai-sdk/gateway": ["@ai-sdk/gateway@4.0.11", "", { "dependencies": { "@ai-sdk/provider": "4.0.2", "@ai-sdk/provider-utils": "5.0.5", "@vercel/oidc": "3.2.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ZdZzQnBxYfjJpWpSNkV+rRWycwTBhxyvwGvxcwx9g+WQoy3MK2xNahSySEgP9hD/X2xY9jkjd0xB67oDE3rLMA=="],
|
||||
|
||||
"@ai-sdk/google": ["@ai-sdk/google@3.0.83", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.30" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-Pz7aCX0dy+5x+r4K/37HbLZNaPtPL4q2NduzJW64VffLv5sI9Nb478wAd7PlH2r2asiypJsz/Jerf9draTciUA=="],
|
||||
"@ai-sdk/google": ["@ai-sdk/google@4.0.8", "", { "dependencies": { "@ai-sdk/provider": "4.0.2", "@ai-sdk/provider-utils": "5.0.5" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-GELd0RkltieuODzr6tfnEOIufeooctYpGUNxujeh+zrChbHUkX2K6Li4h2EAfizctkY4k3JvC93dU9eh2QxzoQ=="],
|
||||
|
||||
"@ai-sdk/openai": ["@ai-sdk/openai@3.0.74", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.30" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-LPDBWd2WCv0GQs29K2pHcNrGx24hm4D8QEP386HwUAUPr1URho6bNVXHNmIv0FxaW+xDkLpNMTen+mFCUBp2LA=="],
|
||||
"@ai-sdk/openai": ["@ai-sdk/openai@4.0.7", "", { "dependencies": { "@ai-sdk/provider": "4.0.2", "@ai-sdk/provider-utils": "5.0.5" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-55K0j8RRjcKosUvIl8u/+SMaS1wedq77xN2iuhlOvB/USbIgSmjkWKV9lqGhhp+Qxhnm3qg5NzrqOI1jmra9fQ=="],
|
||||
|
||||
"@ai-sdk/provider": ["@ai-sdk/provider@3.0.10", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw=="],
|
||||
"@ai-sdk/provider": ["@ai-sdk/provider@4.0.2", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-pfPoy9J1B1xV7cqJ8MYHOsDYrMv5tR3+EMNfI249OhkD2uRakvav3Fo7XpD2luuN/YNCBY7KfEQc7vEV7KEtyw=="],
|
||||
|
||||
"@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.30", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.8" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-VO7I+vPffqI5sMnPoUq5DCSqKIgQIk/naJWRdQVpz2ma2zoprC/lqiJiUEl2s6DfvTD76TbhD3q39ROjlA6rGw=="],
|
||||
"@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@5.0.5", "", { "dependencies": { "@ai-sdk/provider": "4.0.2", "@standard-schema/spec": "^1.1.0", "@workflow/serde": "4.1.0", "eventsource-parser": "^3.0.8" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-oI0t3dvCoqWNV1I8o1Rybi2DXDvHES5r/TrwtJW90tuFLVepgJlftPxrcjh8vaSvjqC2diTuA2vXyjKAyHJm4A=="],
|
||||
|
||||
"@anthropic-ai/claude-agent-sdk": ["@anthropic-ai/claude-agent-sdk@0.3.185", "", { "optionalDependencies": { "@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.3.185", "@anthropic-ai/claude-agent-sdk-darwin-x64": "0.3.185", "@anthropic-ai/claude-agent-sdk-linux-arm64": "0.3.185", "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.3.185", "@anthropic-ai/claude-agent-sdk-linux-x64": "0.3.185", "@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.3.185", "@anthropic-ai/claude-agent-sdk-win32-arm64": "0.3.185", "@anthropic-ai/claude-agent-sdk-win32-x64": "0.3.185" }, "peerDependencies": { "@anthropic-ai/sdk": ">=0.93.0", "@modelcontextprotocol/sdk": "^1.29.0", "zod": "^4.0.0" } }, "sha512-UDDd0cInvOufmR88btR/Ursnh71sb5scoutNlRS2L0LBdkt7JEqYJ0jt7DnOYHEVhMx8AAcg0eYgvXztcWUnFA=="],
|
||||
"@anthropic-ai/claude-agent-sdk": ["@anthropic-ai/claude-agent-sdk@0.3.195", "", { "optionalDependencies": { "@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.3.195", "@anthropic-ai/claude-agent-sdk-darwin-x64": "0.3.195", "@anthropic-ai/claude-agent-sdk-linux-arm64": "0.3.195", "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.3.195", "@anthropic-ai/claude-agent-sdk-linux-x64": "0.3.195", "@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.3.195", "@anthropic-ai/claude-agent-sdk-win32-arm64": "0.3.195", "@anthropic-ai/claude-agent-sdk-win32-x64": "0.3.195" }, "peerDependencies": { "@anthropic-ai/sdk": ">=0.93.0", "@modelcontextprotocol/sdk": "^1.29.0", "zod": "^4.0.0" } }, "sha512-FVmXu9pvOMbuBKWrF8YsYQdQ/upOpv5rS8lFAnFO5jbyXT/2hN7kEPd2vd2GJpaMvNcO/KptyQUK5AxjjTz3+w=="],
|
||||
|
||||
"@anthropic-ai/claude-agent-sdk-darwin-arm64": ["@anthropic-ai/claude-agent-sdk-darwin-arm64@0.3.185", "", { "os": "darwin", "cpu": "arm64" }, "sha512-P2Svxx1IFrS9aw4ylJBtcoJrc/OAOVnDs+o05x4TV7HoHUQUcKZ9XhWOGnadyVT0KLyoktgjyjnaK7Zdtc0Ldg=="],
|
||||
"@anthropic-ai/claude-agent-sdk-darwin-arm64": ["@anthropic-ai/claude-agent-sdk-darwin-arm64@0.3.195", "", { "os": "darwin", "cpu": "arm64" }, "sha512-WIMM/8HRCLsTDHFTIwQvvE8WCA/oaMJtdQxsP7iNyfzIGwXbuOyU95V8vYIhZfaO2yaSpbBRncunq4CtR5H4ng=="],
|
||||
|
||||
"@anthropic-ai/claude-agent-sdk-darwin-x64": ["@anthropic-ai/claude-agent-sdk-darwin-x64@0.3.185", "", { "os": "darwin", "cpu": "x64" }, "sha512-H69m2hIJawzSkCDNO/CPLQCYvDGdlbZdzGTgGF8/IQuB4O81sv8WSAh6TBXwtFXOgEi4HtrUYlxiFDmTHt7hMA=="],
|
||||
"@anthropic-ai/claude-agent-sdk-darwin-x64": ["@anthropic-ai/claude-agent-sdk-darwin-x64@0.3.195", "", { "os": "darwin", "cpu": "x64" }, "sha512-RY7DB+4LXosE0MJ+XELmakfPrDN1YX4lkk9CTDm28jGCVcESRz9kAEqbyaiC48dZcmN9V1NCLutzINGdcr1TBg=="],
|
||||
|
||||
"@anthropic-ai/claude-agent-sdk-linux-arm64": ["@anthropic-ai/claude-agent-sdk-linux-arm64@0.3.185", "", { "os": "linux", "cpu": "arm64" }, "sha512-KtXMCoprGYTSPb/A0/kjrO+PpDJAFbHhDd8rjqA4izU51OYjTDkahsGCcSTFM2jA8krOhPqzx/SNVuAVWmexwA=="],
|
||||
"@anthropic-ai/claude-agent-sdk-linux-arm64": ["@anthropic-ai/claude-agent-sdk-linux-arm64@0.3.195", "", { "os": "linux", "cpu": "arm64" }, "sha512-JuIq5Fnz/F1snl0aqi1gcuRZqPWoPNrL9dJ0DuievCxKkO8hnEz/Mmn5Zos7x1X8HE//ZnEvmQXoEQEZXonJew=="],
|
||||
|
||||
"@anthropic-ai/claude-agent-sdk-linux-arm64-musl": ["@anthropic-ai/claude-agent-sdk-linux-arm64-musl@0.3.185", "", { "os": "linux", "cpu": "arm64" }, "sha512-1GRpKYrg5foomW+qLrxm/k2R/5PEU7RAuEdX65HV6lFMJR3HsGj8qfBq4KCJHTS3r4YdVrFLvPQ/mUqbY6klIA=="],
|
||||
"@anthropic-ai/claude-agent-sdk-linux-arm64-musl": ["@anthropic-ai/claude-agent-sdk-linux-arm64-musl@0.3.195", "", { "os": "linux", "cpu": "arm64" }, "sha512-ZmyBA/AFzhgutcxb7dbhCm6GTjJytwNYXTxJoKE2B3A409WCYccjMqeji6vCMNxyyfylglGo5D8dVMIxW9aoug=="],
|
||||
|
||||
"@anthropic-ai/claude-agent-sdk-linux-x64": ["@anthropic-ai/claude-agent-sdk-linux-x64@0.3.185", "", { "os": "linux", "cpu": "x64" }, "sha512-8U5wu6dNcyzRkwoae0Gu5ZHs6lRSu8CXqd9yrilX3fHR9kKICrm76bLu5q2auuSc/8dx6VL5ZXqSzFKIMp//zw=="],
|
||||
"@anthropic-ai/claude-agent-sdk-linux-x64": ["@anthropic-ai/claude-agent-sdk-linux-x64@0.3.195", "", { "os": "linux", "cpu": "x64" }, "sha512-s1lNi1cL93luoqsItH+fNO4KpIhdkvnVhWGGQUQ/8ftwa2gfmcIQnOg1hG8Ks+KzeD3UUQ8L9YEVHVADnFI/9A=="],
|
||||
|
||||
"@anthropic-ai/claude-agent-sdk-linux-x64-musl": ["@anthropic-ai/claude-agent-sdk-linux-x64-musl@0.3.185", "", { "os": "linux", "cpu": "x64" }, "sha512-YAky0Oez+YYrlcas/xDiaCm9AUX0z1YwM+pnk+CFxEr/ICmc7MbiFsnEIXFLPHaox9bE5iOzw4LS4b/c1tIJRg=="],
|
||||
"@anthropic-ai/claude-agent-sdk-linux-x64-musl": ["@anthropic-ai/claude-agent-sdk-linux-x64-musl@0.3.195", "", { "os": "linux", "cpu": "x64" }, "sha512-nf8Q/LauB+ZOC6QDjxNhbsvwUtYjKYnaWJLTYFwhkmsLujePnety1AtT/1ubaUoq5AM1j297DhMlYTasa79OUA=="],
|
||||
|
||||
"@anthropic-ai/claude-agent-sdk-win32-arm64": ["@anthropic-ai/claude-agent-sdk-win32-arm64@0.3.185", "", { "os": "win32", "cpu": "arm64" }, "sha512-pJEOaCLQQQWSyBeseR/GAn4eEp4WtMDP/o5yPMuuAsNWeoJXM7cY4j/N3KBE6GZofgnYdWEXILF2uw3SjbtINA=="],
|
||||
"@anthropic-ai/claude-agent-sdk-win32-arm64": ["@anthropic-ai/claude-agent-sdk-win32-arm64@0.3.195", "", { "os": "win32", "cpu": "arm64" }, "sha512-hbkDE+xPIZzRWm+D+BKrH9uJH6USIZdDIlsyrIlGi3JFHoieYoA1vdUNyldSS9+F3ZqQtfPjr2Qy08IVB6akYA=="],
|
||||
|
||||
"@anthropic-ai/claude-agent-sdk-win32-x64": ["@anthropic-ai/claude-agent-sdk-win32-x64@0.3.185", "", { "os": "win32", "cpu": "x64" }, "sha512-/Kf9XneSuIkSHNwrxOVY0XT7RovAEcx5nDASKzku4994cZz54otU5mT2jT6dwevDLEStfgts5x/A4z0AePwVTQ=="],
|
||||
"@anthropic-ai/claude-agent-sdk-win32-x64": ["@anthropic-ai/claude-agent-sdk-win32-x64@0.3.195", "", { "os": "win32", "cpu": "x64" }, "sha512-av0piEB3X1Dzhpr8A+DqHVZ9y8s1jpn8enzwX0TKKUPBn5IqLTWC7wD6v66aoUgu4f+g4ThZirmDZA6shyPEZQ=="],
|
||||
|
||||
"@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.105.0", "", { "dependencies": { "json-schema-to-ts": "^3.1.1", "standardwebhooks": "^1.0.0" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["zod"], "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-sDyu+aM9cE6uZE+HgRjjHRb+qqb87GHZOx+8bE0YlWetdL1YcVLxn8h9ltxGOflyChTe6PMEo50kMQV4cw0hfg=="],
|
||||
"@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.107.0", "", { "dependencies": { "json-schema-to-ts": "^3.1.1", "standardwebhooks": "^1.0.0" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["zod"], "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-RWDWyvIeZnatUTzyX8+ayFzAqqLyoDHKnDEODFyW8H89zH+qEsh5h6XAmnbHY5DCoa58o3rjuNe3F3Hg851ayA=="],
|
||||
|
||||
"@astrojs/compiler-binding": ["@astrojs/compiler-binding@0.2.3", "", { "optionalDependencies": { "@astrojs/compiler-binding-darwin-arm64": "0.2.3", "@astrojs/compiler-binding-darwin-x64": "0.2.3", "@astrojs/compiler-binding-linux-arm64-gnu": "0.2.3", "@astrojs/compiler-binding-linux-arm64-musl": "0.2.3", "@astrojs/compiler-binding-linux-x64-gnu": "0.2.3", "@astrojs/compiler-binding-linux-x64-musl": "0.2.3", "@astrojs/compiler-binding-wasm32-wasi": "0.2.3", "@astrojs/compiler-binding-win32-arm64-msvc": "0.2.3", "@astrojs/compiler-binding-win32-x64-msvc": "0.2.3" } }, "sha512-Xz3iBNse+hXXD25IXxsuXEt2ai8klAWE15CRm/EQBc9+aE3jXaF07DZx+iakk3HC6NHvWlEPzLPyxsLgPzOJsw=="],
|
||||
|
||||
@@ -137,15 +137,15 @@
|
||||
|
||||
"@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.16.1", "", { "peerDependencies": { "unenv": "2.0.0-rc.24", "workerd": ">1.20260305.0 <2.0.0-0" }, "optionalPeers": ["workerd"] }, "sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw=="],
|
||||
|
||||
"@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20260617.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-jWwmgEVVWbsHNrLSNXzwjJaH90VzRxq1cWkQFUidxyeUPnMxemeNE8I9qFAfrpzGgE11e9sKDcE3ettJW08swQ=="],
|
||||
"@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20260625.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-naCfBv0WnnTQIQPTniqMoUlklOIFjrAcSn1X+IAOhY8aFLF/xGYtFjs1eEE8sFib3ZuChGGpU23FFORVczqr0A=="],
|
||||
|
||||
"@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20260617.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-LHH7b565g9znfCUOkwbec6FG2rmRbsgCy6aJiU9KN662mNheWl5sw/iKleiFSiljPKQQP3HkjnC/NSkdgi/aSA=="],
|
||||
"@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20260625.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-jmH6zjp6Wrux46+qtFwDwrj+vd7s5bdwEqeGvdnwE0a4IEeAhKs0L42HQOyID+g5lkrHq9m55+AbhtmRAm63Pw=="],
|
||||
|
||||
"@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20260617.1", "", { "os": "linux", "cpu": "x64" }, "sha512-FMnaAKXe4Cfd8TQurCVd9fs2XQVBFRCsP+Id/SRdUv89MlwYu9zXfoyx6BxM+brPTIUK38SHbo8iaxiwzLi9JQ=="],
|
||||
"@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20260625.1", "", { "os": "linux", "cpu": "x64" }, "sha512-MiQkpA/dX8d83Zp64pzHUKfd6ca4cvwxnNobSP6CnXvfESvnNI9pfa+nfwnParla36sPmnYntNkjR7NjRuDeKQ=="],
|
||||
|
||||
"@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20260617.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-MRoifFYcqbxxIIQy7PqO5tFY/qPFSnjXzakWl0sO93l+HLyG35jRAgOi6jfqa4kBxc7gKKtH861DcewjxUfkjA=="],
|
||||
"@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20260625.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-LxxW7Qv60Xvv37+w6gUSDpYZziyqMy+cZWd9IvSA5ehVgKAxmzEaYPMiSZlxk32nbIWL9u/tfjXYCOKJ4Lo+XQ=="],
|
||||
|
||||
"@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20260617.1", "", { "os": "win32", "cpu": "x64" }, "sha512-rgBV9wQrv0OSKgCTTbhFUFY3sLGNANZ88aqaLvtmEn2gmbFVb1J4PDGochVUdB7NSEp4D/ghHva6/8SZmbONpw=="],
|
||||
"@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20260625.1", "", { "os": "win32", "cpu": "x64" }, "sha512-LH6iIX1HHaTwVKV5VokDxxUErXJzQoNZFRwVm7Vx/3fB/ApcTcRCUaMqcxI4as94jEUqg+pmX5czOndiveohow=="],
|
||||
|
||||
"@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="],
|
||||
|
||||
@@ -207,7 +207,7 @@
|
||||
|
||||
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.1", "", { "os": "win32", "cpu": "x64" }, "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A=="],
|
||||
|
||||
"@google/genai": ["@google/genai@2.9.0", "", { "dependencies": { "google-auth-library": "^10.3.0", "p-retry": "^4.6.2", "protobufjs": "^7.5.4", "ws": "^8.18.0" }, "peerDependencies": { "@modelcontextprotocol/sdk": "^1.25.2" }, "optionalPeers": ["@modelcontextprotocol/sdk"] }, "sha512-3DRdSJ0LaKFig3FNGeRDn9BQxtjZm2qr0hNH2d771LKcG0HvUYddlN0LPdSp8XU7Ekb04i9q3+tt64uYqavUdw=="],
|
||||
"@google/genai": ["@google/genai@2.10.0", "", { "dependencies": { "google-auth-library": "^10.3.0", "p-retry": "^4.6.2", "protobufjs": "^7.5.4", "ws": "^8.18.0" }, "peerDependencies": { "@modelcontextprotocol/sdk": "^1.25.2" }, "optionalPeers": ["@modelcontextprotocol/sdk"] }, "sha512-e4cFxj3tiuMtsgOT4G9c1hXyGJhg7/Buj7VVeBacRY3fRtkRZZ59Q3nuVp2xbq8BGQXLXCDB253qMhklMOeUDg=="],
|
||||
|
||||
"@hono/node-server": ["@hono/node-server@1.19.14", "", { "peerDependencies": { "hono": "^4" } }, "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw=="],
|
||||
|
||||
@@ -271,8 +271,6 @@
|
||||
|
||||
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.6", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg=="],
|
||||
|
||||
"@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="],
|
||||
|
||||
"@oslojs/encoding": ["@oslojs/encoding@1.1.0", "", {}, "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ=="],
|
||||
|
||||
"@oxc-project/types": ["@oxc-project/types@0.137.0", "", {}, "sha512-WT+Gb24i8hmvo85AIv2oEYouEXkRlKAlT9WaCa3TfLgNCN+GhrJOGZuIlMouAh38Qe4QOx26eUOVsq70qXrywA=="],
|
||||
@@ -439,13 +437,15 @@
|
||||
|
||||
"@vercel/oidc": ["@vercel/oidc@3.2.0", "", {}, "sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug=="],
|
||||
|
||||
"@workflow/serde": ["@workflow/serde@4.1.0", "", {}, "sha512-pav4F2BoirECWR7Nf1TKt+2eETcBj7jj4cBefQ8VXQCA6NPkaKeLfj/zMgi+3zYV5ZIBT4GuUiphsj0/b9hPQQ=="],
|
||||
|
||||
"abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="],
|
||||
|
||||
"accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="],
|
||||
|
||||
"agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="],
|
||||
|
||||
"ai": ["ai@6.0.208", "", { "dependencies": { "@ai-sdk/gateway": "3.0.133", "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.30", "@opentelemetry/api": "^1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-STz+AaZqJ4ZjH7UkpXkbHx+bjgIDOsE8fIUoZjkZ2whoZcfVmG9K/TqEKouJZ03SuZuD7lagntlU3zBhAEkRpQ=="],
|
||||
"ai": ["ai@7.0.14", "", { "dependencies": { "@ai-sdk/gateway": "4.0.11", "@ai-sdk/provider": "4.0.2", "@ai-sdk/provider-utils": "5.0.5" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-qA82fZyD4xh9IDB+s3SvwbjwjR+GGRmJjTYMwON1uROj8vPDIQbPTZLLq6ZWTVESn9daeH1GMv0zKfVLwNU2sQ=="],
|
||||
|
||||
"ajv": ["ajv@8.18.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="],
|
||||
|
||||
@@ -689,7 +689,7 @@
|
||||
|
||||
"forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="],
|
||||
|
||||
"framer-motion": ["framer-motion@12.40.0", "", { "dependencies": { "motion-dom": "^12.40.0", "motion-utils": "^12.39.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-uaBd3qC1v3KQqBEjwTUd183K6PbS+j0yR9w9VmEOLWA/tnUcSn8Xa3uck7t4dgpDoUss8xQTcj8W2L07lrnLFg=="],
|
||||
"framer-motion": ["framer-motion@12.42.0", "", { "dependencies": { "motion-dom": "^12.42.0", "motion-utils": "^12.39.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-wp7EJnfWaaEScVygKv3e20udoRz+LbtxScsuTkakAxfXmt+ReC6WyPW2nINRAGvd+hG9odwcjBLyOTPjH5pBRA=="],
|
||||
|
||||
"fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="],
|
||||
|
||||
@@ -863,7 +863,7 @@
|
||||
|
||||
"mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="],
|
||||
|
||||
"miniflare": ["miniflare@4.20260617.1", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "0.34.5", "undici": "7.28.0", "workerd": "1.20260617.1", "ws": "8.21.0", "youch": "4.1.0-beta.10" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-Go3/gzStm99QHptsSgU+q1S+xDfLoRgwjJNY80kaTVi0ENhTyqKq+sc4xZiWBSbM7uUcJwmzm8+QFKtcYLJ9nw=="],
|
||||
"miniflare": ["miniflare@4.20260625.0", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "0.34.5", "undici": "7.28.0", "workerd": "1.20260625.1", "ws": "8.21.0", "youch": "4.1.0-beta.10" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-3kKXwRUObJsnBYPBgR0NiNZYKF/yv8GFyha1cx2EeAEraxNODgRVcyeRo+F1ok1tg5Mg7iUpOWSkknQTHuFhwA=="],
|
||||
|
||||
"minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="],
|
||||
|
||||
@@ -873,9 +873,9 @@
|
||||
|
||||
"modern-tar": ["modern-tar@0.7.6", "", {}, "sha512-sweCIVXzx1aIGTCdzcMlSZt1h8k5Tmk08VNAuRk3IU28XamGiOH5ypi11g6De2CH7PhYqSSnGy2A/EFhbWnVKg=="],
|
||||
|
||||
"motion": ["motion@12.40.0", "", { "dependencies": { "framer-motion": "^12.40.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-yjrHUrBFW6kQvjJwRsoiPSAhC5tRwRqNGJWmiJ4CrGnbKp0V88AdzkhBmDoqIsIPfarOe0Uddd37Xq43/gIocA=="],
|
||||
"motion": ["motion@12.42.0", "", { "dependencies": { "framer-motion": "^12.42.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-Qhwvu9sVl5/URSq5CNzwMCpSKK8Uhnrwb6VO977kZyj/wOCS7mWebJUnBoHx5cZU1Zv8a9BD5CSICWKAlrLJgA=="],
|
||||
|
||||
"motion-dom": ["motion-dom@12.40.0", "", { "dependencies": { "motion-utils": "^12.39.0" } }, "sha512-HxU3ZaBwNPVQUBQf1xxgq+7JrPNZvjLVxgbpEZL7RrWJnsxOf0/OM+yrHG9ogLQ31Do/r57Oz2gQWPK+6q62mg=="],
|
||||
"motion-dom": ["motion-dom@12.42.0", "", { "dependencies": { "motion-utils": "^12.39.0" } }, "sha512-M63h4n8R+quJdNhBwuLlgxM+OLYa9+I/T2pzDRboB9fLXRdbou+Gw7Zury+SkpaCyACP1JHSjHgZ1EgTkBr30w=="],
|
||||
|
||||
"motion-utils": ["motion-utils@12.39.0", "", {}, "sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ=="],
|
||||
|
||||
@@ -953,9 +953,9 @@
|
||||
|
||||
"pkce-challenge": ["pkce-challenge@5.0.1", "", {}, "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ=="],
|
||||
|
||||
"playwright": ["playwright@1.61.0", "", { "dependencies": { "playwright-core": "1.61.0" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-Z+7BeeqQPRRzklHsVFP4KTGIyMxKUmfeRA4WisM6G3/XW6nwGeX6fX9qYaDa+CiUqpOkb2f6X3nar05R3kSuJQ=="],
|
||||
"playwright": ["playwright@1.61.1", "", { "dependencies": { "playwright-core": "1.61.1" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ=="],
|
||||
|
||||
"playwright-core": ["playwright-core@1.61.0", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-caX7TrY3Ml6egyDX0WUcTHDxodl/b51y5wJOdCEA36QviK/s2g081hvmGs8eaE3DWb6NYZQ6BjO/QkNRPenoPA=="],
|
||||
"playwright-core": ["playwright-core@1.61.1", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg=="],
|
||||
|
||||
"postcss": ["postcss@8.5.15", "", { "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A=="],
|
||||
|
||||
@@ -973,9 +973,9 @@
|
||||
|
||||
"proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
|
||||
|
||||
"puppeteer": ["puppeteer@25.2.0", "", { "dependencies": { "@puppeteer/browsers": "3.0.5", "chromium-bidi": "16.0.1", "devtools-protocol": "0.0.1638949", "lilconfig": "^3.1.3", "puppeteer-core": "25.2.0", "typed-query-selector": "^2.12.2" }, "bin": { "puppeteer": "lib/puppeteer/node/cli.js" } }, "sha512-JPMPd/2+lgdkLhEyPqH895oR3ccMt1wSra6oewgjjTuLmo2s9zPZpKXQTFEIiA/fMKpiL01kjU3+2zPEReRWNg=="],
|
||||
"puppeteer": ["puppeteer@25.2.1", "", { "dependencies": { "@puppeteer/browsers": "3.0.5", "chromium-bidi": "16.0.1", "devtools-protocol": "0.0.1638949", "lilconfig": "^3.1.3", "puppeteer-core": "25.2.1", "typed-query-selector": "^2.12.2" }, "bin": { "puppeteer": "lib/puppeteer/node/cli.js" } }, "sha512-2D5RMkQH9FRhDU57a1/jV9xWoxqZvUjaZOYjAAPdRCEY8A01V5sxzyGOMs8XiKU9fPF91SOSwNYpHRu5SD958g=="],
|
||||
|
||||
"puppeteer-core": ["puppeteer-core@25.2.0", "", { "dependencies": { "@puppeteer/browsers": "3.0.5", "chromium-bidi": "16.0.1", "devtools-protocol": "0.0.1638949", "typed-query-selector": "^2.12.2", "webdriver-bidi-protocol": "0.4.2", "ws": "^8.21.0" } }, "sha512-jGhuGAlkgOcbyGRc0Cm9b/y4vvqoxhyAyl6a1diVe8F3sHsgTaQ60QQT5F3rGegTZV3prysgHVc+0LsvPZo3GA=="],
|
||||
"puppeteer-core": ["puppeteer-core@25.2.1", "", { "dependencies": { "@puppeteer/browsers": "3.0.5", "chromium-bidi": "16.0.1", "devtools-protocol": "0.0.1638949", "typed-query-selector": "^2.12.2", "webdriver-bidi-protocol": "0.4.2", "ws": "^8.21.0" } }, "sha512-MwEZ4FFGJ1ZLOmu/04eISxoEMKtCnHyJBRFfgpwPPSYNG6gT6Xw1laNziFSV7uwDcx3jK+ATYIo9SfOd8Uhc3w=="],
|
||||
|
||||
"qs": ["qs@6.15.1", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg=="],
|
||||
|
||||
@@ -1163,9 +1163,9 @@
|
||||
|
||||
"which-pm-runs": ["which-pm-runs@1.1.0", "", {}, "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA=="],
|
||||
|
||||
"workerd": ["workerd@1.20260617.1", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20260617.1", "@cloudflare/workerd-darwin-arm64": "1.20260617.1", "@cloudflare/workerd-linux-64": "1.20260617.1", "@cloudflare/workerd-linux-arm64": "1.20260617.1", "@cloudflare/workerd-windows-64": "1.20260617.1" }, "bin": { "workerd": "bin/workerd" } }, "sha512-Re5pl6pdowt3ZmWUzGlOuB7jbRIIPetgKalmo4cYmucQnVhpo7/3e4MfpekbhLi2EhZZz5EY9NWRu8zFzuEZew=="],
|
||||
"workerd": ["workerd@1.20260625.1", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20260625.1", "@cloudflare/workerd-darwin-arm64": "1.20260625.1", "@cloudflare/workerd-linux-64": "1.20260625.1", "@cloudflare/workerd-linux-arm64": "1.20260625.1", "@cloudflare/workerd-windows-64": "1.20260625.1" }, "bin": { "workerd": "bin/workerd" } }, "sha512-GApQvFX52SDM6L4u0+RRnUDB1wJOnEwoXjinkmOPtIyofWBxrlZckdegJSYc1leg++lLZ3+DQ4zMVmBqYVtzfA=="],
|
||||
|
||||
"wrangler": ["wrangler@4.103.0", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.5.0", "@cloudflare/unenv-preset": "2.16.1", "blake3-wasm": "2.1.5", "esbuild": "0.28.1", "miniflare": "4.20260617.1", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", "workerd": "1.20260617.1" }, "optionalDependencies": { "fsevents": "2.3.3" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20260617.1" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "cf-wrangler": "bin/cf-wrangler.js", "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-3Lv1P5t2xcSEkSTKtG+Lz+3JFryuU7YPLkaCUj7gNe+CJsjZJLtUwqsh1x595QBxkIbCE0GAvDx2DCJUU4+oqw=="],
|
||||
"wrangler": ["wrangler@4.105.0", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.5.0", "@cloudflare/unenv-preset": "2.16.1", "blake3-wasm": "2.1.5", "esbuild": "0.28.1", "miniflare": "4.20260625.0", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", "workerd": "1.20260625.1" }, "optionalDependencies": { "fsevents": "2.3.3" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20260625.1" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "cf-wrangler": "bin/cf-wrangler.js", "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-7dXFH6OLj1Fv0y6ZeRPUxFTkp+duWD7/xxVi/1c0vfOeEYwIFKWB7cdqnY05DvY1Ta3BnqAwRkXfLs8PDj538g=="],
|
||||
|
||||
"wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="],
|
||||
|
||||
|
||||
+5
-5
@@ -89,14 +89,14 @@
|
||||
"puppeteer": "^25.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ai-sdk/anthropic": "^3.0.71",
|
||||
"@ai-sdk/google": "^3.0.75",
|
||||
"@ai-sdk/openai": "^3.0.53",
|
||||
"@ai-sdk/anthropic": "^4.0.7",
|
||||
"@ai-sdk/google": "^4.0.8",
|
||||
"@ai-sdk/openai": "^4.0.7",
|
||||
"@anthropic-ai/claude-agent-sdk": "^0.3.165",
|
||||
"@anthropic-ai/sdk": "^0.105.0",
|
||||
"@anthropic-ai/sdk": "^0.107.0",
|
||||
"@google/genai": "^2.8.0",
|
||||
"@paper-design/shaders": "^0.0.76",
|
||||
"ai": "^6.0.168",
|
||||
"ai": "^7.0.14",
|
||||
"archiver": "^8.0.0",
|
||||
"astro": "^7.0.0",
|
||||
"fontkit": "^2.0.4",
|
||||
|
||||
@@ -7928,7 +7928,7 @@ void main() {
|
||||
const barTopFromBottom = barRect && barRect.height > 0
|
||||
? Math.max(16, window.innerHeight - barRect.top + 12)
|
||||
: 16;
|
||||
toastEl = el('div', {
|
||||
const currentToast = el('div', {
|
||||
position: 'fixed', bottom: barTopFromBottom + 'px', left: '50%',
|
||||
transform: 'translateX(-50%) translateY(8px)',
|
||||
background: C.ink, color: C.white,
|
||||
@@ -7938,19 +7938,24 @@ void main() {
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.25s ' + EASE,
|
||||
pointerEvents: 'none', maxWidth: '420px', textAlign: 'center',
|
||||
});
|
||||
toastEl.id = PREFIX + '-toast';
|
||||
toastEl.textContent = message;
|
||||
uiAppend(toastEl);
|
||||
toastEl = currentToast;
|
||||
currentToast.id = PREFIX + '-toast';
|
||||
currentToast.textContent = message;
|
||||
uiAppend(currentToast);
|
||||
requestAnimationFrame(() => {
|
||||
toastEl.style.opacity = '1';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(0)';
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '1';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(0)';
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (toastEl) {
|
||||
toastEl.style.opacity = '0';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => { if (toastEl) { toastEl.remove(); toastEl = null; } }, 250);
|
||||
}
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '0';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => {
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.remove();
|
||||
toastEl = null;
|
||||
}, 250);
|
||||
}, duration);
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ const resolvedOgDescription = ogDescription || description;
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Albert+Sans:wght@300;400;500;600;700&family=Alumni+Sans:wght@400;500;600;700&family=Alumni+Sans+Pinstripe&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Albert+Sans:wght@300;400;500;600;700&family=Alumni+Sans:wght@100;300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<slot name="head" />
|
||||
</head>
|
||||
<body class={bodyClass}>
|
||||
|
||||
@@ -256,7 +256,7 @@ const mockupCandidates = listCandidates('mockups');
|
||||
.logo-dir-name {
|
||||
margin: 0 0 8px;
|
||||
font-family: var(--ks-font-display);
|
||||
font-weight: 600;
|
||||
font-weight: var(--ks-type-headline-weight);
|
||||
font-size: 1.4rem;
|
||||
color: var(--ks-champagne);
|
||||
}
|
||||
|
||||
@@ -309,7 +309,7 @@ const FIXTURES = [
|
||||
.hero{position:relative;width:100%;height:100%;min-height:340px;overflow:hidden;display:grid;align-items:center}
|
||||
.hero-art{position:absolute;inset:0;z-index:0;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)}
|
||||
.hero-inner{position:relative;z-index:1;padding:34px;display:grid;gap:18px;max-width:520px}
|
||||
.hero-title{margin:0;color:oklch(84% 0.035 82);font-family:"Alumni Sans Pinstripe","Albert Sans",Arial,sans-serif;font-weight:300;font-size:2.9rem;line-height:1.02;letter-spacing:-0.01em}
|
||||
.hero-title{margin:0;color:oklch(84% 0.035 82);font-family:"Alumni Sans","Albert Sans",Arial,sans-serif;font-weight:100;font-size:2.9rem;line-height:1.02;letter-spacing:-0.01em}
|
||||
.hero-copy{margin:0;color:oklch(81% 0.03 82);font-size:0.92rem;line-height:1.55;font-weight:300;max-width:40ch}
|
||||
.hero-cta{display:flex;gap:12px;flex-wrap:wrap;margin-top:2px}
|
||||
.hero-cta a{min-height:46px;display:inline-flex;align-items:center;gap:10px;padding:0 22px;border-radius:2px;font-size:0.9rem;font-weight:500;border:1px solid transparent;text-decoration:none}
|
||||
|
||||
@@ -180,7 +180,7 @@
|
||||
display: block;
|
||||
color: var(--ks-kinpaku);
|
||||
font-family: var(--ks-font-display);
|
||||
font-weight: 300;
|
||||
font-weight: 100;
|
||||
font-size: clamp(3.2rem, 7.2vw, 5.6rem);
|
||||
line-height: 1;
|
||||
letter-spacing: 0.22em;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
Overrides sub-pages.css + docs-visuals.css for the long-form "Designing
|
||||
with Impeccable" walkthrough. The existing markup is unchanged; this file
|
||||
restyles every block to the kinpaku brand: dark lacquer surface, gold +
|
||||
verdigris accents, Alumni Sans Pinstripe display, Albert Sans body.
|
||||
verdigris accents, Alumni Sans display, Albert Sans body.
|
||||
|
||||
Structure of this file mirrors the page itself:
|
||||
1. Page scope + base
|
||||
@@ -198,7 +198,7 @@
|
||||
text-wrap: balance;
|
||||
max-width: none;
|
||||
/* "Impeccable" at the display token's 3.4rem minimum is 270px+ in the
|
||||
narrow Pinstripe face and overflows a 360px viewport. Allow break-word
|
||||
narrow Alumni Sans face and overflows a 360px viewport. Allow break-word
|
||||
as a safety net so the title never blows out of its container. */
|
||||
word-break: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
@@ -287,8 +287,8 @@
|
||||
|
||||
.designing-kinpaku .designing-loop-name {
|
||||
color: var(--ks-champagne);
|
||||
/* Pinstripe is single-weight and reads broken at ~1.5–2rem; wordmark
|
||||
carries real stroke weight at compass-label scale (cf. iterate-name). */
|
||||
/* The thin display cut reads too light at compass-label scale (~1.5–2rem);
|
||||
the wordmark token is the same face at weight 400+ (cf. iterate-name). */
|
||||
font-family: var(--ks-font-wordmark);
|
||||
font-weight: 600;
|
||||
font-size: clamp(1.5rem, 2.2vw, 2rem);
|
||||
@@ -806,9 +806,9 @@
|
||||
color: var(--ks-kinpaku);
|
||||
}
|
||||
|
||||
/* Subsection h3s use Albert Sans, not the Pinstripe display face. DESIGN.md
|
||||
/* Subsection h3s use Albert Sans, not the Alumni Sans display face. DESIGN.md
|
||||
reserves the display face for the hero h1 and section h2s; at h3 sizes the
|
||||
thin Pinstripe loses its identity and reads as a broken render. */
|
||||
thin display cut loses presence and reads too light. */
|
||||
.designing-kinpaku .designing-iterate-name {
|
||||
color: var(--ks-champagne);
|
||||
font-family: var(--ks-font);
|
||||
@@ -1427,8 +1427,8 @@
|
||||
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. */
|
||||
/* The brand mock title used the Alumni Sans display face at ~1.6rem, where the
|
||||
thin cut reads too light 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;
|
||||
@@ -1612,7 +1612,7 @@
|
||||
.designing-kinpaku .designing-cta-card-title {
|
||||
color: var(--ks-champagne);
|
||||
font-family: var(--ks-font-display);
|
||||
font-weight: 300;
|
||||
font-weight: 100;
|
||||
font-size: clamp(1.8rem, 3vw, 2.4rem);
|
||||
line-height: 1.1;
|
||||
margin: 0;
|
||||
|
||||
@@ -632,7 +632,7 @@ html.light .docs-kinpaku {
|
||||
.docs-kinpaku .docs-live-target-title {
|
||||
font-family: var(--ks-font-display);
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-weight: var(--ks-type-headline-weight);
|
||||
font-size: 1.4rem;
|
||||
line-height: 1.15;
|
||||
color: var(--ks-champagne);
|
||||
@@ -1200,7 +1200,7 @@ html.light .docs-kinpaku {
|
||||
}
|
||||
|
||||
/* h2/h3 follow the DESIGN.md type scale exactly:
|
||||
- h2 (Headline): Alumni Sans Pinstripe, clamp 2.6-3.4rem, weight 600
|
||||
- h2 (Headline): Alumni Sans, clamp 2.6-3.4rem, weight 600
|
||||
- h3 (Title): Albert Sans, 1.18rem, weight 500
|
||||
- h4: Albert Sans, 1rem, weight 600 (utility)
|
||||
*/
|
||||
|
||||
@@ -200,7 +200,7 @@
|
||||
|
||||
.home-kinpaku .section-title {
|
||||
font-family: var(--ks-font-display);
|
||||
font-weight: 600;
|
||||
font-weight: var(--ks-type-headline-weight);
|
||||
font-size: clamp(2.6rem, 4vw, 3.4rem);
|
||||
line-height: 1.04;
|
||||
color: var(--ks-champagne);
|
||||
@@ -1020,7 +1020,7 @@
|
||||
color: var(--ks-kinpaku);
|
||||
font-family: var(--ks-font-display);
|
||||
font-size: 4.2rem;
|
||||
font-weight: 300;
|
||||
font-weight: 100;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
margin: 0;
|
||||
color: var(--ks-champagne);
|
||||
font-family: var(--ks-font-display);
|
||||
font-weight: 300;
|
||||
font-weight: 100;
|
||||
font-size: clamp(3.4rem, 6.5vw, 5.6rem);
|
||||
line-height: 1.02;
|
||||
letter-spacing: -0.01em;
|
||||
@@ -265,7 +265,7 @@
|
||||
forced the grid track wider than the viewport. Drop it on mobile. */
|
||||
.hero-rebuild-container { padding-left: 0; padding-right: 0; }
|
||||
/* Title keeps its design-system clamp (floors at 3.4rem ≈ 54px here): the
|
||||
Pinstripe display face is condensed, so "interfaces" stays well within a
|
||||
Alumni Sans display face is narrow, so "interfaces" stays well within a
|
||||
320px+ viewport. No mobile shrink — at 54px against 16.8px body it holds a
|
||||
~3.2× hero hierarchy; shrinking it made the heading read smaller than body. */
|
||||
.hero-rebuild-actions { flex-direction: column; align-items: stretch; }
|
||||
@@ -305,7 +305,7 @@
|
||||
margin: 0;
|
||||
color: var(--ks-champagne);
|
||||
font-family: var(--ks-font-display);
|
||||
font-weight: 600;
|
||||
font-weight: var(--ks-type-headline-weight);
|
||||
font-size: clamp(2.6rem, 4vw, 3.4rem);
|
||||
line-height: 1.04;
|
||||
letter-spacing: -0.005em;
|
||||
@@ -649,7 +649,7 @@
|
||||
margin: 0;
|
||||
color: var(--card-fg-strong);
|
||||
font-family: var(--ks-font-display);
|
||||
font-weight: 600;
|
||||
font-weight: var(--ks-type-headline-weight);
|
||||
font-size: clamp(2.6rem, 4vw, 3.4rem);
|
||||
line-height: 1.04;
|
||||
}
|
||||
@@ -2017,7 +2017,7 @@ svg.downloads-rebuild-tab-logo {
|
||||
.live-how-title {
|
||||
margin: 0;
|
||||
font-family: var(--ks-font-display);
|
||||
font-weight: 600;
|
||||
font-weight: var(--ks-type-headline-weight);
|
||||
font-size: 1.18rem;
|
||||
color: var(--ks-champagne);
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
color: var(--ks-champagne);
|
||||
font-family: var(--ks-font-display);
|
||||
font-size: clamp(2.2rem, 3.6vw, 3rem);
|
||||
font-weight: 600;
|
||||
font-weight: var(--ks-type-headline-weight);
|
||||
line-height: 1.06;
|
||||
letter-spacing: -0.005em;
|
||||
}
|
||||
@@ -1007,7 +1007,7 @@
|
||||
}
|
||||
|
||||
/* The legacy display face was italic serif; the kinpaku display face
|
||||
(Alumni Sans Pinstripe) reads wrong synthesized-italic, so reset it on
|
||||
(Alumni Sans) renders wrong as synthesized italic, so reset it on
|
||||
the headings the base stylesheet set to italic. */
|
||||
.kinpaku-surface .sub-page-title,
|
||||
.kinpaku-surface .prose h1,
|
||||
|
||||
@@ -82,20 +82,19 @@
|
||||
--ks-code-cmd: var(--ks-kinpaku); /* code that's a command link */
|
||||
|
||||
/* ============================================================
|
||||
Typography — three faces.
|
||||
- --ks-font-display: Alumni Sans Pinstripe. Pinstripe horizontal
|
||||
strikes feel futuristic and editorial at display size; used for
|
||||
the hero h1 and section h2s. Single-weight — font-weight is inert.
|
||||
- --ks-font-wordmark: solid Alumni Sans, the weightable sibling of
|
||||
the pinstripe. Same letterforms, but carries real weight in the
|
||||
brand lockup where the hairline pinstripe reads too thin.
|
||||
Typography — two faces.
|
||||
- --ks-font-display: Alumni Sans. A weightable humanist grotesque;
|
||||
the hero h1 runs at a thin hairline (100) for elegance, section
|
||||
h2s at a heavier cut (300) to anchor each block.
|
||||
- --ks-font-wordmark: Alumni Sans, same face as display, held at
|
||||
weight 400 for the brand lockup.
|
||||
- --ks-font: Albert Sans. Quiet geometric humanist, used for body
|
||||
and UI text. Pairs cleanly with the pinstripe display without
|
||||
and UI text. Pairs cleanly with the Alumni Sans display without
|
||||
competing.
|
||||
All loaded via Base.astro's Google Fonts link.
|
||||
============================================================ */
|
||||
--ks-font-display: "Alumni Sans Pinstripe", "Albert Sans", Arial, sans-serif;
|
||||
--ks-font-wordmark: "Alumni Sans", "Alumni Sans Pinstripe", "Albert Sans", Arial, sans-serif;
|
||||
--ks-font-display: "Alumni Sans", "Albert Sans", Arial, sans-serif;
|
||||
--ks-font-wordmark: "Alumni Sans", "Albert Sans", Arial, sans-serif;
|
||||
--ks-font: "Albert Sans", "Avenir Next", "Helvetica Neue", Arial, system-ui, sans-serif;
|
||||
--ks-mono: "SFMono-Regular", "Roboto Mono", "JetBrains Mono", Consolas, monospace;
|
||||
|
||||
@@ -103,19 +102,19 @@
|
||||
Type scale. These are the actual sizes the homepage ships with —
|
||||
new pages should read them via var(...) rather than hand-typing.
|
||||
The display vs headline weight split is deliberate: the hero h1
|
||||
reads thin (300) for elegance; section h2s read heavier (600) to
|
||||
reads thin (100) for elegance; section h2s read heavier (300) to
|
||||
anchor each block. Section h2s look heavier than the h1 on purpose.
|
||||
============================================================ */
|
||||
|
||||
/* Display — hero h1. */
|
||||
--ks-type-display-size: clamp(3.4rem, 6.5vw, 5.6rem);
|
||||
--ks-type-display-weight: 300;
|
||||
--ks-type-display-weight: 100;
|
||||
--ks-type-display-line: 1.02;
|
||||
--ks-type-display-track: -0.01em;
|
||||
|
||||
/* Headline — section h2. Heavier than display. */
|
||||
--ks-type-headline-size: clamp(2.6rem, 4vw, 3.4rem);
|
||||
--ks-type-headline-weight: 600;
|
||||
--ks-type-headline-weight: 300;
|
||||
--ks-type-headline-line: 1.04;
|
||||
|
||||
/* Title — card and panel headings (h3). */
|
||||
|
||||
@@ -338,7 +338,7 @@
|
||||
.live-mode-kinpaku .live-demo-card--v1 h3 {
|
||||
font-family: var(--ks-font-display);
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-weight: var(--ks-type-headline-weight);
|
||||
color: var(--ks-champagne);
|
||||
}
|
||||
|
||||
@@ -548,8 +548,8 @@
|
||||
background: var(--ks-lacquer-raised);
|
||||
border: 1.5px solid var(--ks-kinpaku);
|
||||
color: var(--ks-champagne);
|
||||
/* Pinstripe display font loses legibility below ~1.2rem (Two-Face Rule).
|
||||
The mock renders at 12px, so force the body face here. */
|
||||
/* The thin Alumni Sans display cut loses legibility below ~1.2rem (Two-Face
|
||||
Rule). The mock renders at 12px, so force the body face here. */
|
||||
font-family: var(--ks-font);
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
|
||||
@@ -7928,7 +7928,7 @@ void main() {
|
||||
const barTopFromBottom = barRect && barRect.height > 0
|
||||
? Math.max(16, window.innerHeight - barRect.top + 12)
|
||||
: 16;
|
||||
toastEl = el('div', {
|
||||
const currentToast = el('div', {
|
||||
position: 'fixed', bottom: barTopFromBottom + 'px', left: '50%',
|
||||
transform: 'translateX(-50%) translateY(8px)',
|
||||
background: C.ink, color: C.white,
|
||||
@@ -7938,19 +7938,24 @@ void main() {
|
||||
transition: 'opacity 0.25s ' + EASE + ', transform 0.25s ' + EASE,
|
||||
pointerEvents: 'none', maxWidth: '420px', textAlign: 'center',
|
||||
});
|
||||
toastEl.id = PREFIX + '-toast';
|
||||
toastEl.textContent = message;
|
||||
uiAppend(toastEl);
|
||||
toastEl = currentToast;
|
||||
currentToast.id = PREFIX + '-toast';
|
||||
currentToast.textContent = message;
|
||||
uiAppend(currentToast);
|
||||
requestAnimationFrame(() => {
|
||||
toastEl.style.opacity = '1';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(0)';
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '1';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(0)';
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (toastEl) {
|
||||
toastEl.style.opacity = '0';
|
||||
toastEl.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => { if (toastEl) { toastEl.remove(); toastEl = null; } }, 250);
|
||||
}
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.style.opacity = '0';
|
||||
currentToast.style.transform = 'translateX(-50%) translateY(8px)';
|
||||
setTimeout(() => {
|
||||
if (toastEl !== currentToast) return;
|
||||
currentToast.remove();
|
||||
toastEl = null;
|
||||
}, 250);
|
||||
}, duration);
|
||||
}
|
||||
|
||||
|
||||
@@ -528,6 +528,34 @@ describe('live-browser.js regression guards', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('toast enter and dismiss timers only touch the current toast element', () => {
|
||||
assert.match(
|
||||
SOURCE,
|
||||
/function showToast\(message, duration\)[\s\S]{0,1200}?const currentToast = el\('div'/,
|
||||
'showToast must capture the created toast in a local so delayed callbacks cannot dereference or remove a stale global toastEl',
|
||||
);
|
||||
assert.match(
|
||||
SOURCE,
|
||||
/requestAnimationFrame\(\(\) => \{[\s\S]{0,80}?if \(toastEl !== currentToast\) return;[\s\S]{0,120}?currentToast\.style\.opacity = '1';/,
|
||||
'toast enter rAF must no-op when dismissToast or a newer toast replaced toastEl before the frame fires',
|
||||
);
|
||||
assert.match(
|
||||
SOURCE,
|
||||
/setTimeout\(\(\) => \{[\s\S]{0,80}?if \(toastEl !== currentToast\) return;[\s\S]{0,120}?currentToast\.style\.opacity = '0';/,
|
||||
'toast auto-dismiss timer must not animate a newer toast created after this timer was scheduled',
|
||||
);
|
||||
assert.match(
|
||||
SOURCE,
|
||||
/setTimeout\(\(\) => \{[\s\S]{0,80}?if \(toastEl !== currentToast\) return;[\s\S]{0,80}?currentToast\.remove\(\);[\s\S]{0,80}?toastEl = null;/,
|
||||
'toast removal timer must only remove and clear the same toast it scheduled',
|
||||
);
|
||||
assert.doesNotMatch(
|
||||
SOURCE,
|
||||
/requestAnimationFrame\(\(\) => \{\s*toastEl\.style/,
|
||||
'toast enter rAF must not read toastEl.style directly after dismissToast can null it',
|
||||
);
|
||||
});
|
||||
|
||||
it('insert mode UI and generate payload guards', () => {
|
||||
assert.match(SOURCE, /function toggleInsert\(\)/, 'global bar must expose insert toggle');
|
||||
assert.match(SOURCE, /PREFIX \+ '-insert-toggle'/, 'insert toggle needs stable id');
|
||||
|
||||
@@ -249,7 +249,7 @@ export function makeTools(workspace, extraEnv = {}) {
|
||||
* Run one scenario turn against a model.
|
||||
*
|
||||
* `priorMessages` lets multi-turn scenarios chain context from a previous
|
||||
* call (append `result.response.messages` between turns).
|
||||
* call (append the SDK's response messages between turns).
|
||||
*/
|
||||
export async function runTurn({ workspace, model, userPrompt, priorMessages = [], maxSteps = 8, env = {} }) {
|
||||
const { tools, trace } = makeTools(workspace, env);
|
||||
@@ -269,7 +269,8 @@ export async function runTurn({ workspace, model, userPrompt, priorMessages = []
|
||||
} catch (err) {
|
||||
return { trace, error: String(err), text: '', responseMessages: messages, finishReason: 'error' };
|
||||
}
|
||||
const responseMessages = [...messages, ...(result.response?.messages ?? [])];
|
||||
const generatedResponseMessages = result.responseMessages ?? result.response?.messages ?? [];
|
||||
const responseMessages = [...messages, ...generatedResponseMessages];
|
||||
return {
|
||||
trace,
|
||||
text: result.text ?? '',
|
||||
|
||||
Reference in New Issue
Block a user