Improve strategy previews for Docs wireframe weight and App UI color roles.

Boost docs strategy-stage line and dot weight to match App UI legibility, keep phone artboard lines proportional via pv-text scaling, and extend the gallery replica experiments for cells 14–18.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Abdul Wahab
2026-09-01 10:02:40 +05:00
co-authored by Cursor
parent 470b655096
commit 457c2d877c
3 changed files with 149 additions and 52 deletions
+48 -1
View File
@@ -3105,10 +3105,57 @@ body.picker-page {
any heavier stops being display type and becomes a slab. The nav is left out
for the same kind of reason: it is the chrome all four cards share, and a
visitor moving between tabs should not watch it change weight. */
.picker-strategy-stage > .picker-preview:is(.picker-preview--ops, .picker-preview--docs, .picker-preview--gallery) .pv-desktop {
.picker-strategy-stage > .picker-preview:is(.picker-preview--ops, .picker-preview--gallery) .pv-desktop {
--pv-text: 1.35;
}
/* Docs wireframe counts run lighter than ops; the shared 1.35 step still reads
as hairlines beside the app UI on the same screen. Match ops legibility on
the stage for both desktop and phone. */
.picker-strategy-stage > .picker-preview.picker-preview--docs {
--pv-text: 1.65;
}
.picker-strategy-stage > .picker-preview.picker-preview--docs .pd-item i {
width: calc(4.07 * var(--pv-x));
}
.picker-strategy-stage > .picker-preview.picker-preview--docs .pd-item span {
height: calc(1.53 * var(--pv-text) * var(--pv-x));
}
.picker-strategy-stage > .picker-preview.picker-preview--docs .pd-para i {
height: calc(1.35 * var(--pv-text) * var(--pv-x));
}
.picker-strategy-stage > .picker-preview.picker-preview--docs .pd-note-dot {
width: calc(4.07 * var(--pv-x));
}
.picker-strategy-stage > .picker-preview.picker-preview--docs .pd-note-lines i {
height: calc(1 * var(--pv-text) * var(--pv-x));
}
/* Phone body lines keep the authored pv-x counts; only desktop needed the extra
step because strategy stage boosts --pv-text on the preview root while the
phone overrides below still bypass it. Restate phone lines with the same
pv-text mix as desktop so the two artboards stay in proportion. */
.picker-strategy-stage > .picker-preview.picker-preview--docs .pd-phone-body .pd-para i {
height: calc(1.37 * var(--pv-text) * var(--pv-x));
}
.picker-strategy-stage > .picker-preview.picker-preview--docs .pd-phone-body .pd-note-lines i {
height: calc(0.83 * var(--pv-text) * var(--pv-x));
}
.picker-strategy-stage > .picker-preview.picker-preview--docs .pd-phone-body .pd-heading {
height: calc(2.53 * var(--pv-text) * var(--pv-x));
}
.picker-strategy-stage > .picker-preview.picker-preview--docs .pd-phone-body .pd-note-dot {
width: calc(2.64 * var(--pv-text) * var(--pv-x));
}
/* One drawing is shown and the rest stay mounted, so switching costs an
attribute rather than a rebuild. [hidden] is a display: none that the
component's own display: grid outranks, so it is restated here. */
+82 -34
View File
@@ -1,5 +1,5 @@
/* Build an untouched replica of previews-gallery.html, then apply color-only
experiments to selected strategy iframes. The source gallery stays baseline. */
/* 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';
@@ -12,11 +12,50 @@ const OUTPUT = path.join(HERE, 'previews-gallery-improved.html');
const OPS_PREVIEW =
'#picker-form .picker-strategy-stage > .picker-preview.picker-preview--ops';
/** @type {{ id: string, cell: string, css: string }[]} */
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');
/** @type {{ id: string, cells: string[], css: string }[]} */
const EXPERIMENTS = [
{
id: 'landing-drenched-color-roles',
cell: 'strategy--persuade--drenched',
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"] {',
@@ -44,12 +83,10 @@ const EXPERIMENTS = [
},
{
id: 'ops-committed-color-visibility',
cell: 'strategy--operate--committed',
cells: ['strategy--operate--committed'],
css: [
'html[data-cell-screen="03"][data-cell-surface="operate"][data-cell-option="committed"]',
`${OPS_PREVIEW} {`,
' /* Committed: primary owns the paper and the selection wash, not a 5% trace.',
' Structure stays neutral like Restrained so accents still pop. */',
' --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;',
'}',
@@ -57,11 +94,10 @@ const EXPERIMENTS = [
},
{
id: 'ops-full-palette-color-roles',
cell: 'strategy--operate--full-palette',
cells: ['strategy--operate--full-palette'],
css: [
'html[data-cell-screen="03"][data-cell-surface="operate"][data-cell-option="full-palette"]',
`${OPS_PREVIEW} {`,
' /* Full palette wireframe never assigns secondary; spread all four roles. */',
' --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"]',
@@ -82,32 +118,43 @@ const EXPERIMENTS = [
'}',
].join('\n'),
},
{
id: 'docs-strategy-wireframe-weight',
cells: [
'strategy--read--restrained',
'strategy--read--committed',
'strategy--read--full-palette',
],
css: DOCS_WEIGHT_CSS,
},
];
const experiment = String.raw`
<script data-gallery-replica-experiment="strategy-color-fixes">
<script data-gallery-replica-experiment="strategy-fixes">
(function () {
var specs = ${JSON.stringify(EXPERIMENTS.map(({ id, cell, css }) => ({ id, cell, css })))};
var specs = ${JSON.stringify(EXPERIMENTS.map(({ id, cells, css }) => ({ id, cells, css })))};
specs.forEach(function (spec) {
var frame = document.querySelector('iframe[data-cell="' + spec.cell + '"]');
if (!frame) return;
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;
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);
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();
frame.addEventListener('load', apply);
apply();
});
});
})();
</script>`;
@@ -120,9 +167,11 @@ if (!html.includes('</body>')) {
throw new Error('Source gallery has no closing body tag');
}
for (const { cell } of EXPERIMENTS) {
if (!html.includes('data-cell="' + cell + '"')) {
throw new Error('Target cell not found: ' + cell);
for (const { cells } of EXPERIMENTS) {
for (const cell of cells) {
if (!html.includes('data-cell="' + cell + '"')) {
throw new Error('Target cell not found: ' + cell);
}
}
}
@@ -137,12 +186,11 @@ replica = replica.replace(
);
replica = replica.replace(
/<p class="note">Ground-truth extraction[\s\S]*?<\/p>/,
'<p class="note">Replica of the ground-truth gallery with color-only experiments on '
+ '<strong>Landing page + Drenched</strong>, '
+ '<strong>App UI + Committed</strong>, and '
+ '<strong>App UI + Full palette</strong>. '
+ 'Baseline: <a href="previews-gallery.html">previews-gallery.html</a>. '
+ 'Restrained is unchanged (reference).</p>',
'<p class="note">Replica of the ground-truth gallery with experiments on '
+ '<strong>12 Drenched</strong>, '
+ '<strong>1415 App UI</strong> color roles, and '
+ '<strong>1618 Docs</strong> wireframe weight. '
+ 'Baseline: <a href="previews-gallery.html">previews-gallery.html</a>.</p>',
);
await writeFile(OUTPUT, replica);
File diff suppressed because one or more lines are too long