@loworbitstudio/visor-theme-engine 0.16.0 → 0.17.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.
- package/dist/adapters/index.d.ts +1 -1
- package/dist/index.d.ts +165 -4
- package/dist/index.js +193 -9
- package/dist/{types-BstIS9rL.d.ts → types-DqsWwFVZ.d.ts} +61 -4
- package/package.json +1 -1
- package/src/visor-theme.schema.json +78 -2
package/dist/adapters/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { k as GeneratedPrimitives, r as SemanticTokens, R as ResolvedThemeConfig } from '../types-
|
|
1
|
+
import { k as GeneratedPrimitives, r as SemanticTokens, R as ResolvedThemeConfig } from '../types-DqsWwFVZ.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Adapter types for the Visor theme engine.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as FontResolveOptions, a as FontResolution, V as VisorTypography, b as FontDisplayStrategy, T as ThemeFontResult, G as GoogleFontEntry, c as VisorBrand, B as BrandSlot, d as BrandSource, e as BrandResolution, f as ThemeBrandResult, g as BrandStrategy, h as BrandStrategyContext, i as BrandStrategyIssue, j as BrandStrategyValidationResult, S as SerializedBrandStrategy, R as ResolvedThemeConfig, k as GeneratedPrimitives, l as ThemeOutput, m as ThemeData, n as VisorThemeConfig, o as FullShadeScale, C as ColorRole, p as SelectiveShadeScale, q as RGB, P as ParsedColor, O as OKLCH, r as SemanticTokens, s as ShadeStep } from './types-
|
|
2
|
-
export { t as BRAND_VARIANTS, u as BRAND_VISIBILITIES, v as
|
|
1
|
+
import { F as FontResolveOptions, a as FontResolution, V as VisorTypography, b as FontDisplayStrategy, T as ThemeFontResult, G as GoogleFontEntry, c as VisorBrand, B as BrandSlot, d as BrandSource, e as BrandResolution, f as ThemeBrandResult, g as BrandStrategy, h as BrandStrategyContext, i as BrandStrategyIssue, j as BrandStrategyValidationResult, S as SerializedBrandStrategy, R as ResolvedThemeConfig, k as GeneratedPrimitives, l as ThemeOutput, m as ThemeData, n as VisorThemeConfig, o as FullShadeScale, C as ColorRole, p as SelectiveShadeScale, q as RGB, P as ParsedColor, O as OKLCH, r as SemanticTokens, s as ShadeStep } from './types-DqsWwFVZ.js';
|
|
2
|
+
export { t as BRAND_VARIANTS, u as BRAND_VISIBILITIES, v as BrandAccessibility, w as BrandArchetype, x as BrandBoilerplate, y as BrandColorPairing, z as BrandColorUsage, A as BrandContrastTarget, D as BrandGoverns, E as BrandLexiconEntry, H as BrandMessaging, I as BrandPersonalityTrait, J as BrandPillar, K as BrandPositioning, L as BrandStrategyIssueSeverity, M as BrandToneEntry, N as BrandVariant, Q as BrandVisibility, U as BrandVoice, W as BrandVoiceTrait, X as ColorFormat, Y as DEFAULT_BRAND_STRATEGY_SURFACES, Z as DEFAULT_BRAND_STRATEGY_TONE_STATES, _ as FontSource, $ as GOVERNS_WILDCARD, a0 as RGBA, a1 as SemanticTokenValue } from './types-DqsWwFVZ.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Font resolver — maps font family names to loadable font resources.
|
|
@@ -291,8 +291,11 @@ declare function validateBrandStrategy(block: unknown, ctx?: BrandStrategyContex
|
|
|
291
291
|
/**
|
|
292
292
|
* Serialize a validated brand strategy for the manifest. Returns `null` when
|
|
293
293
|
* `visibility: private`. Optional fields (`archetype.secondary`,
|
|
294
|
-
* `voice.traits[].example`, absent `governs` lists
|
|
295
|
-
*
|
|
294
|
+
* `voice.traits[].example`, absent `governs` lists, the Phase 2 wave-1 fields
|
|
295
|
+
* `pillars[].proof` / `messaging` / `taglines` / `boilerplate` / `colorUsage` /
|
|
296
|
+
* `accessibility`) are emitted only when present, so the agent reads a clean,
|
|
297
|
+
* predictable object. The Phase 2 fields are all PUBLIC — a private record
|
|
298
|
+
* never reaches this point, so visibility is enforced once, up top (D4).
|
|
296
299
|
*/
|
|
297
300
|
declare function serializeBrandStrategy(strategy: BrandStrategy): SerializedBrandStrategy | null;
|
|
298
301
|
|
|
@@ -856,6 +859,27 @@ var properties = {
|
|
|
856
859
|
"private"
|
|
857
860
|
],
|
|
858
861
|
description: "Client brands are private and are omitted from the public agent manifest."
|
|
862
|
+
},
|
|
863
|
+
messaging: {
|
|
864
|
+
$ref: "#/$defs/brandMessaging"
|
|
865
|
+
},
|
|
866
|
+
taglines: {
|
|
867
|
+
type: "array",
|
|
868
|
+
items: {
|
|
869
|
+
type: "string",
|
|
870
|
+
minLength: 1
|
|
871
|
+
},
|
|
872
|
+
minItems: 1,
|
|
873
|
+
description: "Phase 2 wave-1 (VI-541). Permanent, brand-level signature line(s) — who the brand is, not what it sells this quarter."
|
|
874
|
+
},
|
|
875
|
+
boilerplate: {
|
|
876
|
+
$ref: "#/$defs/brandBoilerplate"
|
|
877
|
+
},
|
|
878
|
+
colorUsage: {
|
|
879
|
+
$ref: "#/$defs/brandColorUsage"
|
|
880
|
+
},
|
|
881
|
+
accessibility: {
|
|
882
|
+
$ref: "#/$defs/brandAccessibility"
|
|
859
883
|
}
|
|
860
884
|
}
|
|
861
885
|
},
|
|
@@ -1208,6 +1232,15 @@ var $defs = {
|
|
|
1208
1232
|
},
|
|
1209
1233
|
governs: {
|
|
1210
1234
|
$ref: "#/$defs/brandGoverns"
|
|
1235
|
+
},
|
|
1236
|
+
proof: {
|
|
1237
|
+
type: "array",
|
|
1238
|
+
items: {
|
|
1239
|
+
type: "string",
|
|
1240
|
+
minLength: 1
|
|
1241
|
+
},
|
|
1242
|
+
minItems: 1,
|
|
1243
|
+
description: "Phase 2 wave-1 (VI-541). Reasons-to-believe — checkable evidence backing this pillar's claim (the message-house foundation)."
|
|
1211
1244
|
}
|
|
1212
1245
|
}
|
|
1213
1246
|
},
|
|
@@ -1298,6 +1331,134 @@ var $defs = {
|
|
|
1298
1331
|
minLength: 1
|
|
1299
1332
|
}
|
|
1300
1333
|
}
|
|
1334
|
+
},
|
|
1335
|
+
brandMessaging: {
|
|
1336
|
+
type: "object",
|
|
1337
|
+
description: "Phase 2 wave-1 (VI-541). Message-house roof — the single umbrella message above the pillars.",
|
|
1338
|
+
additionalProperties: false,
|
|
1339
|
+
required: [
|
|
1340
|
+
"roof"
|
|
1341
|
+
],
|
|
1342
|
+
properties: {
|
|
1343
|
+
roof: {
|
|
1344
|
+
type: "string",
|
|
1345
|
+
minLength: 1,
|
|
1346
|
+
description: "One overarching statement the pillars support."
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
},
|
|
1350
|
+
brandBoilerplate: {
|
|
1351
|
+
type: "object",
|
|
1352
|
+
description: "Phase 2 wave-1 (VI-541). Reusable \"about us\" copy — short and long forms.",
|
|
1353
|
+
additionalProperties: false,
|
|
1354
|
+
required: [
|
|
1355
|
+
"short",
|
|
1356
|
+
"long"
|
|
1357
|
+
],
|
|
1358
|
+
properties: {
|
|
1359
|
+
short: {
|
|
1360
|
+
type: "string",
|
|
1361
|
+
minLength: 1
|
|
1362
|
+
},
|
|
1363
|
+
long: {
|
|
1364
|
+
type: "string",
|
|
1365
|
+
minLength: 1
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
},
|
|
1369
|
+
brandColorPairing: {
|
|
1370
|
+
type: "object",
|
|
1371
|
+
description: "A color-pairing rule expressed as brand intent (not a computed value).",
|
|
1372
|
+
additionalProperties: false,
|
|
1373
|
+
required: [
|
|
1374
|
+
"use",
|
|
1375
|
+
"with",
|
|
1376
|
+
"rule"
|
|
1377
|
+
],
|
|
1378
|
+
properties: {
|
|
1379
|
+
use: {
|
|
1380
|
+
type: "string",
|
|
1381
|
+
minLength: 1,
|
|
1382
|
+
description: "The token or role being used (e.g. --primary)."
|
|
1383
|
+
},
|
|
1384
|
+
"with": {
|
|
1385
|
+
type: "string",
|
|
1386
|
+
minLength: 1,
|
|
1387
|
+
description: "What it pairs against (token, role, or surface)."
|
|
1388
|
+
},
|
|
1389
|
+
rule: {
|
|
1390
|
+
type: "string",
|
|
1391
|
+
minLength: 1,
|
|
1392
|
+
description: "The intent — when and how the pairing is allowed."
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
},
|
|
1396
|
+
brandColorUsage: {
|
|
1397
|
+
type: "object",
|
|
1398
|
+
description: "Phase 2 wave-1 (VI-541). Color-usage intent — the brand's allowed pairings.",
|
|
1399
|
+
additionalProperties: false,
|
|
1400
|
+
required: [
|
|
1401
|
+
"pairings"
|
|
1402
|
+
],
|
|
1403
|
+
properties: {
|
|
1404
|
+
pairings: {
|
|
1405
|
+
type: "array",
|
|
1406
|
+
items: {
|
|
1407
|
+
$ref: "#/$defs/brandColorPairing"
|
|
1408
|
+
},
|
|
1409
|
+
minItems: 1
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
},
|
|
1413
|
+
brandContrastTarget: {
|
|
1414
|
+
type: "object",
|
|
1415
|
+
description: "A contrast target expressed as brand intent (a WCAG 2.1 AA threshold).",
|
|
1416
|
+
additionalProperties: false,
|
|
1417
|
+
required: [
|
|
1418
|
+
"context",
|
|
1419
|
+
"ratio"
|
|
1420
|
+
],
|
|
1421
|
+
properties: {
|
|
1422
|
+
context: {
|
|
1423
|
+
type: "string",
|
|
1424
|
+
minLength: 1,
|
|
1425
|
+
description: "The text/UI context the target applies to."
|
|
1426
|
+
},
|
|
1427
|
+
ratio: {
|
|
1428
|
+
type: "string",
|
|
1429
|
+
minLength: 1,
|
|
1430
|
+
description: "The minimum contrast ratio (e.g. \"4.5:1\")."
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
},
|
|
1434
|
+
brandAccessibility: {
|
|
1435
|
+
type: "object",
|
|
1436
|
+
description: "Phase 2 wave-1 (VI-541). Accessibility intent — the standard and its contrast targets (authored as intent; live computation is the render surface's concern).",
|
|
1437
|
+
additionalProperties: false,
|
|
1438
|
+
required: [
|
|
1439
|
+
"standard",
|
|
1440
|
+
"contrast",
|
|
1441
|
+
"intent"
|
|
1442
|
+
],
|
|
1443
|
+
properties: {
|
|
1444
|
+
standard: {
|
|
1445
|
+
type: "string",
|
|
1446
|
+
minLength: 1,
|
|
1447
|
+
description: "The conformance standard. Visor targets \"WCAG 2.1 AA\"."
|
|
1448
|
+
},
|
|
1449
|
+
contrast: {
|
|
1450
|
+
type: "array",
|
|
1451
|
+
items: {
|
|
1452
|
+
$ref: "#/$defs/brandContrastTarget"
|
|
1453
|
+
},
|
|
1454
|
+
minItems: 1
|
|
1455
|
+
},
|
|
1456
|
+
intent: {
|
|
1457
|
+
type: "string",
|
|
1458
|
+
minLength: 1,
|
|
1459
|
+
description: "How the brand applies the standard (intent, not computed results)."
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1301
1462
|
}
|
|
1302
1463
|
};
|
|
1303
1464
|
var visorTheme_schema = {
|
package/dist/index.js
CHANGED
|
@@ -248,7 +248,13 @@ var TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
|
248
248
|
"tone",
|
|
249
249
|
"lexicon",
|
|
250
250
|
"core",
|
|
251
|
-
"visibility"
|
|
251
|
+
"visibility",
|
|
252
|
+
// Phase 2 wave-1 (VI-541) — all optional.
|
|
253
|
+
"messaging",
|
|
254
|
+
"taglines",
|
|
255
|
+
"boilerplate",
|
|
256
|
+
"colorUsage",
|
|
257
|
+
"accessibility"
|
|
252
258
|
]);
|
|
253
259
|
var GOVERNS_KEYS = /* @__PURE__ */ new Set(["tokens", "components", "surfaces"]);
|
|
254
260
|
function checkBrandStrategyStructure(block) {
|
|
@@ -347,6 +353,64 @@ function checkBrandStrategyStructure(block) {
|
|
|
347
353
|
if (!isNonEmptyString(block.visibility) || !BRAND_VISIBILITIES.includes(block.visibility)) {
|
|
348
354
|
errors.push(error("BRAND_STRATEGY_VISIBILITY", `'brand-strategy.visibility' is required and must be one of: ${BRAND_VISIBILITIES.join(", ")}`, "brand-strategy.visibility"));
|
|
349
355
|
}
|
|
356
|
+
errors.push(...checkPhase2Structure(block));
|
|
357
|
+
return errors;
|
|
358
|
+
}
|
|
359
|
+
function checkPhase2Structure(block) {
|
|
360
|
+
const errors = [];
|
|
361
|
+
if (block.messaging !== void 0) {
|
|
362
|
+
const messaging = block.messaging;
|
|
363
|
+
if (!isObject(messaging) || !isNonEmptyString(messaging.roof)) {
|
|
364
|
+
errors.push(error("BRAND_STRATEGY_MESSAGING", "'brand-strategy.messaging' must be an object with a non-empty 'roof' string", "brand-strategy.messaging"));
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
if (block.taglines !== void 0) {
|
|
368
|
+
if (!isStringArray(block.taglines) || block.taglines.length === 0) {
|
|
369
|
+
errors.push(error("BRAND_STRATEGY_TAGLINES", "'brand-strategy.taglines' must be a non-empty array of strings when present", "brand-strategy.taglines"));
|
|
370
|
+
} else if (!block.taglines.every(isNonEmptyString)) {
|
|
371
|
+
errors.push(error("BRAND_STRATEGY_TAGLINES", "'brand-strategy.taglines' entries must be non-empty strings", "brand-strategy.taglines"));
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
if (block.boilerplate !== void 0) {
|
|
375
|
+
const boilerplate = block.boilerplate;
|
|
376
|
+
if (!isObject(boilerplate) || !isNonEmptyString(boilerplate.short) || !isNonEmptyString(boilerplate.long)) {
|
|
377
|
+
errors.push(error("BRAND_STRATEGY_BOILERPLATE", "'brand-strategy.boilerplate' must be an object with non-empty 'short' and 'long' strings", "brand-strategy.boilerplate"));
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
if (block.colorUsage !== void 0) {
|
|
381
|
+
const colorUsage = block.colorUsage;
|
|
382
|
+
if (!isObject(colorUsage) || !Array.isArray(colorUsage.pairings) || colorUsage.pairings.length === 0) {
|
|
383
|
+
errors.push(error("BRAND_STRATEGY_COLOR_USAGE", "'brand-strategy.colorUsage' must be an object with a non-empty 'pairings' array", "brand-strategy.colorUsage"));
|
|
384
|
+
} else {
|
|
385
|
+
colorUsage.pairings.forEach((pairing, i) => {
|
|
386
|
+
if (!isObject(pairing) || !isNonEmptyString(pairing.use) || !isNonEmptyString(pairing.with) || !isNonEmptyString(pairing.rule)) {
|
|
387
|
+
errors.push(error("BRAND_STRATEGY_COLOR_USAGE", `'brand-strategy.colorUsage.pairings[${i}]' must have non-empty 'use', 'with', and 'rule' strings`, `brand-strategy.colorUsage.pairings[${i}]`));
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
if (block.accessibility !== void 0) {
|
|
393
|
+
const accessibility = block.accessibility;
|
|
394
|
+
if (!isObject(accessibility)) {
|
|
395
|
+
errors.push(error("BRAND_STRATEGY_ACCESSIBILITY", "'brand-strategy.accessibility' must be an object", "brand-strategy.accessibility"));
|
|
396
|
+
} else {
|
|
397
|
+
if (!isNonEmptyString(accessibility.standard)) {
|
|
398
|
+
errors.push(error("BRAND_STRATEGY_ACCESSIBILITY", "'brand-strategy.accessibility.standard' is required and must be a non-empty string", "brand-strategy.accessibility.standard"));
|
|
399
|
+
}
|
|
400
|
+
if (!isNonEmptyString(accessibility.intent)) {
|
|
401
|
+
errors.push(error("BRAND_STRATEGY_ACCESSIBILITY", "'brand-strategy.accessibility.intent' is required and must be a non-empty string", "brand-strategy.accessibility.intent"));
|
|
402
|
+
}
|
|
403
|
+
if (!Array.isArray(accessibility.contrast) || accessibility.contrast.length === 0) {
|
|
404
|
+
errors.push(error("BRAND_STRATEGY_ACCESSIBILITY", "'brand-strategy.accessibility.contrast' must be a non-empty array", "brand-strategy.accessibility.contrast"));
|
|
405
|
+
} else {
|
|
406
|
+
accessibility.contrast.forEach((target, i) => {
|
|
407
|
+
if (!isObject(target) || !isNonEmptyString(target.context) || !isNonEmptyString(target.ratio)) {
|
|
408
|
+
errors.push(error("BRAND_STRATEGY_ACCESSIBILITY", `'brand-strategy.accessibility.contrast[${i}]' must have non-empty 'context' and 'ratio' strings`, `brand-strategy.accessibility.contrast[${i}]`));
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
350
414
|
return errors;
|
|
351
415
|
}
|
|
352
416
|
function checkPillarStructure(pillar, index) {
|
|
@@ -383,6 +447,13 @@ function checkPillarStructure(pillar, index) {
|
|
|
383
447
|
errors.push(error("BRAND_STRATEGY_GOVERNS", `'${path}.governs' must declare at least one of: ${[...GOVERNS_KEYS].join(", ")}`, `${path}.governs`));
|
|
384
448
|
}
|
|
385
449
|
}
|
|
450
|
+
if (pillar.proof !== void 0) {
|
|
451
|
+
if (!isStringArray(pillar.proof) || pillar.proof.length === 0) {
|
|
452
|
+
errors.push(error("BRAND_STRATEGY_PROOF", `'${path}.proof' must be a non-empty array of strings when present`, `${path}.proof`));
|
|
453
|
+
} else if (!pillar.proof.every(isNonEmptyString)) {
|
|
454
|
+
errors.push(error("BRAND_STRATEGY_PROOF", `'${path}.proof' entries must be non-empty strings`, `${path}.proof`));
|
|
455
|
+
}
|
|
456
|
+
}
|
|
386
457
|
return errors;
|
|
387
458
|
}
|
|
388
459
|
function checkBrandStrategyCoherence(strategy, ctx = {}) {
|
|
@@ -442,6 +513,15 @@ function compactGoverns(governs) {
|
|
|
442
513
|
if (governs.surfaces) out.surfaces = [...governs.surfaces];
|
|
443
514
|
return out;
|
|
444
515
|
}
|
|
516
|
+
function serializePillar(p) {
|
|
517
|
+
const pillar = {
|
|
518
|
+
id: p.id,
|
|
519
|
+
statement: p.statement,
|
|
520
|
+
governs: compactGoverns(p.governs)
|
|
521
|
+
};
|
|
522
|
+
if (p.proof !== void 0) pillar.proof = [...p.proof];
|
|
523
|
+
return pillar;
|
|
524
|
+
}
|
|
445
525
|
function serializeBrandStrategy(strategy) {
|
|
446
526
|
if (strategy.visibility === "private") {
|
|
447
527
|
return null;
|
|
@@ -453,7 +533,7 @@ function serializeBrandStrategy(strategy) {
|
|
|
453
533
|
for (const [state, entry] of Object.entries(strategy.tone)) {
|
|
454
534
|
tone[state] = { feeling: entry.feeling, example: entry.example };
|
|
455
535
|
}
|
|
456
|
-
|
|
536
|
+
const serialized = {
|
|
457
537
|
positioning: {
|
|
458
538
|
onliness: strategy.positioning.onliness,
|
|
459
539
|
category: strategy.positioning.category,
|
|
@@ -462,11 +542,7 @@ function serializeBrandStrategy(strategy) {
|
|
|
462
542
|
essence: [...strategy.essence],
|
|
463
543
|
personality: strategy.personality.map((p) => ({ trait: p.trait, not: p.not })),
|
|
464
544
|
archetype,
|
|
465
|
-
pillars: strategy.pillars.map(
|
|
466
|
-
id: p.id,
|
|
467
|
-
statement: p.statement,
|
|
468
|
-
governs: compactGoverns(p.governs)
|
|
469
|
-
})),
|
|
545
|
+
pillars: strategy.pillars.map(serializePillar),
|
|
470
546
|
voice: {
|
|
471
547
|
traits: strategy.voice.traits.map((t) => {
|
|
472
548
|
const trait = {
|
|
@@ -483,6 +559,38 @@ function serializeBrandStrategy(strategy) {
|
|
|
483
559
|
core: [...strategy.core],
|
|
484
560
|
visibility: strategy.visibility
|
|
485
561
|
};
|
|
562
|
+
if (strategy.messaging !== void 0) {
|
|
563
|
+
serialized.messaging = { roof: strategy.messaging.roof };
|
|
564
|
+
}
|
|
565
|
+
if (strategy.taglines !== void 0) {
|
|
566
|
+
serialized.taglines = [...strategy.taglines];
|
|
567
|
+
}
|
|
568
|
+
if (strategy.boilerplate !== void 0) {
|
|
569
|
+
serialized.boilerplate = {
|
|
570
|
+
short: strategy.boilerplate.short,
|
|
571
|
+
long: strategy.boilerplate.long
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
if (strategy.colorUsage !== void 0) {
|
|
575
|
+
serialized.colorUsage = {
|
|
576
|
+
pairings: strategy.colorUsage.pairings.map((p) => ({
|
|
577
|
+
use: p.use,
|
|
578
|
+
with: p.with,
|
|
579
|
+
rule: p.rule
|
|
580
|
+
}))
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
if (strategy.accessibility !== void 0) {
|
|
584
|
+
serialized.accessibility = {
|
|
585
|
+
standard: strategy.accessibility.standard,
|
|
586
|
+
contrast: strategy.accessibility.contrast.map((c) => ({
|
|
587
|
+
context: c.context,
|
|
588
|
+
ratio: c.ratio
|
|
589
|
+
})),
|
|
590
|
+
intent: strategy.accessibility.intent
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
return serialized;
|
|
486
594
|
}
|
|
487
595
|
|
|
488
596
|
// src/pipeline.ts
|
|
@@ -834,7 +942,17 @@ var visor_theme_schema_default = {
|
|
|
834
942
|
type: "string",
|
|
835
943
|
enum: ["public", "private"],
|
|
836
944
|
description: "Client brands are private and are omitted from the public agent manifest."
|
|
837
|
-
}
|
|
945
|
+
},
|
|
946
|
+
messaging: { $ref: "#/$defs/brandMessaging" },
|
|
947
|
+
taglines: {
|
|
948
|
+
type: "array",
|
|
949
|
+
items: { type: "string", minLength: 1 },
|
|
950
|
+
minItems: 1,
|
|
951
|
+
description: "Phase 2 wave-1 (VI-541). Permanent, brand-level signature line(s) \u2014 who the brand is, not what it sells this quarter."
|
|
952
|
+
},
|
|
953
|
+
boilerplate: { $ref: "#/$defs/brandBoilerplate" },
|
|
954
|
+
colorUsage: { $ref: "#/$defs/brandColorUsage" },
|
|
955
|
+
accessibility: { $ref: "#/$defs/brandAccessibility" }
|
|
838
956
|
}
|
|
839
957
|
},
|
|
840
958
|
spacing: {
|
|
@@ -1056,7 +1174,13 @@ var visor_theme_schema_default = {
|
|
|
1056
1174
|
properties: {
|
|
1057
1175
|
id: { type: "string", minLength: 1 },
|
|
1058
1176
|
statement: { type: "string", minLength: 1, description: "The pillar's claim in one line." },
|
|
1059
|
-
governs: { $ref: "#/$defs/brandGoverns" }
|
|
1177
|
+
governs: { $ref: "#/$defs/brandGoverns" },
|
|
1178
|
+
proof: {
|
|
1179
|
+
type: "array",
|
|
1180
|
+
items: { type: "string", minLength: 1 },
|
|
1181
|
+
minItems: 1,
|
|
1182
|
+
description: "Phase 2 wave-1 (VI-541). Reasons-to-believe \u2014 checkable evidence backing this pillar's claim (the message-house foundation)."
|
|
1183
|
+
}
|
|
1060
1184
|
}
|
|
1061
1185
|
},
|
|
1062
1186
|
brandVoice: {
|
|
@@ -1099,6 +1223,66 @@ var visor_theme_schema_default = {
|
|
|
1099
1223
|
use: { type: "string", minLength: 1 },
|
|
1100
1224
|
avoid: { type: "string", minLength: 1 }
|
|
1101
1225
|
}
|
|
1226
|
+
},
|
|
1227
|
+
brandMessaging: {
|
|
1228
|
+
type: "object",
|
|
1229
|
+
description: "Phase 2 wave-1 (VI-541). Message-house roof \u2014 the single umbrella message above the pillars.",
|
|
1230
|
+
additionalProperties: false,
|
|
1231
|
+
required: ["roof"],
|
|
1232
|
+
properties: {
|
|
1233
|
+
roof: { type: "string", minLength: 1, description: "One overarching statement the pillars support." }
|
|
1234
|
+
}
|
|
1235
|
+
},
|
|
1236
|
+
brandBoilerplate: {
|
|
1237
|
+
type: "object",
|
|
1238
|
+
description: 'Phase 2 wave-1 (VI-541). Reusable "about us" copy \u2014 short and long forms.',
|
|
1239
|
+
additionalProperties: false,
|
|
1240
|
+
required: ["short", "long"],
|
|
1241
|
+
properties: {
|
|
1242
|
+
short: { type: "string", minLength: 1 },
|
|
1243
|
+
long: { type: "string", minLength: 1 }
|
|
1244
|
+
}
|
|
1245
|
+
},
|
|
1246
|
+
brandColorPairing: {
|
|
1247
|
+
type: "object",
|
|
1248
|
+
description: "A color-pairing rule expressed as brand intent (not a computed value).",
|
|
1249
|
+
additionalProperties: false,
|
|
1250
|
+
required: ["use", "with", "rule"],
|
|
1251
|
+
properties: {
|
|
1252
|
+
use: { type: "string", minLength: 1, description: "The token or role being used (e.g. --primary)." },
|
|
1253
|
+
with: { type: "string", minLength: 1, description: "What it pairs against (token, role, or surface)." },
|
|
1254
|
+
rule: { type: "string", minLength: 1, description: "The intent \u2014 when and how the pairing is allowed." }
|
|
1255
|
+
}
|
|
1256
|
+
},
|
|
1257
|
+
brandColorUsage: {
|
|
1258
|
+
type: "object",
|
|
1259
|
+
description: "Phase 2 wave-1 (VI-541). Color-usage intent \u2014 the brand's allowed pairings.",
|
|
1260
|
+
additionalProperties: false,
|
|
1261
|
+
required: ["pairings"],
|
|
1262
|
+
properties: {
|
|
1263
|
+
pairings: { type: "array", items: { $ref: "#/$defs/brandColorPairing" }, minItems: 1 }
|
|
1264
|
+
}
|
|
1265
|
+
},
|
|
1266
|
+
brandContrastTarget: {
|
|
1267
|
+
type: "object",
|
|
1268
|
+
description: "A contrast target expressed as brand intent (a WCAG 2.1 AA threshold).",
|
|
1269
|
+
additionalProperties: false,
|
|
1270
|
+
required: ["context", "ratio"],
|
|
1271
|
+
properties: {
|
|
1272
|
+
context: { type: "string", minLength: 1, description: "The text/UI context the target applies to." },
|
|
1273
|
+
ratio: { type: "string", minLength: 1, description: 'The minimum contrast ratio (e.g. "4.5:1").' }
|
|
1274
|
+
}
|
|
1275
|
+
},
|
|
1276
|
+
brandAccessibility: {
|
|
1277
|
+
type: "object",
|
|
1278
|
+
description: "Phase 2 wave-1 (VI-541). Accessibility intent \u2014 the standard and its contrast targets (authored as intent; live computation is the render surface's concern).",
|
|
1279
|
+
additionalProperties: false,
|
|
1280
|
+
required: ["standard", "contrast", "intent"],
|
|
1281
|
+
properties: {
|
|
1282
|
+
standard: { type: "string", minLength: 1, description: 'The conformance standard. Visor targets "WCAG 2.1 AA".' },
|
|
1283
|
+
contrast: { type: "array", items: { $ref: "#/$defs/brandContrastTarget" }, minItems: 1 },
|
|
1284
|
+
intent: { type: "string", minLength: 1, description: "How the brand applies the standard (intent, not computed results)." }
|
|
1285
|
+
}
|
|
1102
1286
|
}
|
|
1103
1287
|
}
|
|
1104
1288
|
};
|
|
@@ -291,6 +291,12 @@ interface BrandPillar {
|
|
|
291
291
|
statement: string;
|
|
292
292
|
/** What the pillar governs (coherence-checked against the live system). */
|
|
293
293
|
governs: BrandGoverns;
|
|
294
|
+
/**
|
|
295
|
+
* Reasons-to-believe — the message-house foundation (VI-541, Phase 2 wave-1).
|
|
296
|
+
* Concrete, checkable evidence backing this pillar's claim. Optional so a
|
|
297
|
+
* record can carry pillars without proof points.
|
|
298
|
+
*/
|
|
299
|
+
proof?: string[];
|
|
294
300
|
}
|
|
295
301
|
/** A fixed voice trait with a worked example. */
|
|
296
302
|
interface BrandVoiceTrait {
|
|
@@ -319,15 +325,56 @@ interface BrandLexiconEntry {
|
|
|
319
325
|
use: string;
|
|
320
326
|
avoid: string;
|
|
321
327
|
}
|
|
328
|
+
/** Message-house roof — the single umbrella message above the pillars. */
|
|
329
|
+
interface BrandMessaging {
|
|
330
|
+
/** One overarching statement the pillars support (message-house roof). */
|
|
331
|
+
roof: string;
|
|
332
|
+
}
|
|
333
|
+
/** Reusable "about us" copy — short and long forms. */
|
|
334
|
+
interface BrandBoilerplate {
|
|
335
|
+
short: string;
|
|
336
|
+
long: string;
|
|
337
|
+
}
|
|
338
|
+
/** A color-pairing rule expressed as brand intent (not a computed value). */
|
|
339
|
+
interface BrandColorPairing {
|
|
340
|
+
/** The token or role being used (e.g. `--primary`). */
|
|
341
|
+
use: string;
|
|
342
|
+
/** What it pairs against (token, role, or surface). */
|
|
343
|
+
with: string;
|
|
344
|
+
/** The intent — when and how the pairing is allowed. */
|
|
345
|
+
rule: string;
|
|
346
|
+
}
|
|
347
|
+
/** Color-usage intent — the brand's allowed pairings. */
|
|
348
|
+
interface BrandColorUsage {
|
|
349
|
+
pairings: BrandColorPairing[];
|
|
350
|
+
}
|
|
351
|
+
/** A contrast target expressed as brand intent (a WCAG 2.1 AA threshold). */
|
|
352
|
+
interface BrandContrastTarget {
|
|
353
|
+
/** The text/UI context the target applies to. */
|
|
354
|
+
context: string;
|
|
355
|
+
/** The minimum contrast ratio (e.g. "4.5:1"). */
|
|
356
|
+
ratio: string;
|
|
357
|
+
}
|
|
358
|
+
/** Accessibility intent — the standard and its contrast targets. */
|
|
359
|
+
interface BrandAccessibility {
|
|
360
|
+
/** The conformance standard. Visor targets "WCAG 2.1 AA". */
|
|
361
|
+
standard: string;
|
|
362
|
+
/** WCAG 2.1 AA contrast targets, authored as intent (live computation is the render surface's concern). */
|
|
363
|
+
contrast: BrandContrastTarget[];
|
|
364
|
+
/** How the brand applies the standard (intent, not computed results). */
|
|
365
|
+
intent: string;
|
|
366
|
+
}
|
|
322
367
|
/** Visibility of a brand strategy. Client brands are `private`. */
|
|
323
368
|
type BrandVisibility = "public" | "private";
|
|
324
369
|
/**
|
|
325
370
|
* The `brand-strategy` block — strategy + verbal identity as data.
|
|
326
371
|
*
|
|
327
372
|
* `tone` is keyed by UI state (`error`, `success`, …); the keys are validated
|
|
328
|
-
* against the recognized UI states (coherence check D2).
|
|
329
|
-
* required in v1 — F1 authors the full record, and the downstream Workbench
|
|
330
|
-
* surfaces render each section.
|
|
373
|
+
* against the recognized UI states (coherence check D2). The ten Phase 1 fields
|
|
374
|
+
* are required in v1 — F1 authors the full record, and the downstream Workbench
|
|
375
|
+
* surfaces render each section. The Phase 2 wave-1 fields (`messaging`,
|
|
376
|
+
* `taglines`, `boilerplate`, `colorUsage`, `accessibility`; VI-541) are optional
|
|
377
|
+
* so a record — e.g. a private client brand — can omit them.
|
|
331
378
|
*/
|
|
332
379
|
interface BrandStrategy {
|
|
333
380
|
positioning: BrandPositioning;
|
|
@@ -343,6 +390,16 @@ interface BrandStrategy {
|
|
|
343
390
|
/** Aaker core/extended — the immutable subset, as section names. */
|
|
344
391
|
core: string[];
|
|
345
392
|
visibility: BrandVisibility;
|
|
393
|
+
/** Message-house roof — the umbrella message above the pillars. */
|
|
394
|
+
messaging?: BrandMessaging;
|
|
395
|
+
/** Permanent, brand-level signature line(s) — who the brand is, not what it sells this quarter. */
|
|
396
|
+
taglines?: string[];
|
|
397
|
+
/** Reusable "about us" copy — short and long forms. */
|
|
398
|
+
boilerplate?: BrandBoilerplate;
|
|
399
|
+
/** Color-usage intent — the brand's allowed pairings. */
|
|
400
|
+
colorUsage?: BrandColorUsage;
|
|
401
|
+
/** Accessibility intent — WCAG 2.1 AA standard + contrast targets. */
|
|
402
|
+
accessibility?: BrandAccessibility;
|
|
346
403
|
}
|
|
347
404
|
/**
|
|
348
405
|
* The agent-facing projection of a brand strategy, embedded in
|
|
@@ -779,4 +836,4 @@ interface ThemeData {
|
|
|
779
836
|
output: ThemeOutput;
|
|
780
837
|
}
|
|
781
838
|
|
|
782
|
-
export { type
|
|
839
|
+
export { GOVERNS_WILDCARD as $, type BrandContrastTarget as A, type BrandSlot as B, type ColorRole as C, type BrandGoverns as D, type BrandLexiconEntry as E, type FontResolveOptions as F, type GoogleFontEntry as G, type BrandMessaging as H, type BrandPersonalityTrait as I, type BrandPillar as J, type BrandPositioning as K, type BrandStrategyIssueSeverity as L, type BrandToneEntry as M, type BrandVariant as N, type OKLCH as O, type ParsedColor as P, type BrandVisibility as Q, type ResolvedThemeConfig as R, type SerializedBrandStrategy as S, type ThemeFontResult as T, type BrandVoice as U, type VisorTypography as V, type BrandVoiceTrait as W, type ColorFormat as X, DEFAULT_BRAND_STRATEGY_SURFACES as Y, DEFAULT_BRAND_STRATEGY_TONE_STATES as Z, type FontSource as _, type FontResolution as a, type RGBA as a0, type SemanticTokenValue as a1, type FontDisplayStrategy as b, type VisorBrand as c, type BrandSource as d, type BrandResolution as e, type ThemeBrandResult as f, type BrandStrategy as g, type BrandStrategyContext as h, type BrandStrategyIssue as i, type BrandStrategyValidationResult as j, type GeneratedPrimitives as k, type ThemeOutput as l, type ThemeData as m, type VisorThemeConfig as n, type FullShadeScale as o, type SelectiveShadeScale as p, type RGB as q, type SemanticTokens as r, type ShadeStep as s, BRAND_VARIANTS as t, BRAND_VISIBILITIES as u, type BrandAccessibility as v, type BrandArchetype as w, type BrandBoilerplate as x, type BrandColorPairing as y, type BrandColorUsage as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loworbitstudio/visor-theme-engine",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "Theme engine for the Visor design system — shade generation, token mapping, font resolution, and import/export for .visor.yaml themes.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -343,7 +343,17 @@
|
|
|
343
343
|
"type": "string",
|
|
344
344
|
"enum": ["public", "private"],
|
|
345
345
|
"description": "Client brands are private and are omitted from the public agent manifest."
|
|
346
|
-
}
|
|
346
|
+
},
|
|
347
|
+
"messaging": { "$ref": "#/$defs/brandMessaging" },
|
|
348
|
+
"taglines": {
|
|
349
|
+
"type": "array",
|
|
350
|
+
"items": { "type": "string", "minLength": 1 },
|
|
351
|
+
"minItems": 1,
|
|
352
|
+
"description": "Phase 2 wave-1 (VI-541). Permanent, brand-level signature line(s) — who the brand is, not what it sells this quarter."
|
|
353
|
+
},
|
|
354
|
+
"boilerplate": { "$ref": "#/$defs/brandBoilerplate" },
|
|
355
|
+
"colorUsage": { "$ref": "#/$defs/brandColorUsage" },
|
|
356
|
+
"accessibility": { "$ref": "#/$defs/brandAccessibility" }
|
|
347
357
|
}
|
|
348
358
|
},
|
|
349
359
|
"spacing": {
|
|
@@ -565,7 +575,13 @@
|
|
|
565
575
|
"properties": {
|
|
566
576
|
"id": { "type": "string", "minLength": 1 },
|
|
567
577
|
"statement": { "type": "string", "minLength": 1, "description": "The pillar's claim in one line." },
|
|
568
|
-
"governs": { "$ref": "#/$defs/brandGoverns" }
|
|
578
|
+
"governs": { "$ref": "#/$defs/brandGoverns" },
|
|
579
|
+
"proof": {
|
|
580
|
+
"type": "array",
|
|
581
|
+
"items": { "type": "string", "minLength": 1 },
|
|
582
|
+
"minItems": 1,
|
|
583
|
+
"description": "Phase 2 wave-1 (VI-541). Reasons-to-believe — checkable evidence backing this pillar's claim (the message-house foundation)."
|
|
584
|
+
}
|
|
569
585
|
}
|
|
570
586
|
},
|
|
571
587
|
"brandVoice": {
|
|
@@ -608,6 +624,66 @@
|
|
|
608
624
|
"use": { "type": "string", "minLength": 1 },
|
|
609
625
|
"avoid": { "type": "string", "minLength": 1 }
|
|
610
626
|
}
|
|
627
|
+
},
|
|
628
|
+
"brandMessaging": {
|
|
629
|
+
"type": "object",
|
|
630
|
+
"description": "Phase 2 wave-1 (VI-541). Message-house roof — the single umbrella message above the pillars.",
|
|
631
|
+
"additionalProperties": false,
|
|
632
|
+
"required": ["roof"],
|
|
633
|
+
"properties": {
|
|
634
|
+
"roof": { "type": "string", "minLength": 1, "description": "One overarching statement the pillars support." }
|
|
635
|
+
}
|
|
636
|
+
},
|
|
637
|
+
"brandBoilerplate": {
|
|
638
|
+
"type": "object",
|
|
639
|
+
"description": "Phase 2 wave-1 (VI-541). Reusable \"about us\" copy — short and long forms.",
|
|
640
|
+
"additionalProperties": false,
|
|
641
|
+
"required": ["short", "long"],
|
|
642
|
+
"properties": {
|
|
643
|
+
"short": { "type": "string", "minLength": 1 },
|
|
644
|
+
"long": { "type": "string", "minLength": 1 }
|
|
645
|
+
}
|
|
646
|
+
},
|
|
647
|
+
"brandColorPairing": {
|
|
648
|
+
"type": "object",
|
|
649
|
+
"description": "A color-pairing rule expressed as brand intent (not a computed value).",
|
|
650
|
+
"additionalProperties": false,
|
|
651
|
+
"required": ["use", "with", "rule"],
|
|
652
|
+
"properties": {
|
|
653
|
+
"use": { "type": "string", "minLength": 1, "description": "The token or role being used (e.g. --primary)." },
|
|
654
|
+
"with": { "type": "string", "minLength": 1, "description": "What it pairs against (token, role, or surface)." },
|
|
655
|
+
"rule": { "type": "string", "minLength": 1, "description": "The intent — when and how the pairing is allowed." }
|
|
656
|
+
}
|
|
657
|
+
},
|
|
658
|
+
"brandColorUsage": {
|
|
659
|
+
"type": "object",
|
|
660
|
+
"description": "Phase 2 wave-1 (VI-541). Color-usage intent — the brand's allowed pairings.",
|
|
661
|
+
"additionalProperties": false,
|
|
662
|
+
"required": ["pairings"],
|
|
663
|
+
"properties": {
|
|
664
|
+
"pairings": { "type": "array", "items": { "$ref": "#/$defs/brandColorPairing" }, "minItems": 1 }
|
|
665
|
+
}
|
|
666
|
+
},
|
|
667
|
+
"brandContrastTarget": {
|
|
668
|
+
"type": "object",
|
|
669
|
+
"description": "A contrast target expressed as brand intent (a WCAG 2.1 AA threshold).",
|
|
670
|
+
"additionalProperties": false,
|
|
671
|
+
"required": ["context", "ratio"],
|
|
672
|
+
"properties": {
|
|
673
|
+
"context": { "type": "string", "minLength": 1, "description": "The text/UI context the target applies to." },
|
|
674
|
+
"ratio": { "type": "string", "minLength": 1, "description": "The minimum contrast ratio (e.g. \"4.5:1\")." }
|
|
675
|
+
}
|
|
676
|
+
},
|
|
677
|
+
"brandAccessibility": {
|
|
678
|
+
"type": "object",
|
|
679
|
+
"description": "Phase 2 wave-1 (VI-541). Accessibility intent — the standard and its contrast targets (authored as intent; live computation is the render surface's concern).",
|
|
680
|
+
"additionalProperties": false,
|
|
681
|
+
"required": ["standard", "contrast", "intent"],
|
|
682
|
+
"properties": {
|
|
683
|
+
"standard": { "type": "string", "minLength": 1, "description": "The conformance standard. Visor targets \"WCAG 2.1 AA\"." },
|
|
684
|
+
"contrast": { "type": "array", "items": { "$ref": "#/$defs/brandContrastTarget" }, "minItems": 1 },
|
|
685
|
+
"intent": { "type": "string", "minLength": 1, "description": "How the brand applies the standard (intent, not computed results)." }
|
|
686
|
+
}
|
|
611
687
|
}
|
|
612
688
|
}
|
|
613
689
|
}
|