mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-19 09:36:59 +03:00
Board-stage read artboards get thicker bar weight in picker.css; the gallery replica adds matching experiments plus desktop caption circles for Portfolio restrained/committed/drenched and drenched color roles on cell 21. AI-assisted commit. Co-authored-by: Cursor <cursoragent@cursor.com>
350 lines
14 KiB
JavaScript
350 lines
14 KiB
JavaScript
/* Build an untouched replica of previews-gallery.html, then apply experiments
|
||
to selected strategy iframes. The source gallery stays baseline. */
|
||
|
||
import { readFile, writeFile } from 'node:fs/promises';
|
||
import { fileURLToPath } from 'node:url';
|
||
import path from 'node:path';
|
||
|
||
const HERE = path.dirname(fileURLToPath(import.meta.url));
|
||
const SOURCE = path.join(HERE, 'previews-gallery.html');
|
||
const OUTPUT = path.join(HERE, 'previews-gallery-improved.html');
|
||
|
||
const OPS_PREVIEW =
|
||
'#picker-form .picker-strategy-stage > .picker-preview.picker-preview--ops';
|
||
|
||
const DOCS_PREVIEW =
|
||
'#picker-form .picker-strategy-stage > .picker-preview.picker-preview--docs';
|
||
|
||
const DOCS_SCOPE =
|
||
'html[data-cell-screen="03"][data-cell-surface="read"]';
|
||
|
||
const DOCS_WEIGHT_CSS = [
|
||
`${DOCS_SCOPE} ${DOCS_PREVIEW} {`,
|
||
' --pv-text: 1.65 !important;',
|
||
'}',
|
||
`${DOCS_SCOPE} ${DOCS_PREVIEW} .pd-item i {`,
|
||
' width: calc(4.07 * var(--pv-x)) !important;',
|
||
'}',
|
||
`${DOCS_SCOPE} ${DOCS_PREVIEW} .pd-item span {`,
|
||
' height: calc(1.53 * var(--pv-text) * var(--pv-x)) !important;',
|
||
'}',
|
||
`${DOCS_SCOPE} ${DOCS_PREVIEW} .pd-para i {`,
|
||
' height: calc(1.35 * var(--pv-text) * var(--pv-x)) !important;',
|
||
'}',
|
||
`${DOCS_SCOPE} ${DOCS_PREVIEW} .pd-note-dot {`,
|
||
' width: calc(4.07 * var(--pv-x)) !important;',
|
||
'}',
|
||
`${DOCS_SCOPE} ${DOCS_PREVIEW} .pd-note-lines i {`,
|
||
' height: calc(1 * var(--pv-text) * var(--pv-x)) !important;',
|
||
'}',
|
||
`${DOCS_SCOPE} ${DOCS_PREVIEW} .pd-phone-body .pd-para i {`,
|
||
' height: calc(1.37 * var(--pv-text) * var(--pv-x)) !important;',
|
||
'}',
|
||
`${DOCS_SCOPE} ${DOCS_PREVIEW} .pd-phone-body .pd-note-lines i {`,
|
||
' height: calc(0.83 * var(--pv-text) * var(--pv-x)) !important;',
|
||
'}',
|
||
`${DOCS_SCOPE} ${DOCS_PREVIEW} .pd-phone-body .pd-heading {`,
|
||
' height: calc(2.53 * var(--pv-text) * var(--pv-x)) !important;',
|
||
'}',
|
||
`${DOCS_SCOPE} ${DOCS_PREVIEW} .pd-phone-body .pd-note-dot {`,
|
||
' width: calc(2.64 * var(--pv-text) * var(--pv-x)) !important;',
|
||
'}',
|
||
].join('\n');
|
||
|
||
const DOCS_CARRY_SCOPE =
|
||
'html[data-cell-surface="read"]:is([data-cell-screen="08"], [data-cell-screen="09"], [data-cell-screen="10"])';
|
||
|
||
const DOCS_CARRY_ROOT = '[data-carry][data-surface="read"]';
|
||
|
||
const DOCS_CARRY_WEIGHT_CSS = [
|
||
`${DOCS_CARRY_SCOPE} ${DOCS_CARRY_ROOT} {`,
|
||
' --pvs-carry-weight: 1.65 !important;',
|
||
'}',
|
||
`${DOCS_CARRY_SCOPE} ${DOCS_CARRY_ROOT} .ps-docs-item > i {`,
|
||
' width: calc(var(--pt-base) * 0.34 * var(--pvs-carry-weight)) !important;',
|
||
'}',
|
||
`${DOCS_CARRY_SCOPE} ${DOCS_CARRY_ROOT} :is(`,
|
||
' .ps-docs-item b,',
|
||
' .ps-docs-crumb,',
|
||
' .ps-docs-note-copy b',
|
||
') {',
|
||
' height: calc(var(--pt-base) * 0.26 * var(--pvs-carry-weight)) !important;',
|
||
'}',
|
||
`${DOCS_CARRY_SCOPE} ${DOCS_CARRY_ROOT} :is(`,
|
||
' .ps-docs-main .pt-headline i,',
|
||
' .ps-phone-body .pt-headline i',
|
||
') {',
|
||
' height: calc(var(--pt-base) * 0.72 * var(--pvs-carry-weight)) !important;',
|
||
'}',
|
||
`${DOCS_CARRY_SCOPE} ${DOCS_CARRY_ROOT} .ps-docs-sub {`,
|
||
' height: calc(var(--pt-base) * 0.5 * var(--pvs-carry-weight)) !important;',
|
||
'}',
|
||
`${DOCS_CARRY_SCOPE} ${DOCS_CARRY_ROOT} :is(`,
|
||
' .ps-docs-lede i,',
|
||
' .ps-docs-para i,',
|
||
' .ps-docs-list li',
|
||
') {',
|
||
' height: calc(var(--pt-base) * 0.3 * var(--pvs-carry-weight)) !important;',
|
||
'}',
|
||
`${DOCS_CARRY_SCOPE} ${DOCS_CARRY_ROOT} .ps-docs-note-copy > span i {`,
|
||
' height: calc(var(--pt-base) * 0.26 * var(--pvs-carry-weight)) !important;',
|
||
'}',
|
||
`${DOCS_CARRY_SCOPE} ${DOCS_CARRY_ROOT} .ps-docs-list li::before {`,
|
||
' width: calc(var(--pt-base) * 0.3 * var(--pvs-carry-weight)) !important;',
|
||
'}',
|
||
].join('\n');
|
||
|
||
const DOCS_BOARD_CELLS = [
|
||
'boundaries--read--open-space',
|
||
'boundaries--read--thin-dividers',
|
||
'boundaries--read--surface-changes',
|
||
'corners--read--sharp',
|
||
'corners--read--slightly-soft',
|
||
'corners--read--friendly',
|
||
'corners--read--pill',
|
||
'depth--read--flat',
|
||
'depth--read--soft-lift',
|
||
];
|
||
|
||
const GALLERY_PREVIEW =
|
||
'#picker-form .picker-strategy-stage > .picker-preview.picker-preview--gallery';
|
||
|
||
function portfolioCapAvatarsCss(option, circle = 'neutral') {
|
||
const scope =
|
||
'html[data-cell-screen="03"][data-cell-surface="experience"][data-cell-option="' + option + '"]';
|
||
const capCircle =
|
||
circle === 'drenched'
|
||
? [
|
||
' border: 1px solid color-mix(in oklab, var(--pkc-p-ink) 40%, var(--pkc-primary));',
|
||
' background: linear-gradient(',
|
||
' 135deg,',
|
||
' color-mix(in oklab, var(--pkc-p-ink) 16%, var(--pkc-primary)),',
|
||
' color-mix(in oklab, var(--pkc-p-ink) 28%, var(--pkc-primary))',
|
||
' );',
|
||
].join('\n')
|
||
: circle === 'committed'
|
||
? [
|
||
' border: 1px solid color-mix(in oklab, var(--pkc-primary) 42%, var(--pkc-neutral));',
|
||
' background: linear-gradient(',
|
||
' 135deg,',
|
||
' color-mix(in oklab, var(--pkc-primary) 16%, var(--pkc-neutral)),',
|
||
' color-mix(in oklab, var(--pkc-primary) 30%, var(--pkc-neutral))',
|
||
' );',
|
||
].join('\n')
|
||
: [
|
||
' border: 1px solid color-mix(in oklab, var(--pv-secondary) 55%, var(--pv-neutral));',
|
||
' background: linear-gradient(',
|
||
' 135deg,',
|
||
' color-mix(in oklab, var(--pv-secondary) 24%, var(--pv-neutral)),',
|
||
' color-mix(in oklab, var(--pv-secondary) 46%, var(--pv-neutral))',
|
||
' );',
|
||
].join('\n');
|
||
|
||
return [
|
||
`${scope} ${GALLERY_PREVIEW} .pv-desktop .pg-cap {`,
|
||
' padding-top: 5.2cqh !important;',
|
||
' gap: 2.6cqh !important;',
|
||
'}',
|
||
`${scope} ${GALLERY_PREVIEW} .pv-desktop .pg-cap::before {`,
|
||
' content: "";',
|
||
' display: block;',
|
||
' width: calc(11.5 * var(--pv-x));',
|
||
' aspect-ratio: 1;',
|
||
' border-radius: 50%;',
|
||
capCircle,
|
||
'}',
|
||
].join('\n');
|
||
}
|
||
|
||
const PORTFOLIO_DRENCHED_COLOR_CSS = [
|
||
'html[data-cell-screen="03"][data-cell-surface="experience"][data-cell-option="drenched"]',
|
||
`${GALLERY_PREVIEW} {`,
|
||
' --pv-secondary: var(--pkc-secondary) !important;',
|
||
' --pv-tertiary: var(--pkc-tertiary) !important;',
|
||
' --pv-bone: color-mix(in oklab, var(--pkc-p-ink) 55%, var(--pkc-primary)) !important;',
|
||
' --pv-strong: var(--pkc-p-ink) !important;',
|
||
' --pv-secondary-wash: color-mix(in oklab, var(--pkc-p-ink) 16%, var(--pkc-primary)) !important;',
|
||
'}',
|
||
'html[data-cell-screen="03"][data-cell-surface="experience"][data-cell-option="drenched"]',
|
||
`${GALLERY_PREVIEW} .pv-image {`,
|
||
' background: linear-gradient(',
|
||
' 135deg,',
|
||
' color-mix(in oklab, var(--pkc-p-ink) 16%, var(--pkc-primary)),',
|
||
' color-mix(in oklab, var(--pkc-p-ink) 28%, var(--pkc-primary))',
|
||
' ) !important;',
|
||
' border-color: color-mix(in oklab, var(--pkc-p-ink) 40%, var(--pkc-primary)) !important;',
|
||
'}',
|
||
'html[data-cell-screen="03"][data-cell-surface="experience"][data-cell-option="drenched"]',
|
||
`${GALLERY_PREVIEW} .pv-image::after {`,
|
||
' background: var(--pkc-tertiary) !important;',
|
||
'}',
|
||
].join('\n');
|
||
|
||
/** @type {{ id: string, cells: string[], css: string }[]} */
|
||
const EXPERIMENTS = [
|
||
{
|
||
id: 'landing-drenched-color-roles',
|
||
cells: ['strategy--persuade--drenched'],
|
||
css: [
|
||
'html[data-cell-screen="03"][data-cell-surface="persuade"][data-cell-option="drenched"]',
|
||
'#picker-form .picker-strategy-stage > .picker-preview[data-surface="persuade"] {',
|
||
' --pv-secondary: var(--pkc-secondary) !important;',
|
||
' --pv-tertiary: var(--pkc-tertiary) !important;',
|
||
' --pv-bone: color-mix(in oklab, var(--pkc-p-ink) 55%, var(--pkc-primary)) !important;',
|
||
' --pv-strong: var(--pkc-p-ink) !important;',
|
||
' --pv-secondary-wash: color-mix(in oklab, var(--pkc-p-ink) 16%, var(--pkc-primary)) !important;',
|
||
'}',
|
||
'html[data-cell-screen="03"][data-cell-surface="persuade"][data-cell-option="drenched"]',
|
||
'#picker-form .picker-strategy-stage > .picker-preview[data-surface="persuade"] .pv-image {',
|
||
' background: linear-gradient(',
|
||
' 135deg,',
|
||
' color-mix(in oklab, var(--pkc-p-ink) 16%, var(--pkc-primary)),',
|
||
' color-mix(in oklab, var(--pkc-p-ink) 28%, var(--pkc-primary))',
|
||
' ) !important;',
|
||
' border-color: color-mix(in oklab, var(--pkc-p-ink) 40%, var(--pkc-primary)) !important;',
|
||
'}',
|
||
'html[data-cell-screen="03"][data-cell-surface="persuade"][data-cell-option="drenched"]',
|
||
'#picker-form .picker-strategy-stage > .picker-preview[data-surface="persuade"] .pv-actions i:last-child {',
|
||
' border-color: color-mix(in oklab, var(--pkc-p-ink) 45%, var(--pkc-primary)) !important;',
|
||
' background: color-mix(in oklab, var(--pkc-p-ink) 12%, var(--pkc-primary)) !important;',
|
||
'}',
|
||
].join('\n'),
|
||
},
|
||
{
|
||
id: 'ops-committed-color-visibility',
|
||
cells: ['strategy--operate--committed'],
|
||
css: [
|
||
'html[data-cell-screen="03"][data-cell-surface="operate"][data-cell-option="committed"]',
|
||
`${OPS_PREVIEW} {`,
|
||
' --pv-neutral: color-mix(in oklab, var(--pkc-neutral) 84%, var(--pkc-primary)) !important;',
|
||
' --po-wash: color-mix(in oklab, var(--pkc-primary) 24%, var(--pkc-neutral)) !important;',
|
||
'}',
|
||
].join('\n'),
|
||
},
|
||
{
|
||
id: 'ops-full-palette-color-roles',
|
||
cells: ['strategy--operate--full-palette'],
|
||
css: [
|
||
'html[data-cell-screen="03"][data-cell-surface="operate"][data-cell-option="full-palette"]',
|
||
`${OPS_PREVIEW} {`,
|
||
' --po-wash: color-mix(in oklab, var(--pkc-secondary) 22%, var(--pkc-neutral)) !important;',
|
||
'}',
|
||
'html[data-cell-screen="03"][data-cell-surface="operate"][data-cell-option="full-palette"]',
|
||
`${OPS_PREVIEW} .po-row--on .po-dot {`,
|
||
' background: var(--pkc-tertiary) !important;',
|
||
'}',
|
||
'html[data-cell-screen="03"][data-cell-surface="operate"][data-cell-option="full-palette"]',
|
||
`${OPS_PREVIEW} .po-field {`,
|
||
' border-color: var(--pkc-secondary) !important;',
|
||
'}',
|
||
'html[data-cell-screen="03"][data-cell-surface="operate"][data-cell-option="full-palette"]',
|
||
`${OPS_PREVIEW} .po-chart i:nth-child(2) {`,
|
||
' background: color-mix(in oklab, var(--pkc-secondary) 78%, var(--pkc-neutral)) !important;',
|
||
'}',
|
||
'html[data-cell-screen="03"][data-cell-surface="operate"][data-cell-option="full-palette"]',
|
||
`${OPS_PREVIEW} .po-chart i:nth-child(3) {`,
|
||
' background: color-mix(in oklab, var(--pkc-tertiary) 68%, var(--pkc-neutral)) !important;',
|
||
'}',
|
||
].join('\n'),
|
||
},
|
||
{
|
||
id: 'docs-strategy-wireframe-weight',
|
||
cells: [
|
||
'strategy--read--restrained',
|
||
'strategy--read--committed',
|
||
'strategy--read--full-palette',
|
||
],
|
||
css: DOCS_WEIGHT_CSS,
|
||
},
|
||
{
|
||
id: 'docs-board-carry-weight',
|
||
cells: DOCS_BOARD_CELLS,
|
||
css: DOCS_CARRY_WEIGHT_CSS,
|
||
},
|
||
{
|
||
id: 'portfolio-restrained-cap-avatars',
|
||
cells: ['strategy--experience--restrained'],
|
||
css: portfolioCapAvatarsCss('restrained', 'neutral'),
|
||
},
|
||
{
|
||
id: 'portfolio-committed-cap-avatars',
|
||
cells: ['strategy--experience--committed'],
|
||
css: portfolioCapAvatarsCss('committed', 'committed'),
|
||
},
|
||
{
|
||
id: 'portfolio-drenched-gallery',
|
||
cells: ['strategy--experience--drenched'],
|
||
css: PORTFOLIO_DRENCHED_COLOR_CSS + '\n' + portfolioCapAvatarsCss('drenched', 'drenched'),
|
||
},
|
||
];
|
||
|
||
const experiment = String.raw`
|
||
<script data-gallery-replica-experiment="strategy-fixes">
|
||
(function () {
|
||
var specs = ${JSON.stringify(EXPERIMENTS.map(({ id, cells, css }) => ({ id, cells, css })))};
|
||
|
||
specs.forEach(function (spec) {
|
||
spec.cells.forEach(function (cellId) {
|
||
var frame = document.querySelector('iframe[data-cell="' + cellId + '"]');
|
||
if (!frame) return;
|
||
|
||
function apply() {
|
||
var doc = frame.contentDocument;
|
||
if (!doc || !doc.head) return;
|
||
|
||
var style = doc.querySelector('[data-experiment="' + spec.id + '"]');
|
||
if (!style) {
|
||
style = doc.createElement('style');
|
||
style.setAttribute('data-experiment', spec.id);
|
||
style.textContent = spec.css;
|
||
doc.head.appendChild(style);
|
||
}
|
||
}
|
||
|
||
frame.addEventListener('load', apply);
|
||
apply();
|
||
});
|
||
});
|
||
})();
|
||
</script>`;
|
||
|
||
const html = await readFile(SOURCE, 'utf8');
|
||
if (html.includes('data-gallery-replica-experiment')) {
|
||
throw new Error('Source gallery already contains the replica experiment');
|
||
}
|
||
if (!html.includes('</body>')) {
|
||
throw new Error('Source gallery has no closing body tag');
|
||
}
|
||
|
||
for (const { cells } of EXPERIMENTS) {
|
||
for (const cell of cells) {
|
||
if (!html.includes('data-cell="' + cell + '"')) {
|
||
throw new Error('Target cell not found: ' + cell);
|
||
}
|
||
}
|
||
}
|
||
|
||
let replica = html.replace('</body>', experiment + '\n</body>');
|
||
replica = replica.replace(
|
||
'<title>Questionnaire previews, ground-truth gallery</title>',
|
||
'<title>Questionnaire previews (improved experiment)</title>',
|
||
);
|
||
replica = replica.replace(
|
||
'<h1>Questionnaire previews</h1>',
|
||
'<h1>Questionnaire previews (improved experiment)</h1>',
|
||
);
|
||
replica = replica.replace(
|
||
/<p class="note">Ground-truth extraction[\s\S]*?<\/p>/,
|
||
'<p class="note">Replica of the ground-truth gallery with experiments on '
|
||
+ '<strong>12 Drenched</strong>, '
|
||
+ '<strong>14–15 App UI</strong> color roles, '
|
||
+ '<strong>16–18 Docs</strong> strategy wireframe weight, and '
|
||
+ '<strong>45–47 / 59–62 / 71–72 Docs</strong> board bar weight, and '
|
||
+ '<strong>19–21 Portfolio</strong> caption circles (desktop), '
|
||
+ '<strong>21</strong> drenched color roles. '
|
||
+ 'Baseline: <a href="previews-gallery.html">previews-gallery.html</a>.</p>',
|
||
);
|
||
|
||
await writeFile(OUTPUT, replica);
|
||
console.log('wrote previews-gallery-improved.html (' + (replica.length / 1024 / 1024).toFixed(1) + ' MB)');
|