@commonpub/layer 0.68.1 → 0.69.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -29,6 +29,8 @@ import {
|
|
|
29
29
|
SHADOW_PRESETS,
|
|
30
30
|
RATIOS,
|
|
31
31
|
FONTS,
|
|
32
|
+
DESIGN_ARCHETYPES,
|
|
33
|
+
type DesignArchetype,
|
|
32
34
|
defaultRecipe,
|
|
33
35
|
type HarmonyScheme,
|
|
34
36
|
} from '@commonpub/theme-studio';
|
|
@@ -75,6 +77,44 @@ const SCHEMES: { val: HarmonyScheme; label: string }[] = [
|
|
|
75
77
|
{ val: 'monochrome', label: 'Mono' },
|
|
76
78
|
];
|
|
77
79
|
|
|
80
|
+
// --- Design-ethos archetype (Phase 3) ----------------------------------
|
|
81
|
+
// Applies a whole structural preset (shape/shadow/border/type/density/texture)
|
|
82
|
+
// while preserving the user's chosen color + mode, then tags the recipe.
|
|
83
|
+
function applyArchetype(a: DesignArchetype): void {
|
|
84
|
+
recipe.value = { ...recipe.value, ...a.patch, archetype: a.k };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// --- Neutral temperature (Phase 2) -------------------------------------
|
|
88
|
+
// Decouples surfaces/text from the accent hue. "Auto" = accent-tinted.
|
|
89
|
+
type NeutralMode = 'auto' | 'pure' | 'warm' | 'cool';
|
|
90
|
+
const NEUTRALS: { k: NeutralMode; label: string }[] = [
|
|
91
|
+
{ k: 'auto', label: 'Auto' },
|
|
92
|
+
{ k: 'pure', label: 'Pure' },
|
|
93
|
+
{ k: 'warm', label: 'Warm' },
|
|
94
|
+
{ k: 'cool', label: 'Cool' },
|
|
95
|
+
];
|
|
96
|
+
const neutralMode = computed<NeutralMode>(() => {
|
|
97
|
+
if (recipe.value.neutralHue === undefined && recipe.value.neutralSat === undefined) return 'auto';
|
|
98
|
+
if ((recipe.value.neutralSat ?? 0) === 0) return 'pure';
|
|
99
|
+
const h = recipe.value.neutralHue ?? 0;
|
|
100
|
+
return h < 120 || h >= 300 ? 'warm' : 'cool';
|
|
101
|
+
});
|
|
102
|
+
function setNeutral(m: NeutralMode): void {
|
|
103
|
+
if (m === 'auto') {
|
|
104
|
+
recipe.value.neutralHue = undefined;
|
|
105
|
+
recipe.value.neutralSat = undefined;
|
|
106
|
+
} else if (m === 'pure') {
|
|
107
|
+
recipe.value.neutralHue = 0;
|
|
108
|
+
recipe.value.neutralSat = 0;
|
|
109
|
+
} else if (m === 'warm') {
|
|
110
|
+
recipe.value.neutralHue = 30;
|
|
111
|
+
recipe.value.neutralSat = 8;
|
|
112
|
+
} else {
|
|
113
|
+
recipe.value.neutralHue = 220;
|
|
114
|
+
recipe.value.neutralSat = 8;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
78
118
|
// --- Emit on every change ---------------------------------------------
|
|
79
119
|
|
|
80
120
|
function emitGenerate(): void {
|
|
@@ -232,6 +272,24 @@ function finishWith(apply: boolean): void {
|
|
|
232
272
|
<div class="cpub-studio-body">
|
|
233
273
|
<!-- STEP 1: COLOR -->
|
|
234
274
|
<div v-if="step === 0">
|
|
275
|
+
<div class="cpub-studio-arch">
|
|
276
|
+
<span class="cpub-studio-sublbl">Style <span class="cpub-studio-hint">sets shape, shadow, type & feel</span></span>
|
|
277
|
+
<div class="cpub-studio-archgrid">
|
|
278
|
+
<button
|
|
279
|
+
v-for="a in DESIGN_ARCHETYPES"
|
|
280
|
+
:key="a.k"
|
|
281
|
+
type="button"
|
|
282
|
+
class="cpub-studio-archcard"
|
|
283
|
+
:class="{ on: recipe.archetype === a.k }"
|
|
284
|
+
:title="a.sub"
|
|
285
|
+
@click="applyArchetype(a)"
|
|
286
|
+
>
|
|
287
|
+
<span class="cpub-studio-archname">{{ a.label }}</span>
|
|
288
|
+
<span class="cpub-studio-archsub">{{ a.sub }}</span>
|
|
289
|
+
</button>
|
|
290
|
+
</div>
|
|
291
|
+
</div>
|
|
292
|
+
|
|
235
293
|
<div class="cpub-studio-tabs">
|
|
236
294
|
<button type="button" :class="{ on: colorTab === 'vibe' }" @click="colorTab = 'vibe'">By vibe</button>
|
|
237
295
|
<button type="button" :class="{ on: colorTab === 'custom' }" @click="colorTab = 'custom'">My colors</button>
|
|
@@ -296,6 +354,12 @@ function finishWith(apply: boolean): void {
|
|
|
296
354
|
<button v-for="sc in SCHEMES" :key="sc.val" type="button" :class="{ on: recipe.scheme === sc.val }" @click="recipe.scheme = sc.val">{{ sc.label }}</button>
|
|
297
355
|
</span>
|
|
298
356
|
</label>
|
|
357
|
+
<label class="cpub-studio-field">
|
|
358
|
+
<span class="cpub-studio-lbl">Neutral <span class="cpub-studio-hint">surface tint</span></span>
|
|
359
|
+
<span class="cpub-studio-seg">
|
|
360
|
+
<button v-for="n in NEUTRALS" :key="n.k" type="button" :class="{ on: neutralMode === n.k }" @click="setNeutral(n.k)">{{ n.label }}</button>
|
|
361
|
+
</span>
|
|
362
|
+
</label>
|
|
299
363
|
<div class="cpub-studio-field">
|
|
300
364
|
<span class="cpub-studio-lbl">Suggested family</span>
|
|
301
365
|
<span class="cpub-studio-family">
|
|
@@ -502,6 +566,14 @@ function finishWith(apply: boolean): void {
|
|
|
502
566
|
.cpub-studio-dots { display: flex; gap: 3px; }
|
|
503
567
|
.cpub-studio-dots span { flex: 1; height: 14px; }
|
|
504
568
|
|
|
569
|
+
.cpub-studio-arch { margin-bottom: var(--space-3); }
|
|
570
|
+
.cpub-studio-archgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 6px; }
|
|
571
|
+
.cpub-studio-archcard { display: flex; flex-direction: column; gap: 2px; background: var(--surface2); border: var(--border-width-thin) solid var(--border2); padding: var(--space-2); cursor: pointer; text-align: left; }
|
|
572
|
+
.cpub-studio-archcard:hover { border-color: var(--text-faint); }
|
|
573
|
+
.cpub-studio-archcard.on { border-color: var(--accent); background: var(--accent-bg); }
|
|
574
|
+
.cpub-studio-archname { font-family: var(--font-mono); font-size: var(--text-label); font-weight: var(--font-weight-bold); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--text); }
|
|
575
|
+
.cpub-studio-archsub { font-size: var(--text-label); color: var(--text-faint); line-height: var(--leading-tight); }
|
|
576
|
+
|
|
505
577
|
.cpub-studio-sublbl { font-family: var(--font-mono); font-size: var(--text-label); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--text-faint); margin: var(--space-4) 0 var(--space-2); }
|
|
506
578
|
.cpub-studio-pallist, .cpub-studio-setlist { display: flex; flex-direction: column; gap: 6px; }
|
|
507
579
|
.cpub-studio-palchip { display: flex; align-items: center; gap: var(--space-2); background: var(--surface2); border: var(--border-width-thin) solid var(--border2); padding: 6px 8px; cursor: pointer; }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@commonpub/layer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.69.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./nuxt.config.ts",
|
|
6
6
|
"files": [
|
|
@@ -56,14 +56,14 @@
|
|
|
56
56
|
"@commonpub/auth": "0.8.0",
|
|
57
57
|
"@commonpub/config": "0.20.0",
|
|
58
58
|
"@commonpub/docs": "0.6.3",
|
|
59
|
-
"@commonpub/
|
|
59
|
+
"@commonpub/protocol": "0.13.0",
|
|
60
60
|
"@commonpub/explainer": "0.7.15",
|
|
61
|
-
"@commonpub/
|
|
61
|
+
"@commonpub/learning": "0.5.2",
|
|
62
|
+
"@commonpub/schema": "0.38.0",
|
|
62
63
|
"@commonpub/server": "2.83.0",
|
|
63
|
-
"@commonpub/
|
|
64
|
-
"@commonpub/
|
|
65
|
-
"@commonpub/
|
|
66
|
-
"@commonpub/protocol": "0.13.0"
|
|
64
|
+
"@commonpub/ui": "0.12.1",
|
|
65
|
+
"@commonpub/editor": "0.7.11",
|
|
66
|
+
"@commonpub/theme-studio": "0.4.0"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
69
|
"@testing-library/jest-dom": "^6.9.1",
|
package/theme/base.css
CHANGED
|
@@ -300,9 +300,35 @@ body {
|
|
|
300
300
|
*::before,
|
|
301
301
|
*::after {
|
|
302
302
|
box-sizing: border-box;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/* Surface radius. Real UI surfaces (buttons, cards, inputs, tags, panels)
|
|
306
|
+
* inherit the theme's --radius. Structural, media, and decorative elements are
|
|
307
|
+
* reset to 0 below so a rounded theme (e.g. Stoa, --radius:12px) does NOT put
|
|
308
|
+
* radii on line breaks, dividers, rules, icons, images, table cells, or
|
|
309
|
+
* pseudo-element decorations — the "line breaks carry rounded corners" bug.
|
|
310
|
+
* (Elements that genuinely want rounding set it explicitly, e.g. avatars use
|
|
311
|
+
* --radius-full; an explicit class-level border-radius outranks these resets.) */
|
|
312
|
+
* {
|
|
303
313
|
border-radius: var(--radius);
|
|
304
314
|
}
|
|
305
315
|
|
|
316
|
+
hr,
|
|
317
|
+
svg,
|
|
318
|
+
img,
|
|
319
|
+
picture,
|
|
320
|
+
video,
|
|
321
|
+
canvas,
|
|
322
|
+
iframe,
|
|
323
|
+
table, thead, tbody, tfoot, tr, td, th, caption, col, colgroup,
|
|
324
|
+
::before,
|
|
325
|
+
::after,
|
|
326
|
+
::marker,
|
|
327
|
+
::placeholder,
|
|
328
|
+
.cpub-divider {
|
|
329
|
+
border-radius: 0;
|
|
330
|
+
}
|
|
331
|
+
|
|
306
332
|
/* === ACCESSIBILITY === */
|
|
307
333
|
|
|
308
334
|
/* Skip-to-content link */
|