@getvitops/utils 6.0.0 → 8.0.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.
Files changed (58) hide show
  1. package/CHANGELOG.md +248 -13
  2. package/dist/adc-BFrzpMHq.d.mts +25 -0
  3. package/dist/adc-BFrzpMHq.d.mts.map +1 -0
  4. package/dist/adc-D6aw2qgq.mjs +45 -0
  5. package/dist/adc-D6aw2qgq.mjs.map +1 -0
  6. package/dist/ads/index.d.mts +0 -1
  7. package/dist/ads/index.d.mts.map +1 -1
  8. package/dist/ads/index.mjs +4 -13
  9. package/dist/ads/index.mjs.map +1 -1
  10. package/dist/{cloudflare-CD8vwrgj.mjs → cloudflare-CgAsXiqe.mjs} +24 -2
  11. package/dist/cloudflare-CgAsXiqe.mjs.map +1 -0
  12. package/dist/color/index.d.mts +0 -3
  13. package/dist/color/index.d.mts.map +1 -1
  14. package/dist/color/index.mjs +0 -3
  15. package/dist/color/index.mjs.map +1 -1
  16. package/dist/index.d.mts +5 -101
  17. package/dist/index.d.mts.map +1 -1
  18. package/dist/index.mjs +5 -145
  19. package/dist/index.mjs.map +1 -1
  20. package/dist/indexing/index.d.mts +5 -6
  21. package/dist/indexing/index.d.mts.map +1 -1
  22. package/dist/indexing/index.mjs +12 -34
  23. package/dist/indexing/index.mjs.map +1 -1
  24. package/dist/json-store-30CFCbZZ.mjs +38 -0
  25. package/dist/json-store-30CFCbZZ.mjs.map +1 -0
  26. package/dist/media/index.d.mts +0 -2
  27. package/dist/media/index.d.mts.map +1 -1
  28. package/dist/media/index.mjs +4 -20
  29. package/dist/media/index.mjs.map +1 -1
  30. package/dist/notify/index.d.mts +1 -2
  31. package/dist/notify/index.d.mts.map +1 -1
  32. package/dist/onboarding/index.d.mts +7 -7
  33. package/dist/onboarding/index.d.mts.map +1 -1
  34. package/dist/onboarding/index.mjs +19 -38
  35. package/dist/onboarding/index.mjs.map +1 -1
  36. package/dist/reviews/index.d.mts +154 -0
  37. package/dist/reviews/index.d.mts.map +1 -0
  38. package/dist/reviews/index.mjs +218 -0
  39. package/dist/reviews/index.mjs.map +1 -0
  40. package/dist/schema/index.d.mts +191 -0
  41. package/dist/schema/index.d.mts.map +1 -0
  42. package/dist/schema/index.mjs +241 -0
  43. package/dist/schema/index.mjs.map +1 -0
  44. package/dist/security/index.d.mts +48 -0
  45. package/dist/security/index.d.mts.map +1 -0
  46. package/dist/security/index.mjs +80 -0
  47. package/dist/security/index.mjs.map +1 -0
  48. package/dist/token-Bz_-igw-.d.mts +74 -0
  49. package/dist/{token--18wN9UR.d.mts.map → token-Bz_-igw-.d.mts.map} +1 -1
  50. package/dist/{token-BV7tPHh2.mjs → token-DkKC5m23.mjs} +25 -3
  51. package/dist/{token-BV7tPHh2.mjs.map → token-DkKC5m23.mjs.map} +1 -1
  52. package/dist/tracking/index.d.mts +1 -1
  53. package/dist/{types-C3lHaSrU.d.mts → types-CHHjzRrv.d.mts} +1 -2
  54. package/dist/types-CHHjzRrv.d.mts.map +1 -0
  55. package/package.json +25 -2
  56. package/dist/cloudflare-CD8vwrgj.mjs.map +0 -1
  57. package/dist/token--18wN9UR.d.mts +0 -46
  58. package/dist/types-C3lHaSrU.d.mts.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudflare-CgAsXiqe.mjs","names":[],"sources":["../src/plan-format.ts","../src/onboarding/cloudflare.ts"],"sourcesContent":["/**\n * The end-of-run summary table shared by `onboarding/plan.ts`'s and `ads/plan.ts`'s\n * `formatSummary` — same header row, same column padding, same \"Reminders\n * (manual — no API):\" tail. Their `StepAction`/`StepPlan`/`formatPlan` glyph\n * renderers stay separate: onboarding's steps are `create | update | skip`\n * with no `blocked` state, ads' are `create | skip | blocked` with a `needs`\n * field, and collapsing those two shapes into one would blur a real\n * difference rather than remove duplication.\n */\nconst pad = (s: string, n: number) => s.padEnd(n);\n\n/** Render a fixed-width table, then a \"Reminders\" section if any were passed. */\nexport function table(headers: string[], rows: string[][], reminders: string[]): string {\n const widths = headers.map((h, i) =>\n Math.max(h.length, ...rows.map((row) => row[i]?.length ?? 0)),\n );\n const line = (cells: string[]) =>\n cells\n .map((c, i) => pad(c, widths[i] ?? 0))\n .join(' ')\n .trimEnd();\n\n const out = [line(headers), widths.map((w) => '─'.repeat(w)).join(' ')];\n for (const row of rows) out.push(line(row));\n if (reminders.length) out.push('', 'Reminders (manual — no API):', ...reminders);\n return out.join('\\n');\n}\n","/**\n * Cloudflare DNS — the one thing this command writes.\n *\n * Scoped to exactly what onboarding needs and nothing more: find a zone by name,\n * read the apex TXT records, and *create* the verification TXT when it is missing.\n * There is deliberately no update and no delete — the command's contract is that it\n * never removes a DNS record, so the destructive verbs are simply absent rather\n * than guarded.\n *\n * The token is a `Zone:DNS:Edit` credential from the environment\n * (`CLOUDFLARE_API_TOKEN`); listing a zone by name also needs `Zone:Read`, which\n * Cloudflare's standard \"Edit zone DNS\" token template already bundles. As with the\n * indexing executors, `fetchImpl` is injected so the request shape is testable\n * without the network, and every call returns a structured result rather than\n * throwing — the caller decides what a failure means per domain.\n */\nconst API = 'https://api.cloudflare.com/client/v4';\n\ninterface CfEnvelope<T> {\n success: boolean;\n errors?: { code: number; message: string }[];\n result?: T;\n}\n\nconst cfError = (status: number, body: CfEnvelope<unknown>): string => {\n const first = body.errors?.[0];\n return first ? `${first.code} ${first.message}` : `HTTP ${status}`;\n};\n\n/** Find the zone id for a domain (`GET /zones?name=`). */\nexport async function findZoneId(\n token: string,\n domain: string,\n fetchImpl: typeof fetch = fetch,\n): Promise<{ ok: boolean; status: number; zoneId?: string; message?: string }> {\n const res = await fetchImpl(`${API}/zones?name=${encodeURIComponent(domain)}`, {\n headers: { authorization: `Bearer ${token}` },\n });\n const body = (await res.json()) as CfEnvelope<{ id: string; name: string }[]>;\n if (!res.ok || !body.success)\n return { ok: false, status: res.status, message: cfError(res.status, body) };\n const zone = body.result?.[0];\n if (!zone)\n return {\n ok: false,\n status: res.status,\n // Name the scope: this lookup is a GET /zones?name=, which needs\n // `Zone:Read` — a token carrying only `Zone:DNS:Edit` reaches here and\n // reads as \"the zone isn't in this account\", which sends you to the\n // wrong dashboard.\n message: `no Cloudflare zone named \"${domain}\" (is it in this account, and does the token carry Zone:Read as well as Zone:DNS:Edit? The \"Edit zone DNS\" template covers both.)`,\n };\n return { ok: true, status: res.status, zoneId: zone.id };\n}\n\n/** List the apex TXT record contents for a zone. */\nexport async function listApexTxt(\n token: string,\n zoneId: string,\n domain: string,\n fetchImpl: typeof fetch = fetch,\n): Promise<{ ok: boolean; status: number; contents: string[]; message?: string }> {\n const res = await fetchImpl(\n `${API}/zones/${zoneId}/dns_records?type=TXT&name=${encodeURIComponent(domain)}`,\n { headers: { authorization: `Bearer ${token}` } },\n );\n const body = (await res.json()) as CfEnvelope<{ content: string }[]>;\n if (!res.ok || !body.success)\n return { ok: false, status: res.status, contents: [], message: cfError(res.status, body) };\n // Cloudflare returns TXT content quoted; normalise so an exact compare works.\n const contents = (body.result ?? []).map((r) => r.content.replace(/^\"|\"$/g, ''));\n return { ok: true, status: res.status, contents };\n}\n\n/**\n * Create an apex TXT record. **Create only** — never called when one already\n * exists (the planner decides that), and there is no sibling that edits or removes.\n */\nexport async function createApexTxt(\n token: string,\n zoneId: string,\n domain: string,\n content: string,\n fetchImpl: typeof fetch = fetch,\n): Promise<{ ok: boolean; status: number; message?: string }> {\n const res = await fetchImpl(`${API}/zones/${zoneId}/dns_records`, {\n method: 'POST',\n headers: { authorization: `Bearer ${token}`, 'content-type': 'application/json' },\n body: JSON.stringify({ type: 'TXT', name: domain, content }),\n });\n const body = (await res.json()) as CfEnvelope<{ id: string }>;\n if (!res.ok || !body.success)\n return { ok: false, status: res.status, message: cfError(res.status, body) };\n return { ok: true, status: res.status };\n}\n"],"mappings":";;;;;;;;;;AASA,MAAM,OAAO,GAAW,MAAc,EAAE,OAAO,CAAC;;AAGhD,SAAgB,MAAM,SAAmB,MAAkB,WAA6B;CACtF,MAAM,SAAS,QAAQ,KAAK,GAAG,MAC7B,KAAK,IAAI,EAAE,QAAQ,GAAG,KAAK,KAAK,QAAQ,IAAI,EAAE,EAAE,UAAU,CAAC,CAAC,CAC9D;CACA,MAAM,QAAQ,UACZ,MACG,KAAK,GAAG,MAAM,IAAI,GAAG,OAAO,MAAM,CAAC,CAAC,CAAC,CACrC,KAAK,IAAI,CAAC,CACV,QAAQ;CAEb,MAAM,MAAM,CAAC,KAAK,OAAO,GAAG,OAAO,KAAK,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;CACvE,KAAK,MAAM,OAAO,MAAM,IAAI,KAAK,KAAK,GAAG,CAAC;CAC1C,IAAI,UAAU,QAAQ,IAAI,KAAK,IAAI,gCAAgC,GAAG,SAAS;CAC/E,OAAO,IAAI,KAAK,IAAI;AACtB;;;;;;;;;;;;;;;;;;;;ACVA,MAAM,MAAM;AAQZ,MAAM,WAAW,QAAgB,SAAsC;CACrE,MAAM,QAAQ,KAAK,SAAS;CAC5B,OAAO,QAAQ,GAAG,MAAM,KAAK,GAAG,MAAM,YAAY,QAAQ;AAC5D;;AAGA,eAAsB,WACpB,OACA,QACA,YAA0B,OACmD;CAC7E,MAAM,MAAM,MAAM,UAAU,GAAG,IAAI,cAAc,mBAAmB,MAAM,KAAK,EAC7E,SAAS,EAAE,eAAe,UAAU,QAAQ,EAC9C,CAAC;CACD,MAAM,OAAQ,MAAM,IAAI,KAAK;CAC7B,IAAI,CAAC,IAAI,MAAM,CAAC,KAAK,SACnB,OAAO;EAAE,IAAI;EAAO,QAAQ,IAAI;EAAQ,SAAS,QAAQ,IAAI,QAAQ,IAAI;CAAE;CAC7E,MAAM,OAAO,KAAK,SAAS;CAC3B,IAAI,CAAC,MACH,OAAO;EACL,IAAI;EACJ,QAAQ,IAAI;EAKZ,SAAS,6BAA6B,OAAO;CAC/C;CACF,OAAO;EAAE,IAAI;EAAM,QAAQ,IAAI;EAAQ,QAAQ,KAAK;CAAG;AACzD;;AAGA,eAAsB,YACpB,OACA,QACA,QACA,YAA0B,OACsD;CAChF,MAAM,MAAM,MAAM,UAChB,GAAG,IAAI,SAAS,OAAO,6BAA6B,mBAAmB,MAAM,KAC7E,EAAE,SAAS,EAAE,eAAe,UAAU,QAAQ,EAAE,CAClD;CACA,MAAM,OAAQ,MAAM,IAAI,KAAK;CAC7B,IAAI,CAAC,IAAI,MAAM,CAAC,KAAK,SACnB,OAAO;EAAE,IAAI;EAAO,QAAQ,IAAI;EAAQ,UAAU,CAAC;EAAG,SAAS,QAAQ,IAAI,QAAQ,IAAI;CAAE;CAE3F,MAAM,YAAY,KAAK,UAAU,CAAC,EAAC,CAAE,KAAK,MAAM,EAAE,QAAQ,QAAQ,UAAU,EAAE,CAAC;CAC/E,OAAO;EAAE,IAAI;EAAM,QAAQ,IAAI;EAAQ;CAAS;AAClD;;;;;AAMA,eAAsB,cACpB,OACA,QACA,QACA,SACA,YAA0B,OACkC;CAC5D,MAAM,MAAM,MAAM,UAAU,GAAG,IAAI,SAAS,OAAO,eAAe;EAChE,QAAQ;EACR,SAAS;GAAE,eAAe,UAAU;GAAS,gBAAgB;EAAmB;EAChF,MAAM,KAAK,UAAU;GAAE,MAAM;GAAO,MAAM;GAAQ;EAAQ,CAAC;CAC7D,CAAC;CACD,MAAM,OAAQ,MAAM,IAAI,KAAK;CAC7B,IAAI,CAAC,IAAI,MAAM,CAAC,KAAK,SACnB,OAAO;EAAE,IAAI;EAAO,QAAQ,IAAI;EAAQ,SAAS,QAAQ,IAAI,QAAQ,IAAI;CAAE;CAC7E,OAAO;EAAE,IAAI;EAAM,QAAQ,IAAI;CAAO;AACxC"}
@@ -34,9 +34,6 @@ declare function hexToOklch(hex: string): {
34
34
  c: number;
35
35
  h: number;
36
36
  };
37
- /**
38
- * Convert OKLCH components to hex color
39
- */
40
37
  declare function oklchToHex(oklch: {
41
38
  l: number;
42
39
  c: number;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/color/colors.ts","../../src/color/color-harmony.ts"],"mappings":";UAkBiB,SAAA;EACf,CAAA;EACA,CAAA;EACA,CAAA;EACA,OAAA;EAHA;EAKA,aAAA;AAAA;;;;AAAa;iBAOC,WAAA,CAAY,CAAA,UAAW,CAAA,UAAW,CAAA,WAAY,SAAS;;;;;iBAmBvD,SAAA,CAAU,CAAA,UAAW,CAAA,UAAW,CAAA,WAAY,SAAS;;;;AAnBE;iBAsCvD,kBAAA,CACd,CAAA,UACA,CAAA,UACA,CAAA,UACA,KAAA;AAAA,cAUW,UAAA;AAAA,KACD,QAAA,WAAmB,UAAU;AAAA,cAE5B,YAAA;AAAA,KAWD,UAAA,WAAqB,YAAY;;;;iBAK7B,UAAA,CAAW,GAAA;EAAgB,CAAA;EAAW,CAAA;EAAW,CAAA;AAAA;;;;iBAajD,UAAA,CAAW,KAAA;EAAS,CAAA;EAAW,CAAA;EAAW,CAAA;AAAA;;;;AAhC+B;iBA8CzE,gBAAA,CAAiB,WAAmB;;;;AA7CX;iBA8DzB,eAAA,CAAgB,IAAY;;;;iBA+G5B,YAAA,CAAa,GAAW;AAhKxC;;;AAAA,iBAsLgB,mBAAA,CAAoB,GAAW;AAAA,cAclC,aAAA;AAAA,KASD,WAAA,WAAsB,aAAa;AAAA,UAE9B,iBAAA;EACf,KAAA;EACA,OAAA;EACA,YAAA;AAAA;AAAA,cAGW,mBAAA,EAAqB,MAAA,CAAO,WAAA,EAAa,iBAAA;;;AAhNY;AAalE;;;;;;;;;AAAqE;AAcrE;cAyOa,gBAAA,EAAkB,MAAM,CAAC,QAAA;;;AAzOc;AAiBpD;;;;AAA4C;AA+G5C;;;;AAAwC;AAsBxC;;;;AAA+C;AAc/C;cAsGa,eAAA;EAAA,SAAwD,KAAA;EAAA,SAAA,IAAA;AAAA;AAAA,UAE3D,UAAA;EACR,CAAA;EACA,CAAA;EACA,CAAA;AAAA;AAhGF;;;;;AAAA,iBAwGgB,UAAA,CAAW,WAAA,WAAsB,UAAU;;;AArG7C;AAGd;iBAkIgB,qBAAA,CAAsB,SAAA,WAAoB,QAAQ;;;;;;;;;iBAuBlD,eAAA,CAAgB,IAAA,EAAM,QAAQ,EAAE,SAAA;;AAzJuB;AAoDvE;;;;AAA8C;AAiC9C;;;;;AAAsE;;;;;;iBA6FtD,oBAAA,CACd,KAAA,sBAA2B,MAAA,mBAC1B,MAAA,CAAO,QAAA;;iBAsFM,UAAA,CAAW,EAAA,UAAY,EAAU;AAxKjD;;;;AAAA,iBAgLgB,MAAA,CAAO,EAAA,UAAY,GAAY;AAhJ/C;;;;AAAkE;AAuBlE;;;;;AAvBA,iBAiKgB,eAAA,CAAgB,GAAA,UAAa,MAAA;EAAoB,KAAA;EAAe,IAAA;AAAA;;;;AAvkBhF;;KCdY,eAAA;AAAA,UAWK,aAAA;EACf,EAAA,EAAI,eAAe;EACnB,KAAA;EACA,WAAA;EACA,QAAA;AAAA;AAAA,cAGW,kBAAA,EAAoB,aAAa;ADE/B;AAOf;;AAPe,iBC0DC,oBAAA,CAAqB,OAAA,UAAiB,QAAA,EAAU,eAAe;;;;iBAgB/D,qBAAA,CACd,OAAA,WACC,KAAK;EAAG,QAAA,EAAU,eAAA;EAAiB,GAAA;EAAa,KAAA;EAAe,WAAA;AAAA;;;;cAYrD,uBAAA;EAAA;;;;;;;;iBAUG,yBAAA,CACd,IAAA,eAAmB,uBAAuB,EAC1C,YAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/color/colors.ts","../../src/color/color-harmony.ts"],"mappings":";UAiBiB,SAAA;EACf,CAAA;EACA,CAAA;EACA,CAAA;EACA,OAAA;EAHA;EAKA,aAAA;AAAA;;;;AAAa;iBAOC,WAAA,CAAY,CAAA,UAAW,CAAA,UAAW,CAAA,WAAY,SAAS;;;;;iBAmBvD,SAAA,CAAU,CAAA,UAAW,CAAA,UAAW,CAAA,WAAY,SAAS;;;;AAnBE;iBAsCvD,kBAAA,CACd,CAAA,UACA,CAAA,UACA,CAAA,UACA,KAAA;AAAA,cAUW,UAAA;AAAA,KACD,QAAA,WAAmB,UAAU;AAAA,cAE5B,YAAA;AAAA,KAWD,UAAA,WAAqB,YAAY;;;;iBAK7B,UAAA,CAAW,GAAA;EAAgB,CAAA;EAAW,CAAA;EAAW,CAAA;AAAA;AAAA,iBAUjD,UAAA,CAAW,KAAA;EAAS,CAAA;EAAW,CAAA;EAAW,CAAA;AAAA;;AAvC3B;AAU/B;;iBA0CgB,gBAAA,CAAiB,WAAmB;;AA1CqC;AACzF;;iBA0DgB,eAAA,CAAgB,IAAY;;AA1DH;AAEzC;iBAsKgB,YAAA,CAAa,GAAW;;;AA5J9B;iBAkLM,mBAAA,CAAoB,GAAW;AAAA,cAclC,aAAA;AAAA,KASD,WAAA,WAAsB,aAAa;AAAA,UAE9B,iBAAA;EACf,KAAA;EACA,OAAA;EACA,YAAA;AAAA;AAAA,cAGW,mBAAA,EAAqB,MAAA,CAAO,WAAA,EAAa,iBAAA;;;;;;AA3MY;AAUlE;;;;;;;;cAqPa,gBAAA,EAAkB,MAAM,CAAC,QAAA;AArP+B;AAarE;;;;AAAoD;AAiBpD;;;;AAA4C;AA8G5C;;;;AAAwC;AAsBxC;;;AAlKqE,cAsRxD,eAAA;EAAA,SAAwD,KAAA;EAAA,SAAA,IAAA;AAAA;AAAA,UAE3D,UAAA;EACR,CAAA;EACA,CAAA;EACA,CAAA;AAAA;;;AAlG6C;AAE/C;;iBAwGgB,UAAA,CAAW,WAAA,WAAsB,UAAU;;;;;iBAgC3C,qBAAA,CAAsB,SAAA,WAAoB,QAAQ;AArIpD;AAGd;;;;;;;AAHc,iBA4JE,eAAA,CAAgB,IAAA,EAAM,QAAQ,EAAE,SAAA;;;;;AAzJuB;AAoDvE;;;;AAA8C;AAiC9C;;;;;AAAsE;;;iBA6FtD,oBAAA,CACd,KAAA,sBAA2B,MAAA,mBAC1B,MAAA,CAAO,QAAA;;iBAsFM,UAAA,CAAW,EAAA,UAAY,EAAU;;;AAhL9C;AAQH;iBAgLgB,MAAA,CAAO,EAAA,UAAY,GAAY;;;AAhLY;AAgC3D;;;;AAAkE;AAuBlE;;iBA0IgB,eAAA,CAAgB,GAAA,UAAa,MAAA;EAAoB,KAAA;EAAe,IAAA;AAAA;;;;AAlkBhF;;KCbY,eAAA;AAAA,UAWK,aAAA;EACf,EAAA,EAAI,eAAe;EACnB,KAAA;EACA,WAAA;EACA,QAAA;AAAA;AAAA,cAGW,kBAAA,EAAoB,aAAa;ADC/B;AAOf;;AAPe,iBC2DC,oBAAA,CAAqB,OAAA,UAAiB,QAAA,EAAU,eAAe;;;;iBAgB/D,qBAAA,CACd,OAAA,WACC,KAAK;EAAG,QAAA,EAAU,eAAA;EAAiB,GAAA;EAAa,KAAA;EAAe,WAAA;AAAA;;;;cAYrD,uBAAA;EAAA;;;;;;;;iBAUG,yBAAA,CACd,IAAA,eAAmB,uBAAuB,EAC1C,YAAA"}
@@ -105,9 +105,6 @@ function hexToOklch(hex) {
105
105
  h: oklch.coords[2] || 0
106
106
  };
107
107
  }
108
- /**
109
- * Convert OKLCH components to hex color
110
- */
111
108
  function oklchToHex(oklch) {
112
109
  const srgb = new Color("oklch", [
113
110
  oklch.l,
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["OKLCH_Space","sRGB_Space","P3_Space"],"sources":["../../src/color/colors.ts","../../src/color/color-harmony.ts"],"sourcesContent":["import Color from 'colorjs.io';\nimport {\n OKLCH as OKLCH_Space,\n sRGB as sRGB_Space,\n P3 as P3_Space,\n ColorSpace,\n to,\n toGamutCSS,\n clone,\n serialize,\n type PlainColorObject,\n} from 'colorjs.io/fn';\n\n// Register color spaces once for functional API\nColorSpace.register(OKLCH_Space);\nColorSpace.register(sRGB_Space);\nColorSpace.register(P3_Space);\n\nexport interface RgbResult {\n r: number;\n g: number;\n b: number;\n inGamut: boolean;\n /** Max channel overshoot beyond [0,1] before clamping. 0 when in gamut. */\n gamutDistance: number;\n}\n\n/**\n * Convert OKLCh to sRGB, returning 0-255 clamped values with gamut flag.\n * Fast path for per-pixel canvas rendering (no gamut mapping, just clamp).\n */\nexport function oklchToSrgb(l: number, c: number, h: number): RgbResult {\n const col: PlainColorObject = { space: OKLCH_Space, coords: [l, c, h], alpha: 1 };\n const rgb = to(col, sRGB_Space);\n const [r, g, b] = rgb.coords;\n const inGamut = r >= 0 && r <= 1 && g >= 0 && g <= 1 && b >= 0 && b <= 1;\n const gamutDistance = inGamut ? 0 : Math.max(-r, r - 1, -g, g - 1, -b, b - 1, 0);\n return {\n r: Math.max(0, Math.min(255, Math.round(r * 255))),\n g: Math.max(0, Math.min(255, Math.round(g * 255))),\n b: Math.max(0, Math.min(255, Math.round(b * 255))),\n inGamut,\n gamutDistance,\n };\n}\n\n/**\n * Convert OKLCh to Display P3, returning 0-255 clamped values with gamut flag.\n * Fast path for per-pixel canvas rendering on P3 displays.\n */\nexport function oklchToP3(l: number, c: number, h: number): RgbResult {\n const col: PlainColorObject = { space: OKLCH_Space, coords: [l, c, h], alpha: 1 };\n const rgb = to(col, P3_Space);\n const [r, g, b] = rgb.coords;\n const inGamut = r >= 0 && r <= 1 && g >= 0 && g <= 1 && b >= 0 && b <= 1;\n const gamutDistance = inGamut ? 0 : Math.max(-r, r - 1, -g, g - 1, -b, b - 1, 0);\n return {\n r: Math.max(0, Math.min(255, Math.round(r * 255))),\n g: Math.max(0, Math.min(255, Math.round(g * 255))),\n b: Math.max(0, Math.min(255, Math.round(b * 255))),\n inGamut,\n gamutDistance,\n };\n}\n\n/**\n * Gamut-map an OKLCh color using the CSS gamut mapping algorithm, return hex.\n * Slower than oklchToSrgb/oklchToP3 (uses iterative reduction), use for single colors only.\n */\nexport function gamutMapOklchToHex(\n l: number,\n c: number,\n h: number,\n space: 'srgb' | 'p3' = 'srgb',\n): string {\n const col: PlainColorObject = { space: OKLCH_Space, coords: [l, c, h], alpha: 1 };\n const targetSpace = space === 'p3' ? P3_Space : sRGB_Space;\n const mapped = toGamutCSS(clone(col), { space: targetSpace });\n const rgb = to(mapped, sRGB_Space);\n return serialize(rgb, { format: 'hex' });\n}\n\n// Standard 11-step scale - will be transposed based on input anchors\nexport const STEP_NAMES = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950] as const;\nexport type StepName = (typeof STEP_NAMES)[number];\n\nexport const COLOR_GROUPS = [\n 'neutral',\n 'brand',\n 'primary',\n 'accent',\n 'complement',\n 'success',\n 'warning',\n 'error',\n 'info',\n] as const;\nexport type ColorGroup = (typeof COLOR_GROUPS)[number];\n\n/**\n * Convert hex color to OKLCH components\n */\nexport function hexToOklch(hex: string): { l: number; c: number; h: number } {\n const color = new Color(hex);\n const oklch = color.to('oklch');\n return {\n l: oklch.coords[0],\n c: oklch.coords[1],\n h: oklch.coords[2] || 0,\n };\n}\n\n/**\n * Convert OKLCH components to hex color\n */\nexport function oklchToHex(oklch: { l: number; c: number; h: number }): string {\n const color = new Color('oklch', [oklch.l, oklch.c, oklch.h]);\n // Convert to sRGB and clamp to gamut, then format as hex\n const srgb = color.to('srgb');\n if (!srgb.inGamut()) {\n srgb.toGamut({ method: 'css' });\n }\n return srgb.toString({ format: 'hex' });\n}\n\n/**\n * Convert OKLCH CSS string to hex color\n * @example oklchStringToHex(\"oklch(50% 0.15 270)\") => \"#8b5cf6\"\n */\nexport function oklchStringToHex(oklchString: string): string {\n try {\n const color = new Color(oklchString);\n const srgb = color.to('srgb');\n if (!srgb.inGamut()) {\n srgb.toGamut({ method: 'css' });\n }\n return srgb.toString({ format: 'hex' });\n } catch {\n return '#808080';\n }\n}\n\n/**\n * Format a color name by separating compound words\n * Examples: \"mediumseagreen\" -> \"Medium Sea Green\", \"darkblue\" -> \"Dark Blue\"\n */\nexport function formatColorName(name: string): string {\n if (!name) return 'Unknown';\n\n // Handle special cases with proper word separation\n const specialCases: Record<string, string> = {\n aliceblue: 'Alice Blue',\n antiquewhite: 'Antique White',\n blanchedalmond: 'Blanched Almond',\n blueviolet: 'Blue Violet',\n burlywood: 'Burly Wood',\n cadetblue: 'Cadet Blue',\n cornflowerblue: 'Cornflower Blue',\n darkblue: 'Dark Blue',\n darkcyan: 'Dark Cyan',\n darkgoldenrod: 'Dark Goldenrod',\n darkgray: 'Dark Gray',\n darkgreen: 'Dark Green',\n darkgrey: 'Dark Grey',\n darkkhaki: 'Dark Khaki',\n darkmagenta: 'Dark Magenta',\n darkolivegreen: 'Dark Olive Green',\n darkorange: 'Dark Orange',\n darkorchid: 'Dark Orchid',\n darkred: 'Dark Red',\n darksalmon: 'Dark Salmon',\n darkseagreen: 'Dark Sea Green',\n darkslateblue: 'Dark Slate Blue',\n darkslategray: 'Dark Slate Gray',\n darkslategrey: 'Dark Slate Grey',\n darkturquoise: 'Dark Turquoise',\n darkviolet: 'Dark Violet',\n deeppink: 'Deep Pink',\n deepskyblue: 'Deep Sky Blue',\n dimgray: 'Dim Gray',\n dimgrey: 'Dim Grey',\n dodgerblue: 'Dodger Blue',\n floralwhite: 'Floral White',\n forestgreen: 'Forest Green',\n ghostwhite: 'Ghost White',\n greenyellow: 'Green Yellow',\n hotpink: 'Hot Pink',\n indianred: 'Indian Red',\n lavenderblush: 'Lavender Blush',\n lawngreen: 'Lawn Green',\n lemonchiffon: 'Lemon Chiffon',\n lightblue: 'Light Blue',\n lightcoral: 'Light Coral',\n lightcyan: 'Light Cyan',\n lightgoldenrodyellow: 'Light Goldenrod Yellow',\n lightgray: 'Light Gray',\n lightgreen: 'Light Green',\n lightgrey: 'Light Grey',\n lightpink: 'Light Pink',\n lightsalmon: 'Light Salmon',\n lightseagreen: 'Light Sea Green',\n lightskyblue: 'Light Sky Blue',\n lightslategray: 'Light Slate Gray',\n lightslategrey: 'Light Slate Grey',\n lightsteelblue: 'Light Steel Blue',\n lightyellow: 'Light Yellow',\n limegreen: 'Lime Green',\n mediumaquamarine: 'Medium Aquamarine',\n mediumblue: 'Medium Blue',\n mediumorchid: 'Medium Orchid',\n mediumpurple: 'Medium Purple',\n mediumseagreen: 'Medium Sea Green',\n mediumslateblue: 'Medium Slate Blue',\n mediumspringgreen: 'Medium Spring Green',\n mediumturquoise: 'Medium Turquoise',\n mediumvioletred: 'Medium Violet Red',\n midnightblue: 'Midnight Blue',\n mintcream: 'Mint Cream',\n mistyrose: 'Misty Rose',\n navajowhite: 'Navajo White',\n oldlace: 'Old Lace',\n olivedrab: 'Olive Drab',\n orangered: 'Orange Red',\n palegoldenrod: 'Pale Goldenrod',\n palegreen: 'Pale Green',\n paleturquoise: 'Pale Turquoise',\n palevioletred: 'Pale Violet Red',\n papayawhip: 'Papaya Whip',\n peachpuff: 'Peach Puff',\n powderblue: 'Powder Blue',\n rosybrown: 'Rosy Brown',\n royalblue: 'Royal Blue',\n saddlebrown: 'Saddle Brown',\n sandybrown: 'Sandy Brown',\n seagreen: 'Sea Green',\n skyblue: 'Sky Blue',\n slateblue: 'Slate Blue',\n slategray: 'Slate Gray',\n slategrey: 'Slate Grey',\n springgreen: 'Spring Green',\n steelblue: 'Steel Blue',\n whitesmoke: 'White Smoke',\n yellowgreen: 'Yellow Green',\n };\n\n const lowerName = name.toLowerCase();\n if (specialCases[lowerName]) {\n return specialCases[lowerName];\n }\n\n // Default: just capitalize first letter\n return name.charAt(0).toUpperCase() + name.slice(1);\n}\n\n/**\n * Get the closest CSS color name for a hex color\n */\nexport function getColorName(hex: string): string {\n try {\n const color = new Color(hex);\n const oklch = color.to('oklch');\n const hue = oklch.coords[2] || 0;\n\n if (hue < 30 || hue >= 330) return 'Red';\n if (hue < 60) return 'Orange';\n if (hue < 90) return 'Yellow';\n if (hue < 150) return 'Green';\n if (hue < 210) return 'Cyan';\n if (hue < 270) return 'Blue';\n if (hue < 330) return 'Purple';\n return 'Unknown';\n } catch {\n return 'Unknown';\n }\n}\n\n/**\n * Get color name with hue value\n */\nexport function getColorNameWithHue(hex: string): string {\n try {\n const color = new Color(hex);\n const oklch = color.to('oklch');\n const hue = oklch.coords[2] || 0;\n const roundedHue = Math.round(hue / 10) * 10;\n const name = getColorName(hex);\n return `${name} ${roundedHue}`;\n } catch {\n return 'Unknown';\n }\n}\n\n// Color harmony definitions\nexport const HARMONY_TYPES = [\n 'single',\n 'analogous',\n 'triad',\n 'complementary',\n 'split-complementary',\n 'square',\n 'compound',\n] as const;\nexport type HarmonyType = (typeof HARMONY_TYPES)[number];\n\nexport interface HarmonyDefinition {\n label: string;\n offsets: number[];\n primaryIndex: number;\n}\n\nexport const HARMONY_DEFINITIONS: Record<HarmonyType, HarmonyDefinition> = {\n single: {\n label: 'Single',\n offsets: [0],\n primaryIndex: 0,\n },\n analogous: {\n label: 'Analogous',\n offsets: [-30, 0, 30],\n primaryIndex: 1,\n },\n triad: {\n label: 'Triad',\n offsets: [0, 120, 240],\n primaryIndex: 0,\n },\n complementary: {\n label: 'Complementary',\n offsets: [0, 180],\n primaryIndex: 0,\n },\n 'split-complementary': {\n label: 'Split Complementary',\n offsets: [0, 150, 210],\n primaryIndex: 0,\n },\n square: {\n label: 'Square',\n offsets: [0, 90, 180, 270],\n primaryIndex: 0,\n },\n compound: {\n label: 'Compound',\n offsets: [-30, 0, 180, 210],\n primaryIndex: 1,\n },\n};\n\n/**\n * The shared lightness ladder every ramp is built on (lightest → darkest).\n *\n * Fixed, NOT seed-derived. Two hues at the same step have to read equally light,\n * otherwise one contrast table cannot serve every hue and a `muted` variant means\n * something different depending on which role you ask. Only chroma and hue vary\n * between ramps.\n *\n * The previous engine transposed this curve onto each seed, which let relative\n * luminance at step 300 range from 0.253 (rust) to 0.384 (amber) across the\n * shipped palette — the drift this replaces.\n *\n * Anchored steps are the one deliberate exception: see `generateOklchPalette`.\n */\nexport const LIGHTNESS_LADDER: Record<StepName, number> = {\n 50: 0.98,\n 100: 0.95,\n 200: 0.9,\n 300: 0.83,\n 400: 0.74,\n 500: 0.65,\n 600: 0.54,\n 700: 0.47,\n 800: 0.38,\n 900: 0.29,\n 950: 0.21,\n};\n\n/**\n * Chroma a ramp decays *towards* beyond its outermost anchors, so the near-white\n * and near-black ends keep a whisper of the hue instead of going flat grey. The\n * dark end carries slightly more because chroma reads weaker against black.\n *\n * It is a CEILING, not a target — `Math.min(ENDPOINT_CHROMA.x, anchor.c)`. That\n * distinction is the whole reason a neutral is authorable. The interpolation\n * factor reaches exactly 1 at steps 50 and 950 for every anchor position, so as a\n * target it made the endpoints these constants *unconditionally*: seeds at chroma\n * 0.001, 0.002, 0.05 and 0.2 all produced a byte-identical step 50. A brand\n * wanting plain white with grey panels had no seed that worked, and chroma 0 was\n * worst of all — colorjs returns NaN hue for a true achromatic colour, which\n * `hexToOklch` collapses to 0, so the \"neutral\" came out pink.\n *\n * As a ceiling, a low-chroma seed simply stays low and a chroma-0 seed stays 0 at\n * every unanchored step, which makes the NaN-hue collapse invisible rather than\n * something `hexToOklch` has to solve (its `|| 0` is load-bearing for\n * `getColorName`).\n */\nexport const ENDPOINT_CHROMA = { light: 0.008, dark: 0.015 } as const;\n\ninterface OklchColor {\n l: number;\n c: number;\n h: number;\n}\n\n/**\n * Parses an OKLCH CSS string into numerical components.\n * @param oklchString - e.g., 'oklch(50% 0.15 270)'\n * @returns Lightness (0-1), Chroma (0-~0.37), Hue (0-360)\n */\nexport function parseOklch(oklchString: string): OklchColor {\n const parts = oklchString.match(/oklch\\(([^ ]+) ([^ ]+) ([^ ]+)\\)/);\n if (!parts) throw new Error('Invalid OKLCH string format.');\n\n const [, lRaw = '', cRaw = '', hRaw = ''] = parts;\n const l = parseFloat(lRaw) / (lRaw.includes('%') ? 100 : 1);\n const c = parseFloat(cRaw);\n const h = parseFloat(hRaw);\n\n return { l, c, h };\n}\n\n/**\n * Linearly interpolates a value between a start and end point.\n */\nfunction lerp(start: number, end: number, factor: number): number {\n return start + factor * (end - start);\n}\n\n/**\n * Interpolate hue the short way round the wheel. A ramp anchored at 350° and 10°\n * spans 20°, not 340° — the naive lerp sent it the long way through cyan.\n */\nfunction lerpHue(start: number, end: number, factor: number): number {\n const delta = ((((end - start) % 360) + 540) % 360) - 180;\n return (start + delta * factor + 360) % 360;\n}\n\n/**\n * The ladder step whose lightness is closest to `lightness` — i.e. where a\n * supplied colour naturally belongs.\n */\nexport function assignStepByLightness(lightness: number): StepName {\n let closestStep: StepName = 500;\n let minDiff = Math.abs(lightness - LIGHTNESS_LADDER[500]);\n\n for (const step of STEP_NAMES) {\n const diff = Math.abs(lightness - LIGHTNESS_LADDER[step]);\n if (diff < minDiff) {\n minDiff = diff;\n closestStep = step;\n }\n }\n\n return closestStep;\n}\n\n/**\n * How far an anchored colour sits from its step's ladder lightness.\n *\n * The generator surfaces this as a warning: a large deviation is legal (the\n * caller asked for that exact colour) but it means the hue will read heavier or\n * lighter than its siblings at that step, which is worth knowing rather than\n * discovering later.\n */\nexport function ladderDeviation(step: StepName, lightness: number): number {\n return lightness - LIGHTNESS_LADDER[step];\n}\n\n/** Absolute chroma ceiling — beyond this nothing survives gamut mapping anyway. */\nconst MAX_CHROMA = 0.37;\n\n/**\n * Build a complete 11-step OKLCH ramp from one or more anchor colours.\n *\n * **Ladder-first with exact anchors.** Every anchor is reproduced *verbatim* at\n * its step; every other step takes its lightness from `LIGHTNESS_LADDER`, with\n * chroma and hue interpolated between the flanking anchors and decayed toward\n * `ENDPOINT_CHROMA` beyond the outermost ones.\n *\n * The consequence is the point: a client's brand hex survives byte-for-byte,\n * while the other ten steps stay directly comparable to every other hue. The\n * deviation from the ladder is bounded and *local to anchored steps* — unlike\n * the previous engine, which warped the whole ramp to fit its anchors so every\n * step drifted.\n *\n * Chroma may come out beyond the sRGB gamut here; that is deliberate.\n * `oklchStringToHex` gamut-maps with the CSS algorithm, which reduces chroma\n * while holding lightness, so the ladder survives the conversion.\n */\nexport function generateOklchPalette(\n input: string | string[] | Record<string, string>,\n): Record<StepName, string> {\n let anchors: Record<number, string> = {};\n\n if (typeof input === 'string') {\n anchors[assignStepByLightness(parseOklch(input).l)] = input;\n } else if (Array.isArray(input)) {\n for (const colorStr of input) {\n anchors[assignStepByLightness(parseOklch(colorStr).l)] = colorStr;\n }\n } else if (typeof input === 'object' && input !== null) {\n anchors = { ...input };\n } else {\n throw new Error(\n 'Input must be a color string, array of colors, or object with step assignments',\n );\n }\n\n const parsedAnchors: Record<number, OklchColor> = {};\n for (const [key, value] of Object.entries(anchors)) {\n parsedAnchors[Number(key)] = parseOklch(value);\n }\n\n const anchorSteps = Object.keys(parsedAnchors)\n .map(Number)\n .sort((a, b) => a - b) as StepName[];\n\n // Interpolate across step *index*, not the numeric label: the labels aren't\n // evenly spaced (50→100 is a smaller jump than 100→200), so lerping on them\n // would bunch the ramp up at the light end.\n const idx = (step: number) => STEP_NAMES.indexOf(step as StepName);\n const lastIdx = STEP_NAMES.length - 1;\n\n const palette: Record<number, string> = {};\n\n for (const step of STEP_NAMES) {\n // An anchor is the caller's exact colour. Emit it untouched.\n if (parsedAnchors[step]) {\n palette[step] = anchors[step] as string;\n continue;\n }\n\n // `lighter` is the nearest anchor with a smaller step (50 is lightest);\n // `darker` the nearest with a larger one.\n const lighter = [...anchorSteps].reverse().find((s) => s < step);\n const darker = anchorSteps.find((s) => s > step);\n\n let chroma: number;\n let hue: number;\n\n if (lighter !== undefined && darker !== undefined) {\n const a = parsedAnchors[lighter] as OklchColor;\n const b = parsedAnchors[darker] as OklchColor;\n const factor = (idx(step) - idx(lighter)) / (idx(darker) - idx(lighter));\n chroma = lerp(a.c, b.c, factor);\n hue = lerpHue(a.h, b.h, factor);\n } else if (lighter !== undefined) {\n // Past the darkest anchor — fade toward the tinted near-black end.\n const a = parsedAnchors[lighter] as OklchColor;\n const factor = (idx(step) - idx(lighter)) / (lastIdx - idx(lighter));\n chroma = lerp(a.c, Math.min(ENDPOINT_CHROMA.dark, a.c), factor);\n hue = a.h;\n } else if (darker !== undefined) {\n // Past the lightest anchor — fade toward the tinted near-white end.\n const b = parsedAnchors[darker] as OklchColor;\n const factor = (idx(darker) - idx(step)) / idx(darker);\n chroma = lerp(b.c, Math.min(ENDPOINT_CHROMA.light, b.c), factor);\n hue = b.h;\n } else {\n chroma = 0.1;\n hue = 0;\n }\n\n const lightness = LIGHTNESS_LADDER[step];\n const finalL = (lightness * 100).toFixed(2) + '%';\n const finalC = Math.min(chroma, MAX_CHROMA).toFixed(4);\n const finalH = hue.toFixed(2);\n\n palette[step] = `oklch(${finalL} ${finalC} ${finalH})`;\n }\n\n return palette;\n}\n\n// ── Contrast + endpoints (for the functional-token layer) ────────────────────\n\n/** APCA lightness-contrast (Lc) magnitude between a foreground and background. */\nexport function contrastLc(fg: string, bg: string): number {\n return Math.abs(new Color(bg).contrast(fg, 'APCA'));\n}\n\n/**\n * Pick a tinted near-white or near-black foreground for best contrast on `bg`\n * (a whisper of the background's hue mixed into off-white/off-black).\n */\nexport function pickOn(bg: string, hue?: number): string {\n const h = hue ?? hexToOklch(bg).h;\n const white = oklchToHex({ l: 0.98, c: 0.01, h });\n const black = oklchToHex({ l: 0.16, c: 0.02, h });\n return contrastLc(white, bg) >= contrastLc(black, bg) ? white : black;\n}\n\n/**\n * The tinted off-white / off-black endpoints for a hue — white/black with a\n * whisper of the hue mixed in. These are the text/background tints every ramp\n * needs (and the one exception strict brand kits allow).\n *\n * Derived from `LIGHTNESS_LADDER` and `ENDPOINT_CHROMA` rather than its own\n * literals, so a strict tone kit's endpoints land on the same ladder rungs a\n * generated ramp would have used. This is the single definition — callers must\n * not hand-write their own near-white/near-black.\n */\nexport function tintedEndpoints(hue: number, chroma?: number): { light: string; dark: string } {\n return {\n light: oklchToHex({\n l: LIGHTNESS_LADDER[50],\n c: Math.min(chroma ?? ENDPOINT_CHROMA.light, 0.02),\n h: hue,\n }),\n dark: oklchToHex({\n l: LIGHTNESS_LADDER[950],\n c: Math.min((chroma ?? ENDPOINT_CHROMA.dark) * 1.5, 0.03),\n h: hue,\n }),\n };\n}\n","/**\n * Color harmony strategies for generating complementary colors\n */\n\nexport type HarmonyStrategy =\n | 'complement'\n | 'analogous-plus'\n | 'analogous-minus'\n | 'triadic-plus'\n | 'triadic-minus'\n | 'split-plus'\n | 'split-minus'\n | 'tetradic-plus'\n | 'tetradic-minus';\n\nexport interface HarmonyOption {\n id: HarmonyStrategy;\n label: string;\n description: string;\n hueShift: number;\n}\n\nexport const HARMONY_STRATEGIES: HarmonyOption[] = [\n {\n id: 'complement',\n label: 'Complement',\n description: 'Opposite on color wheel (high contrast)',\n hueShift: 180,\n },\n {\n id: 'analogous-plus',\n label: 'Analogous+',\n description: 'Adjacent colors (harmonious)',\n hueShift: 30,\n },\n {\n id: 'analogous-minus',\n label: 'Analogous-',\n description: 'Adjacent colors (harmonious)',\n hueShift: -30,\n },\n {\n id: 'triadic-plus',\n label: 'Triadic+',\n description: 'Evenly spaced (balanced)',\n hueShift: 120,\n },\n {\n id: 'triadic-minus',\n label: 'Triadic-',\n description: 'Evenly spaced (balanced)',\n hueShift: -120,\n },\n {\n id: 'split-plus',\n label: 'Split Complement+',\n description: 'Near opposite (softer contrast)',\n hueShift: 150,\n },\n {\n id: 'split-minus',\n label: 'Split Complement-',\n description: 'Near opposite (softer contrast)',\n hueShift: -150,\n },\n {\n id: 'tetradic-plus',\n label: 'Tetradic+',\n description: 'Square spacing (rich palette)',\n hueShift: 90,\n },\n {\n id: 'tetradic-minus',\n label: 'Tetradic-',\n description: 'Square spacing (rich palette)',\n hueShift: -90,\n },\n];\n\n/**\n * Applies a harmony strategy to a hue value\n */\nexport function applyHarmonyStrategy(baseHue: number, strategy: HarmonyStrategy): number {\n const harmonyOption = HARMONY_STRATEGIES.find((h) => h.id === strategy);\n if (!harmonyOption) return baseHue;\n\n let newHue = baseHue + harmonyOption.hueShift;\n\n // Normalize to 0-360 range\n while (newHue < 0) newHue += 360;\n while (newHue >= 360) newHue -= 360;\n\n return newHue;\n}\n\n/**\n * Gets all harmony suggestions for a given base hue\n */\nexport function getHarmonySuggestions(\n baseHue: number,\n): Array<{ strategy: HarmonyStrategy; hue: number; label: string; description: string }> {\n return HARMONY_STRATEGIES.map((strategy) => ({\n strategy: strategy.id,\n hue: applyHarmonyStrategy(baseHue, strategy.id),\n label: strategy.label,\n description: strategy.description,\n }));\n}\n\n/**\n * Default functional color hues (if user doesn't specify)\n */\nexport const DEFAULT_FUNCTIONAL_HUES = {\n success: 142, // Green\n warning: 38, // Orange/Amber\n error: 0, // Red\n info: 200, // Blue\n} as const;\n\n/**\n * Suggests a functional color hue based on existing palette to maintain harmony\n */\nexport function suggestFunctionalColorHue(\n type: keyof typeof DEFAULT_FUNCTIONAL_HUES,\n existingHues: number[],\n): number {\n const defaultHue = DEFAULT_FUNCTIONAL_HUES[type];\n\n if (existingHues.length === 0) {\n return defaultHue;\n }\n\n // Find the closest existing hue and adjust slightly to maintain harmony\n const avgHue = existingHues.reduce((sum, h) => sum + h, 0) / existingHues.length;\n\n // Rotate the default hue to be more in line with the palette's color temperature\n const hueShift = avgHue - 200; // Assuming 200 is neutral blue\n let adjustedHue = defaultHue + hueShift * 0.3; // 30% influence\n\n // Normalize\n while (adjustedHue < 0) adjustedHue += 360;\n while (adjustedHue >= 360) adjustedHue -= 360;\n\n return adjustedHue;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["OKLCH_Space","sRGB_Space","P3_Space"],"sources":["../../src/color/colors.ts","../../src/color/color-harmony.ts"],"sourcesContent":["import Color from 'colorjs.io';\nimport {\n OKLCH as OKLCH_Space,\n sRGB as sRGB_Space,\n P3 as P3_Space,\n ColorSpace,\n to,\n toGamutCSS,\n clone,\n serialize,\n type PlainColorObject,\n} from 'colorjs.io/fn';\n\nColorSpace.register(OKLCH_Space);\nColorSpace.register(sRGB_Space);\nColorSpace.register(P3_Space);\n\nexport interface RgbResult {\n r: number;\n g: number;\n b: number;\n inGamut: boolean;\n /** Max channel overshoot beyond [0,1] before clamping. 0 when in gamut. */\n gamutDistance: number;\n}\n\n/**\n * Convert OKLCh to sRGB, returning 0-255 clamped values with gamut flag.\n * Fast path for per-pixel canvas rendering (no gamut mapping, just clamp).\n */\nexport function oklchToSrgb(l: number, c: number, h: number): RgbResult {\n const col: PlainColorObject = { space: OKLCH_Space, coords: [l, c, h], alpha: 1 };\n const rgb = to(col, sRGB_Space);\n const [r, g, b] = rgb.coords;\n const inGamut = r >= 0 && r <= 1 && g >= 0 && g <= 1 && b >= 0 && b <= 1;\n const gamutDistance = inGamut ? 0 : Math.max(-r, r - 1, -g, g - 1, -b, b - 1, 0);\n return {\n r: Math.max(0, Math.min(255, Math.round(r * 255))),\n g: Math.max(0, Math.min(255, Math.round(g * 255))),\n b: Math.max(0, Math.min(255, Math.round(b * 255))),\n inGamut,\n gamutDistance,\n };\n}\n\n/**\n * Convert OKLCh to Display P3, returning 0-255 clamped values with gamut flag.\n * Fast path for per-pixel canvas rendering on P3 displays.\n */\nexport function oklchToP3(l: number, c: number, h: number): RgbResult {\n const col: PlainColorObject = { space: OKLCH_Space, coords: [l, c, h], alpha: 1 };\n const rgb = to(col, P3_Space);\n const [r, g, b] = rgb.coords;\n const inGamut = r >= 0 && r <= 1 && g >= 0 && g <= 1 && b >= 0 && b <= 1;\n const gamutDistance = inGamut ? 0 : Math.max(-r, r - 1, -g, g - 1, -b, b - 1, 0);\n return {\n r: Math.max(0, Math.min(255, Math.round(r * 255))),\n g: Math.max(0, Math.min(255, Math.round(g * 255))),\n b: Math.max(0, Math.min(255, Math.round(b * 255))),\n inGamut,\n gamutDistance,\n };\n}\n\n/**\n * Gamut-map an OKLCh color using the CSS gamut mapping algorithm, return hex.\n * Slower than oklchToSrgb/oklchToP3 (uses iterative reduction), use for single colors only.\n */\nexport function gamutMapOklchToHex(\n l: number,\n c: number,\n h: number,\n space: 'srgb' | 'p3' = 'srgb',\n): string {\n const col: PlainColorObject = { space: OKLCH_Space, coords: [l, c, h], alpha: 1 };\n const targetSpace = space === 'p3' ? P3_Space : sRGB_Space;\n const mapped = toGamutCSS(clone(col), { space: targetSpace });\n const rgb = to(mapped, sRGB_Space);\n return serialize(rgb, { format: 'hex' });\n}\n\n// Standard 11-step scale - will be transposed based on input anchors\nexport const STEP_NAMES = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950] as const;\nexport type StepName = (typeof STEP_NAMES)[number];\n\nexport const COLOR_GROUPS = [\n 'neutral',\n 'brand',\n 'primary',\n 'accent',\n 'complement',\n 'success',\n 'warning',\n 'error',\n 'info',\n] as const;\nexport type ColorGroup = (typeof COLOR_GROUPS)[number];\n\n/**\n * Convert hex color to OKLCH components\n */\nexport function hexToOklch(hex: string): { l: number; c: number; h: number } {\n const color = new Color(hex);\n const oklch = color.to('oklch');\n return {\n l: oklch.coords[0],\n c: oklch.coords[1],\n h: oklch.coords[2] || 0,\n };\n}\n\nexport function oklchToHex(oklch: { l: number; c: number; h: number }): string {\n const color = new Color('oklch', [oklch.l, oklch.c, oklch.h]);\n const srgb = color.to('srgb');\n if (!srgb.inGamut()) {\n srgb.toGamut({ method: 'css' });\n }\n return srgb.toString({ format: 'hex' });\n}\n\n/**\n * Convert OKLCH CSS string to hex color\n * @example oklchStringToHex(\"oklch(50% 0.15 270)\") => \"#8b5cf6\"\n */\nexport function oklchStringToHex(oklchString: string): string {\n try {\n const color = new Color(oklchString);\n const srgb = color.to('srgb');\n if (!srgb.inGamut()) {\n srgb.toGamut({ method: 'css' });\n }\n return srgb.toString({ format: 'hex' });\n } catch {\n return '#808080';\n }\n}\n\n/**\n * Format a color name by separating compound words\n * Examples: \"mediumseagreen\" -> \"Medium Sea Green\", \"darkblue\" -> \"Dark Blue\"\n */\nexport function formatColorName(name: string): string {\n if (!name) return 'Unknown';\n\n const specialCases: Record<string, string> = {\n aliceblue: 'Alice Blue',\n antiquewhite: 'Antique White',\n blanchedalmond: 'Blanched Almond',\n blueviolet: 'Blue Violet',\n burlywood: 'Burly Wood',\n cadetblue: 'Cadet Blue',\n cornflowerblue: 'Cornflower Blue',\n darkblue: 'Dark Blue',\n darkcyan: 'Dark Cyan',\n darkgoldenrod: 'Dark Goldenrod',\n darkgray: 'Dark Gray',\n darkgreen: 'Dark Green',\n darkgrey: 'Dark Grey',\n darkkhaki: 'Dark Khaki',\n darkmagenta: 'Dark Magenta',\n darkolivegreen: 'Dark Olive Green',\n darkorange: 'Dark Orange',\n darkorchid: 'Dark Orchid',\n darkred: 'Dark Red',\n darksalmon: 'Dark Salmon',\n darkseagreen: 'Dark Sea Green',\n darkslateblue: 'Dark Slate Blue',\n darkslategray: 'Dark Slate Gray',\n darkslategrey: 'Dark Slate Grey',\n darkturquoise: 'Dark Turquoise',\n darkviolet: 'Dark Violet',\n deeppink: 'Deep Pink',\n deepskyblue: 'Deep Sky Blue',\n dimgray: 'Dim Gray',\n dimgrey: 'Dim Grey',\n dodgerblue: 'Dodger Blue',\n floralwhite: 'Floral White',\n forestgreen: 'Forest Green',\n ghostwhite: 'Ghost White',\n greenyellow: 'Green Yellow',\n hotpink: 'Hot Pink',\n indianred: 'Indian Red',\n lavenderblush: 'Lavender Blush',\n lawngreen: 'Lawn Green',\n lemonchiffon: 'Lemon Chiffon',\n lightblue: 'Light Blue',\n lightcoral: 'Light Coral',\n lightcyan: 'Light Cyan',\n lightgoldenrodyellow: 'Light Goldenrod Yellow',\n lightgray: 'Light Gray',\n lightgreen: 'Light Green',\n lightgrey: 'Light Grey',\n lightpink: 'Light Pink',\n lightsalmon: 'Light Salmon',\n lightseagreen: 'Light Sea Green',\n lightskyblue: 'Light Sky Blue',\n lightslategray: 'Light Slate Gray',\n lightslategrey: 'Light Slate Grey',\n lightsteelblue: 'Light Steel Blue',\n lightyellow: 'Light Yellow',\n limegreen: 'Lime Green',\n mediumaquamarine: 'Medium Aquamarine',\n mediumblue: 'Medium Blue',\n mediumorchid: 'Medium Orchid',\n mediumpurple: 'Medium Purple',\n mediumseagreen: 'Medium Sea Green',\n mediumslateblue: 'Medium Slate Blue',\n mediumspringgreen: 'Medium Spring Green',\n mediumturquoise: 'Medium Turquoise',\n mediumvioletred: 'Medium Violet Red',\n midnightblue: 'Midnight Blue',\n mintcream: 'Mint Cream',\n mistyrose: 'Misty Rose',\n navajowhite: 'Navajo White',\n oldlace: 'Old Lace',\n olivedrab: 'Olive Drab',\n orangered: 'Orange Red',\n palegoldenrod: 'Pale Goldenrod',\n palegreen: 'Pale Green',\n paleturquoise: 'Pale Turquoise',\n palevioletred: 'Pale Violet Red',\n papayawhip: 'Papaya Whip',\n peachpuff: 'Peach Puff',\n powderblue: 'Powder Blue',\n rosybrown: 'Rosy Brown',\n royalblue: 'Royal Blue',\n saddlebrown: 'Saddle Brown',\n sandybrown: 'Sandy Brown',\n seagreen: 'Sea Green',\n skyblue: 'Sky Blue',\n slateblue: 'Slate Blue',\n slategray: 'Slate Gray',\n slategrey: 'Slate Grey',\n springgreen: 'Spring Green',\n steelblue: 'Steel Blue',\n whitesmoke: 'White Smoke',\n yellowgreen: 'Yellow Green',\n };\n\n const lowerName = name.toLowerCase();\n if (specialCases[lowerName]) {\n return specialCases[lowerName];\n }\n\n // Default: just capitalize first letter\n return name.charAt(0).toUpperCase() + name.slice(1);\n}\n\n/**\n * Get the closest CSS color name for a hex color\n */\nexport function getColorName(hex: string): string {\n try {\n const color = new Color(hex);\n const oklch = color.to('oklch');\n const hue = oklch.coords[2] || 0;\n\n if (hue < 30 || hue >= 330) return 'Red';\n if (hue < 60) return 'Orange';\n if (hue < 90) return 'Yellow';\n if (hue < 150) return 'Green';\n if (hue < 210) return 'Cyan';\n if (hue < 270) return 'Blue';\n if (hue < 330) return 'Purple';\n return 'Unknown';\n } catch {\n return 'Unknown';\n }\n}\n\n/**\n * Get color name with hue value\n */\nexport function getColorNameWithHue(hex: string): string {\n try {\n const color = new Color(hex);\n const oklch = color.to('oklch');\n const hue = oklch.coords[2] || 0;\n const roundedHue = Math.round(hue / 10) * 10;\n const name = getColorName(hex);\n return `${name} ${roundedHue}`;\n } catch {\n return 'Unknown';\n }\n}\n\n// Color harmony definitions\nexport const HARMONY_TYPES = [\n 'single',\n 'analogous',\n 'triad',\n 'complementary',\n 'split-complementary',\n 'square',\n 'compound',\n] as const;\nexport type HarmonyType = (typeof HARMONY_TYPES)[number];\n\nexport interface HarmonyDefinition {\n label: string;\n offsets: number[];\n primaryIndex: number;\n}\n\nexport const HARMONY_DEFINITIONS: Record<HarmonyType, HarmonyDefinition> = {\n single: {\n label: 'Single',\n offsets: [0],\n primaryIndex: 0,\n },\n analogous: {\n label: 'Analogous',\n offsets: [-30, 0, 30],\n primaryIndex: 1,\n },\n triad: {\n label: 'Triad',\n offsets: [0, 120, 240],\n primaryIndex: 0,\n },\n complementary: {\n label: 'Complementary',\n offsets: [0, 180],\n primaryIndex: 0,\n },\n 'split-complementary': {\n label: 'Split Complementary',\n offsets: [0, 150, 210],\n primaryIndex: 0,\n },\n square: {\n label: 'Square',\n offsets: [0, 90, 180, 270],\n primaryIndex: 0,\n },\n compound: {\n label: 'Compound',\n offsets: [-30, 0, 180, 210],\n primaryIndex: 1,\n },\n};\n\n/**\n * The shared lightness ladder every ramp is built on (lightest → darkest).\n *\n * Fixed, NOT seed-derived. Two hues at the same step have to read equally light,\n * otherwise one contrast table cannot serve every hue and a `muted` variant means\n * something different depending on which role you ask. Only chroma and hue vary\n * between ramps.\n *\n * The previous engine transposed this curve onto each seed, which let relative\n * luminance at step 300 range from 0.253 (rust) to 0.384 (amber) across the\n * shipped palette — the drift this replaces.\n *\n * Anchored steps are the one deliberate exception: see `generateOklchPalette`.\n */\nexport const LIGHTNESS_LADDER: Record<StepName, number> = {\n 50: 0.98,\n 100: 0.95,\n 200: 0.9,\n 300: 0.83,\n 400: 0.74,\n 500: 0.65,\n 600: 0.54,\n 700: 0.47,\n 800: 0.38,\n 900: 0.29,\n 950: 0.21,\n};\n\n/**\n * Chroma a ramp decays *towards* beyond its outermost anchors, so the near-white\n * and near-black ends keep a whisper of the hue instead of going flat grey. The\n * dark end carries slightly more because chroma reads weaker against black.\n *\n * It is a CEILING, not a target — `Math.min(ENDPOINT_CHROMA.x, anchor.c)`. That\n * distinction is the whole reason a neutral is authorable. The interpolation\n * factor reaches exactly 1 at steps 50 and 950 for every anchor position, so as a\n * target it made the endpoints these constants *unconditionally*: seeds at chroma\n * 0.001, 0.002, 0.05 and 0.2 all produced a byte-identical step 50. A brand\n * wanting plain white with grey panels had no seed that worked, and chroma 0 was\n * worst of all — colorjs returns NaN hue for a true achromatic colour, which\n * `hexToOklch` collapses to 0, so the \"neutral\" came out pink.\n *\n * As a ceiling, a low-chroma seed simply stays low and a chroma-0 seed stays 0 at\n * every unanchored step, which makes the NaN-hue collapse invisible rather than\n * something `hexToOklch` has to solve (its `|| 0` is load-bearing for\n * `getColorName`).\n */\nexport const ENDPOINT_CHROMA = { light: 0.008, dark: 0.015 } as const;\n\ninterface OklchColor {\n l: number;\n c: number;\n h: number;\n}\n\n/**\n * Parses an OKLCH CSS string into numerical components.\n * @param oklchString - e.g., 'oklch(50% 0.15 270)'\n * @returns Lightness (0-1), Chroma (0-~0.37), Hue (0-360)\n */\nexport function parseOklch(oklchString: string): OklchColor {\n const parts = oklchString.match(/oklch\\(([^ ]+) ([^ ]+) ([^ ]+)\\)/);\n if (!parts) throw new Error('Invalid OKLCH string format.');\n\n const [, lRaw = '', cRaw = '', hRaw = ''] = parts;\n const l = parseFloat(lRaw) / (lRaw.includes('%') ? 100 : 1);\n const c = parseFloat(cRaw);\n const h = parseFloat(hRaw);\n\n return { l, c, h };\n}\n\n/**\n * Linearly interpolates a value between a start and end point.\n */\nfunction lerp(start: number, end: number, factor: number): number {\n return start + factor * (end - start);\n}\n\n/**\n * Interpolate hue the short way round the wheel. A ramp anchored at 350° and 10°\n * spans 20°, not 340° — the naive lerp sent it the long way through cyan.\n */\nfunction lerpHue(start: number, end: number, factor: number): number {\n const delta = ((((end - start) % 360) + 540) % 360) - 180;\n return (start + delta * factor + 360) % 360;\n}\n\n/**\n * The ladder step whose lightness is closest to `lightness` — i.e. where a\n * supplied colour naturally belongs.\n */\nexport function assignStepByLightness(lightness: number): StepName {\n let closestStep: StepName = 500;\n let minDiff = Math.abs(lightness - LIGHTNESS_LADDER[500]);\n\n for (const step of STEP_NAMES) {\n const diff = Math.abs(lightness - LIGHTNESS_LADDER[step]);\n if (diff < minDiff) {\n minDiff = diff;\n closestStep = step;\n }\n }\n\n return closestStep;\n}\n\n/**\n * How far an anchored colour sits from its step's ladder lightness.\n *\n * The generator surfaces this as a warning: a large deviation is legal (the\n * caller asked for that exact colour) but it means the hue will read heavier or\n * lighter than its siblings at that step, which is worth knowing rather than\n * discovering later.\n */\nexport function ladderDeviation(step: StepName, lightness: number): number {\n return lightness - LIGHTNESS_LADDER[step];\n}\n\n/** Absolute chroma ceiling — beyond this nothing survives gamut mapping anyway. */\nconst MAX_CHROMA = 0.37;\n\n/**\n * Build a complete 11-step OKLCH ramp from one or more anchor colours.\n *\n * **Ladder-first with exact anchors.** Every anchor is reproduced *verbatim* at\n * its step; every other step takes its lightness from `LIGHTNESS_LADDER`, with\n * chroma and hue interpolated between the flanking anchors and decayed toward\n * `ENDPOINT_CHROMA` beyond the outermost ones.\n *\n * The consequence is the point: a client's brand hex survives byte-for-byte,\n * while the other ten steps stay directly comparable to every other hue. The\n * deviation from the ladder is bounded and *local to anchored steps* — unlike\n * the previous engine, which warped the whole ramp to fit its anchors so every\n * step drifted.\n *\n * Chroma may come out beyond the sRGB gamut here; that is deliberate.\n * `oklchStringToHex` gamut-maps with the CSS algorithm, which reduces chroma\n * while holding lightness, so the ladder survives the conversion.\n */\nexport function generateOklchPalette(\n input: string | string[] | Record<string, string>,\n): Record<StepName, string> {\n let anchors: Record<number, string> = {};\n\n if (typeof input === 'string') {\n anchors[assignStepByLightness(parseOklch(input).l)] = input;\n } else if (Array.isArray(input)) {\n for (const colorStr of input) {\n anchors[assignStepByLightness(parseOklch(colorStr).l)] = colorStr;\n }\n } else if (typeof input === 'object' && input !== null) {\n anchors = { ...input };\n } else {\n throw new Error(\n 'Input must be a color string, array of colors, or object with step assignments',\n );\n }\n\n const parsedAnchors: Record<number, OklchColor> = {};\n for (const [key, value] of Object.entries(anchors)) {\n parsedAnchors[Number(key)] = parseOklch(value);\n }\n\n const anchorSteps = Object.keys(parsedAnchors)\n .map(Number)\n .sort((a, b) => a - b) as StepName[];\n\n // Interpolate across step *index*, not the numeric label: the labels aren't\n // evenly spaced (50→100 is a smaller jump than 100→200), so lerping on them\n // would bunch the ramp up at the light end.\n const idx = (step: number) => STEP_NAMES.indexOf(step as StepName);\n const lastIdx = STEP_NAMES.length - 1;\n\n const palette: Record<number, string> = {};\n\n for (const step of STEP_NAMES) {\n // An anchor is the caller's exact colour. Emit it untouched.\n if (parsedAnchors[step]) {\n palette[step] = anchors[step] as string;\n continue;\n }\n\n // `lighter` is the nearest anchor with a smaller step (50 is lightest);\n // `darker` the nearest with a larger one.\n const lighter = [...anchorSteps].reverse().find((s) => s < step);\n const darker = anchorSteps.find((s) => s > step);\n\n let chroma: number;\n let hue: number;\n\n if (lighter !== undefined && darker !== undefined) {\n const a = parsedAnchors[lighter] as OklchColor;\n const b = parsedAnchors[darker] as OklchColor;\n const factor = (idx(step) - idx(lighter)) / (idx(darker) - idx(lighter));\n chroma = lerp(a.c, b.c, factor);\n hue = lerpHue(a.h, b.h, factor);\n } else if (lighter !== undefined) {\n // Past the darkest anchor — fade toward the tinted near-black end.\n const a = parsedAnchors[lighter] as OklchColor;\n const factor = (idx(step) - idx(lighter)) / (lastIdx - idx(lighter));\n chroma = lerp(a.c, Math.min(ENDPOINT_CHROMA.dark, a.c), factor);\n hue = a.h;\n } else if (darker !== undefined) {\n // Past the lightest anchor — fade toward the tinted near-white end.\n const b = parsedAnchors[darker] as OklchColor;\n const factor = (idx(darker) - idx(step)) / idx(darker);\n chroma = lerp(b.c, Math.min(ENDPOINT_CHROMA.light, b.c), factor);\n hue = b.h;\n } else {\n chroma = 0.1;\n hue = 0;\n }\n\n const lightness = LIGHTNESS_LADDER[step];\n const finalL = (lightness * 100).toFixed(2) + '%';\n const finalC = Math.min(chroma, MAX_CHROMA).toFixed(4);\n const finalH = hue.toFixed(2);\n\n palette[step] = `oklch(${finalL} ${finalC} ${finalH})`;\n }\n\n return palette;\n}\n\n// ── Contrast + endpoints (for the functional-token layer) ────────────────────\n\n/** APCA lightness-contrast (Lc) magnitude between a foreground and background. */\nexport function contrastLc(fg: string, bg: string): number {\n return Math.abs(new Color(bg).contrast(fg, 'APCA'));\n}\n\n/**\n * Pick a tinted near-white or near-black foreground for best contrast on `bg`\n * (a whisper of the background's hue mixed into off-white/off-black).\n */\nexport function pickOn(bg: string, hue?: number): string {\n const h = hue ?? hexToOklch(bg).h;\n const white = oklchToHex({ l: 0.98, c: 0.01, h });\n const black = oklchToHex({ l: 0.16, c: 0.02, h });\n return contrastLc(white, bg) >= contrastLc(black, bg) ? white : black;\n}\n\n/**\n * The tinted off-white / off-black endpoints for a hue — white/black with a\n * whisper of the hue mixed in. These are the text/background tints every ramp\n * needs (and the one exception strict brand kits allow).\n *\n * Derived from `LIGHTNESS_LADDER` and `ENDPOINT_CHROMA` rather than its own\n * literals, so a strict tone kit's endpoints land on the same ladder rungs a\n * generated ramp would have used. This is the single definition — callers must\n * not hand-write their own near-white/near-black.\n */\nexport function tintedEndpoints(hue: number, chroma?: number): { light: string; dark: string } {\n return {\n light: oklchToHex({\n l: LIGHTNESS_LADDER[50],\n c: Math.min(chroma ?? ENDPOINT_CHROMA.light, 0.02),\n h: hue,\n }),\n dark: oklchToHex({\n l: LIGHTNESS_LADDER[950],\n c: Math.min((chroma ?? ENDPOINT_CHROMA.dark) * 1.5, 0.03),\n h: hue,\n }),\n };\n}\n","/**\n * Color harmony strategies for generating complementary colors\n */\n\nexport type HarmonyStrategy =\n | 'complement'\n | 'analogous-plus'\n | 'analogous-minus'\n | 'triadic-plus'\n | 'triadic-minus'\n | 'split-plus'\n | 'split-minus'\n | 'tetradic-plus'\n | 'tetradic-minus';\n\nexport interface HarmonyOption {\n id: HarmonyStrategy;\n label: string;\n description: string;\n hueShift: number;\n}\n\nexport const HARMONY_STRATEGIES: HarmonyOption[] = [\n {\n id: 'complement',\n label: 'Complement',\n description: 'Opposite on color wheel (high contrast)',\n hueShift: 180,\n },\n {\n id: 'analogous-plus',\n label: 'Analogous+',\n description: 'Adjacent colors (harmonious)',\n hueShift: 30,\n },\n {\n id: 'analogous-minus',\n label: 'Analogous-',\n description: 'Adjacent colors (harmonious)',\n hueShift: -30,\n },\n {\n id: 'triadic-plus',\n label: 'Triadic+',\n description: 'Evenly spaced (balanced)',\n hueShift: 120,\n },\n {\n id: 'triadic-minus',\n label: 'Triadic-',\n description: 'Evenly spaced (balanced)',\n hueShift: -120,\n },\n {\n id: 'split-plus',\n label: 'Split Complement+',\n description: 'Near opposite (softer contrast)',\n hueShift: 150,\n },\n {\n id: 'split-minus',\n label: 'Split Complement-',\n description: 'Near opposite (softer contrast)',\n hueShift: -150,\n },\n {\n id: 'tetradic-plus',\n label: 'Tetradic+',\n description: 'Square spacing (rich palette)',\n hueShift: 90,\n },\n {\n id: 'tetradic-minus',\n label: 'Tetradic-',\n description: 'Square spacing (rich palette)',\n hueShift: -90,\n },\n];\n\n/**\n * Applies a harmony strategy to a hue value\n */\nexport function applyHarmonyStrategy(baseHue: number, strategy: HarmonyStrategy): number {\n const harmonyOption = HARMONY_STRATEGIES.find((h) => h.id === strategy);\n if (!harmonyOption) return baseHue;\n\n let newHue = baseHue + harmonyOption.hueShift;\n\n // Normalize to 0-360 range\n while (newHue < 0) newHue += 360;\n while (newHue >= 360) newHue -= 360;\n\n return newHue;\n}\n\n/**\n * Gets all harmony suggestions for a given base hue\n */\nexport function getHarmonySuggestions(\n baseHue: number,\n): Array<{ strategy: HarmonyStrategy; hue: number; label: string; description: string }> {\n return HARMONY_STRATEGIES.map((strategy) => ({\n strategy: strategy.id,\n hue: applyHarmonyStrategy(baseHue, strategy.id),\n label: strategy.label,\n description: strategy.description,\n }));\n}\n\n/**\n * Default functional color hues (if user doesn't specify)\n */\nexport const DEFAULT_FUNCTIONAL_HUES = {\n success: 142, // Green\n warning: 38, // Orange/Amber\n error: 0, // Red\n info: 200, // Blue\n} as const;\n\n/**\n * Suggests a functional color hue based on existing palette to maintain harmony\n */\nexport function suggestFunctionalColorHue(\n type: keyof typeof DEFAULT_FUNCTIONAL_HUES,\n existingHues: number[],\n): number {\n const defaultHue = DEFAULT_FUNCTIONAL_HUES[type];\n\n if (existingHues.length === 0) {\n return defaultHue;\n }\n\n // Find the closest existing hue and adjust slightly to maintain harmony\n const avgHue = existingHues.reduce((sum, h) => sum + h, 0) / existingHues.length;\n\n // Rotate the default hue to be more in line with the palette's color temperature\n const hueShift = avgHue - 200; // Assuming 200 is neutral blue\n let adjustedHue = defaultHue + hueShift * 0.3; // 30% influence\n\n // Normalize\n while (adjustedHue < 0) adjustedHue += 360;\n while (adjustedHue >= 360) adjustedHue -= 360;\n\n return adjustedHue;\n}\n"],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -102,106 +102,6 @@ declare function toHtml<Tag extends string>(content: string | El<Tag>): string;
102
102
  /** Render an array of `ContentNode`s to an HTML string. */
103
103
  declare function nodesToHtml(nodes: ContentNode[], resolveText?: (value: Localizable) => string): string;
104
104
  //#endregion
105
- //#region src/schema/article.d.ts
106
- interface ArticleAuthor {
107
- name: string;
108
- url?: string;
109
- }
110
- interface ArticleGraphOptions {
111
- headline: string;
112
- description?: string;
113
- image?: string | string[];
114
- datePublished: string;
115
- dateModified?: string;
116
- author: ArticleAuthor | ArticleAuthor[];
117
- publisher?: {
118
- name: string;
119
- logo?: string;
120
- };
121
- mainEntityOfPage?: string;
122
- articleSection?: string;
123
- wordCount?: number;
124
- keywords?: string[];
125
- }
126
- /** Build a schema.org Article JSON-LD graph. */
127
- declare function articleGraph(options: ArticleGraphOptions): Record<string, unknown>;
128
- //#endregion
129
- //#region src/schema/breadcrumb.d.ts
130
- interface BreadcrumbItem {
131
- name: string;
132
- url: string;
133
- }
134
- interface BreadcrumbGraphOptions {
135
- items: BreadcrumbItem[];
136
- }
137
- /** Build a schema.org BreadcrumbList JSON-LD graph. */
138
- declare function breadcrumbGraph(options: BreadcrumbGraphOptions): Record<string, unknown>;
139
- //#endregion
140
- //#region src/schema/faq.d.ts
141
- interface FAQItem {
142
- question: string;
143
- answer: string;
144
- }
145
- interface FAQGraphOptions {
146
- items: FAQItem[];
147
- }
148
- /**
149
- * Build a schema.org FAQPage JSON-LD graph.
150
- *
151
- * NOTE: Google recommends FAQ markup only for authoritative government
152
- * and health sites. For other sites, consider using QAPage schema instead.
153
- */
154
- declare function faqGraph(options: FAQGraphOptions): Record<string, unknown>;
155
- //#endregion
156
- //#region src/schema/organization.d.ts
157
- interface OrganizationGraphOptions {
158
- name: string;
159
- url?: string;
160
- logo?: string;
161
- description?: string;
162
- email?: string;
163
- telephone?: string;
164
- address?: {
165
- streetAddress?: string;
166
- addressLocality?: string;
167
- addressRegion?: string;
168
- postalCode?: string;
169
- addressCountry?: string;
170
- };
171
- sameAs?: string[];
172
- foundingDate?: string;
173
- founders?: string[];
174
- numberOfEmployees?: number | {
175
- minValue: number;
176
- maxValue: number;
177
- };
178
- parentOrganization?: {
179
- name: string;
180
- url?: string;
181
- };
182
- subOrganization?: {
183
- name: string;
184
- url?: string;
185
- }[];
186
- contactPoint?: {
187
- type?: 'customer service' | 'technical support' | 'sales' | 'billing support' | 'reservations';
188
- telephone: string;
189
- email?: string;
190
- contactType: string;
191
- availableLanguage?: string[];
192
- areaServed?: string[];
193
- }[];
194
- areaServed?: string[];
195
- brand?: string;
196
- award?: string[];
197
- memberOf?: {
198
- name: string;
199
- url?: string;
200
- }[];
201
- }
202
- /** Build a schema.org Organization JSON-LD graph. */
203
- declare function organizationGraph(options: OrganizationGraphOptions): Record<string, unknown>;
204
- //#endregion
205
105
  //#region src/icons.d.ts
206
106
  /**
207
107
  * Semantic icon name mapping across icon sets.
@@ -267,6 +167,7 @@ declare const iconMap: {
267
167
  readonly bookmark: "bookmark";
268
168
  readonly favorite: "heart";
269
169
  readonly star: "star";
170
+ readonly 'star-half': "star-half-stroke";
270
171
  readonly login: "right-to-bracket";
271
172
  readonly logout: "right-from-bracket";
272
173
  readonly email: "envelope";
@@ -438,6 +339,7 @@ declare const iconMap: {
438
339
  readonly bookmark: "bookmark";
439
340
  readonly favorite: "favorite";
440
341
  readonly star: "star";
342
+ readonly 'star-half': "star-half";
441
343
  readonly login: "login";
442
344
  readonly logout: "logout";
443
345
  readonly email: "mail";
@@ -526,6 +428,7 @@ declare const iconMap: {
526
428
  readonly bookmark: "bookmark";
527
429
  readonly favorite: "heart";
528
430
  readonly star: "star";
431
+ readonly 'star-half': "star-half";
529
432
  readonly login: "log-in";
530
433
  readonly logout: "log-out";
531
434
  readonly email: "mail";
@@ -614,6 +517,7 @@ declare const iconMap: {
614
517
  readonly bookmark: "bookmark";
615
518
  readonly favorite: "heart";
616
519
  readonly star: "star";
520
+ readonly 'star-half': "star-half";
617
521
  readonly login: "sign-in";
618
522
  readonly logout: "sign-out";
619
523
  readonly email: "envelope";
@@ -799,5 +703,5 @@ declare function collectIconRefs(files: readonly {
799
703
  text: string;
800
704
  }[], opts?: IconScanOptions): IconScanResult;
801
705
  //#endregion
802
- export { type ArticleAuthor, type ArticleGraphOptions, type Attrs, type BrandIcon, type BreadcrumbGraphOptions, type BreadcrumbItem, type ChildNode, type ContentNode, type DynamicIconRef, type El, type Elmnt, type FAQGraphOptions, type FAQItem, type FaviconLink, type FaviconOptions, type FaviconTagOptions, type IconRef, type IconRefKind, type IconScanOptions, type IconScanResult, type IconSet, type ImageLink, type ImageRef, type Link, type Localizable, type OrganizationGraphOptions, SCAN_EXT, SCAN_SKIP, type ScanOptions, type SemanticIcon, type SourceFile, type StyleList, type StyleValue, type TextLink, WEIGHTED_SETS, type WebManifestOptions, articleGraph, breadcrumbGraph, collectIconRefs, extractIconRefs, faqGraph, faviconLinks, faviconManifest, generateFavicons, generateIconInclude, getAttribute, iconMap, isElmnt, isImageLink, isLink, isTextLink, nodesToHtml, organizationGraph, parseRenderedSlots, partAttrs, prefixToMapKey, resolveBrandIcon, resolveIcon, scanFiles, serialize, styleList, t, toHtml, writeFaviconManifest };
706
+ export { type Attrs, type BrandIcon, type ChildNode, type ContentNode, type DynamicIconRef, type El, type Elmnt, type FaviconLink, type FaviconOptions, type FaviconTagOptions, type IconRef, type IconRefKind, type IconScanOptions, type IconScanResult, type IconSet, type ImageLink, type ImageRef, type Link, type Localizable, SCAN_EXT, SCAN_SKIP, type ScanOptions, type SemanticIcon, type SourceFile, type StyleList, type StyleValue, type TextLink, WEIGHTED_SETS, type WebManifestOptions, collectIconRefs, extractIconRefs, faviconLinks, faviconManifest, generateFavicons, generateIconInclude, getAttribute, iconMap, isElmnt, isImageLink, isLink, isTextLink, nodesToHtml, parseRenderedSlots, partAttrs, prefixToMapKey, resolveBrandIcon, resolveIcon, scanFiles, serialize, styleList, t, toHtml, writeFaviconManifest };
803
707
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/content.ts","../src/html.ts","../src/schema/article.ts","../src/schema/breadcrumb.ts","../src/schema/faq.ts","../src/schema/organization.ts","../src/icons.ts","../src/scan.ts","../src/icons-scan.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/content.ts","../src/html.ts","../src/icons.ts","../src/scan.ts","../src/icons-scan.ts"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -154,150 +154,6 @@ function nodesToHtml(nodes, resolveText = defaultResolveText) {
154
154
  return nodes.map((node) => nodeToHtml(node, resolveText)).join("");
155
155
  }
156
156
 
157
- //#endregion
158
- //#region src/schema/article.ts
159
- /** Build a schema.org Article JSON-LD graph. */
160
- function articleGraph(options) {
161
- const { headline, description, image, datePublished, dateModified, author, publisher, mainEntityOfPage, articleSection, wordCount, keywords } = options;
162
- const authors = Array.isArray(author) ? author : [author];
163
- return {
164
- "@context": "https://schema.org",
165
- "@type": "Article",
166
- headline,
167
- ...description && { description },
168
- ...image && { image: Array.isArray(image) ? image : [image] },
169
- datePublished,
170
- ...dateModified && { dateModified },
171
- author: authors.map((a) => ({
172
- "@type": "Person",
173
- name: a.name,
174
- ...a.url && { url: a.url }
175
- })),
176
- ...publisher && { publisher: {
177
- "@type": "Organization",
178
- name: publisher.name,
179
- ...publisher.logo && { logo: {
180
- "@type": "ImageObject",
181
- url: publisher.logo
182
- } }
183
- } },
184
- ...mainEntityOfPage && { mainEntityOfPage: {
185
- "@type": "WebPage",
186
- "@id": mainEntityOfPage
187
- } },
188
- ...articleSection && { articleSection },
189
- ...wordCount && { wordCount },
190
- ...keywords && { keywords: keywords.join(", ") }
191
- };
192
- }
193
-
194
- //#endregion
195
- //#region src/schema/breadcrumb.ts
196
- /** Build a schema.org BreadcrumbList JSON-LD graph. */
197
- function breadcrumbGraph(options) {
198
- return {
199
- "@context": "https://schema.org",
200
- "@type": "BreadcrumbList",
201
- itemListElement: options.items.map((item, index) => ({
202
- "@type": "ListItem",
203
- position: index + 1,
204
- name: item.name,
205
- item: item.url
206
- }))
207
- };
208
- }
209
-
210
- //#endregion
211
- //#region src/schema/faq.ts
212
- /**
213
- * Build a schema.org FAQPage JSON-LD graph.
214
- *
215
- * NOTE: Google recommends FAQ markup only for authoritative government
216
- * and health sites. For other sites, consider using QAPage schema instead.
217
- */
218
- function faqGraph(options) {
219
- return {
220
- "@context": "https://schema.org",
221
- "@type": "FAQPage",
222
- mainEntity: options.items.map((item) => ({
223
- "@type": "Question",
224
- name: item.question,
225
- acceptedAnswer: {
226
- "@type": "Answer",
227
- text: item.answer
228
- }
229
- }))
230
- };
231
- }
232
-
233
- //#endregion
234
- //#region src/schema/organization.ts
235
- /** Build a schema.org Organization JSON-LD graph. */
236
- function organizationGraph(options) {
237
- const { name, url, logo, description, email, telephone, address, sameAs, foundingDate, founders, numberOfEmployees, parentOrganization, subOrganization, contactPoint, areaServed, brand, award, memberOf } = options;
238
- return {
239
- "@context": "https://schema.org",
240
- "@type": "Organization",
241
- name,
242
- ...url && { url },
243
- ...logo && { logo },
244
- ...description && { description },
245
- ...email && { email },
246
- ...telephone && { telephone },
247
- ...address && { address: {
248
- "@type": "PostalAddress",
249
- ...address.streetAddress && { streetAddress: address.streetAddress },
250
- ...address.addressLocality && { addressLocality: address.addressLocality },
251
- ...address.addressRegion && { addressRegion: address.addressRegion },
252
- ...address.postalCode && { postalCode: address.postalCode },
253
- ...address.addressCountry && { addressCountry: address.addressCountry }
254
- } },
255
- ...sameAs && { sameAs },
256
- ...foundingDate && { foundingDate },
257
- ...founders && { founders: founders.map((f) => ({
258
- "@type": "Person",
259
- name: f
260
- })) },
261
- ...numberOfEmployees && { numberOfEmployees: typeof numberOfEmployees === "number" ? {
262
- "@type": "QuantitativeValue",
263
- value: numberOfEmployees
264
- } : {
265
- "@type": "QuantitativeValue",
266
- minValue: numberOfEmployees.minValue,
267
- maxValue: numberOfEmployees.maxValue
268
- } },
269
- ...parentOrganization && { parentOrganization: {
270
- "@type": "Organization",
271
- name: parentOrganization.name,
272
- ...parentOrganization.url && { url: parentOrganization.url }
273
- } },
274
- ...subOrganization && { subOrganization: subOrganization.map((sub) => ({
275
- "@type": "Organization",
276
- name: sub.name,
277
- ...sub.url && { url: sub.url }
278
- })) },
279
- ...contactPoint && { contactPoint: contactPoint.map((cp) => ({
280
- "@type": "ContactPoint",
281
- telephone: cp.telephone,
282
- contactType: cp.contactType,
283
- ...cp.email && { email: cp.email },
284
- ...cp.availableLanguage && { availableLanguage: cp.availableLanguage },
285
- ...cp.areaServed && { areaServed: cp.areaServed }
286
- })) },
287
- ...areaServed && { areaServed },
288
- ...brand && { brand: {
289
- "@type": "Brand",
290
- name: brand
291
- } },
292
- ...award && { award },
293
- ...memberOf && { memberOf: memberOf.map((m) => ({
294
- "@type": "Organization",
295
- name: m.name,
296
- ...m.url && { url: m.url }
297
- })) }
298
- };
299
- }
300
-
301
157
  //#endregion
302
158
  //#region src/icons.ts
303
159
  /**
@@ -381,6 +237,7 @@ const iconMap = {
381
237
  bookmark: "bookmark",
382
238
  favorite: "heart",
383
239
  star: "star",
240
+ "star-half": "star-half-stroke",
384
241
  login: "right-to-bracket",
385
242
  logout: "right-from-bracket",
386
243
  email: "envelope",
@@ -552,6 +409,7 @@ const iconMap = {
552
409
  bookmark: "bookmark",
553
410
  favorite: "favorite",
554
411
  star: "star",
412
+ "star-half": "star-half",
555
413
  login: "login",
556
414
  logout: "logout",
557
415
  email: "mail",
@@ -640,6 +498,7 @@ const iconMap = {
640
498
  bookmark: "bookmark",
641
499
  favorite: "heart",
642
500
  star: "star",
501
+ "star-half": "star-half",
643
502
  login: "log-in",
644
503
  logout: "log-out",
645
504
  email: "mail",
@@ -728,6 +587,7 @@ const iconMap = {
728
587
  bookmark: "bookmark",
729
588
  favorite: "heart",
730
589
  star: "star",
590
+ "star-half": "star-half",
731
591
  login: "sign-in",
732
592
  logout: "sign-out",
733
593
  email: "envelope",
@@ -1079,5 +939,5 @@ function collectIconRefs(files, opts) {
1079
939
  }
1080
940
 
1081
941
  //#endregion
1082
- export { SCAN_EXT, SCAN_SKIP, WEIGHTED_SETS, articleGraph, breadcrumbGraph, collectIconRefs, extractIconRefs, faqGraph, faviconLinks, faviconManifest, generateFavicons, generateIconInclude, getAttribute, iconMap, isElmnt, isImageLink, isLink, isTextLink, nodesToHtml, organizationGraph, parseRenderedSlots, partAttrs, prefixToMapKey, resolveBrandIcon, resolveIcon, scanFiles, serialize, styleList, t, toHtml, writeFaviconManifest };
942
+ export { SCAN_EXT, SCAN_SKIP, WEIGHTED_SETS, collectIconRefs, extractIconRefs, faviconLinks, faviconManifest, generateFavicons, generateIconInclude, getAttribute, iconMap, isElmnt, isImageLink, isLink, isTextLink, nodesToHtml, parseRenderedSlots, partAttrs, prefixToMapKey, resolveBrandIcon, resolveIcon, scanFiles, serialize, styleList, t, toHtml, writeFaviconManifest };
1083
943
  //# sourceMappingURL=index.mjs.map