rikiki-deck 0.7.1 → 0.7.2

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 (103) hide show
  1. package/README.md +1 -1
  2. package/bin/lib/browser.mjs +24 -1
  3. package/bin/lib/check-api.d.ts +28 -0
  4. package/bin/lib/check-api.mjs +6 -0
  5. package/bin/lib/check-plugins.mjs +228 -0
  6. package/bin/lib/check.mjs +369 -14
  7. package/bin/lib/component-deps.mjs +69 -0
  8. package/bin/lib/export-pdf.mjs +28 -5
  9. package/bin/lib/inline.mjs +70 -35
  10. package/bin/lib/narrative.mjs +77 -0
  11. package/bin/lib/prune-icons.mjs +24 -1
  12. package/bin/rikiki.mjs +45 -7
  13. package/dist/{plugins/click-stages.d.ts → click-stages.d.ts} +1 -1
  14. package/dist/{layouts/deck-cover.d.ts → deck-cover.d.ts} +2 -0
  15. package/dist/deck-cover.js +9 -6
  16. package/dist/{atoms/deck-kicker.d.ts → deck-kicker.d.ts} +5 -0
  17. package/dist/deck-kicker.js +1 -1
  18. package/dist/deck-mermaid.js +4 -4
  19. package/dist/deck-overview.js +41 -40
  20. package/dist/deck-presenter.js +89 -46
  21. package/dist/{runtime/deck-root.d.ts → deck-root.d.ts} +14 -3
  22. package/dist/deck-root.js +5 -5
  23. package/dist/{extras/deck-timeline.d.ts → deck-timeline.d.ts} +6 -0
  24. package/dist/deck-timeline.js +4 -4
  25. package/dist/deck-versus.js +2 -2
  26. package/dist/index.d.ts +37 -37
  27. package/dist/index.js +55 -52
  28. package/dist/standalone.js +229 -182
  29. package/dist/vendor/THIRD-PARTY-NOTICES.txt +3 -3
  30. package/dist/vendor/inventory.json +7 -7
  31. package/dist/vendor/mermaid.min.js +95 -95
  32. package/docs/llms/rikiki-reference.md +31 -4
  33. package/llms.txt +1 -1
  34. package/package.json +13 -6
  35. package/dist/contrast.js +0 -1
  36. package/dist/shared/contrast.d.ts +0 -52
  37. /package/dist/{shared/annotation-marks.d.ts → annotation-marks.d.ts} +0 -0
  38. /package/dist/{shared/bar-segments.d.ts → bar-segments.d.ts} +0 -0
  39. /package/dist/{infrastructure/browser-location.d.ts → browser-location.d.ts} +0 -0
  40. /package/dist/{shared/cards-syntax.d.ts → cards-syntax.d.ts} +0 -0
  41. /package/dist/{runtime/color.d.ts → color.d.ts} +0 -0
  42. /package/dist/{extras/deck-agenda.d.ts → deck-agenda.d.ts} +0 -0
  43. /package/dist/{extras/deck-annotate.d.ts → deck-annotate.d.ts} +0 -0
  44. /package/dist/{atoms/deck-badge.d.ts → deck-badge.d.ts} +0 -0
  45. /package/dist/{extras/deck-bar.d.ts → deck-bar.d.ts} +0 -0
  46. /package/dist/{layouts/deck-bento.d.ts → deck-bento.d.ts} +0 -0
  47. /package/dist/{molecules/deck-callout.d.ts → deck-callout.d.ts} +0 -0
  48. /package/dist/{molecules/deck-card.d.ts → deck-card.d.ts} +0 -0
  49. /package/dist/{molecules/deck-cell.d.ts → deck-cell.d.ts} +0 -0
  50. /package/dist/{extras/deck-checklist.d.ts → deck-checklist.d.ts} +0 -0
  51. /package/dist/{atoms/deck-code-highlighter.d.ts → deck-code-highlighter.d.ts} +0 -0
  52. /package/dist/{atoms/deck-code.d.ts → deck-code.d.ts} +0 -0
  53. /package/dist/{molecules/deck-csv.d.ts → deck-csv.d.ts} +0 -0
  54. /package/dist/{layouts/deck-feature-cards.d.ts → deck-feature-cards.d.ts} +0 -0
  55. /package/dist/{layouts/deck-feature.d.ts → deck-feature.d.ts} +0 -0
  56. /package/dist/{extras/deck-figure.d.ts → deck-figure.d.ts} +0 -0
  57. /package/dist/{molecules/deck-fit.d.ts → deck-fit.d.ts} +0 -0
  58. /package/dist/{extras/deck-flow.d.ts → deck-flow.d.ts} +0 -0
  59. /package/dist/{extras/deck-graph.d.ts → deck-graph.d.ts} +0 -0
  60. /package/dist/{molecules/deck-grid.d.ts → deck-grid.d.ts} +0 -0
  61. /package/dist/{runtime/deck-help.d.ts → deck-help.d.ts} +0 -0
  62. /package/dist/{extras/deck-icon.d.ts → deck-icon.d.ts} +0 -0
  63. /package/dist/{extras/deck-kpi-grid.d.ts → deck-kpi-grid.d.ts} +0 -0
  64. /package/dist/{domain/deck-link.d.ts → deck-link.d.ts} +0 -0
  65. /package/dist/{molecules/deck-md.d.ts → deck-md.d.ts} +0 -0
  66. /package/dist/{molecules/deck-mermaid.d.ts → deck-mermaid.d.ts} +0 -0
  67. /package/dist/{molecules/deck-metric.d.ts → deck-metric.d.ts} +0 -0
  68. /package/dist/{runtime/deck-notes.d.ts → deck-notes.d.ts} +0 -0
  69. /package/dist/{domain/deck-outline.d.ts → deck-outline.d.ts} +0 -0
  70. /package/dist/{runtime/deck-overview.d.ts → deck-overview.d.ts} +0 -0
  71. /package/dist/{extras/deck-persona.d.ts → deck-persona.d.ts} +0 -0
  72. /package/dist/{layouts/deck-photo.d.ts → deck-photo.d.ts} +0 -0
  73. /package/dist/{molecules/deck-point.d.ts → deck-point.d.ts} +0 -0
  74. /package/dist/{runtime/deck-presenter.d.ts → deck-presenter.d.ts} +0 -0
  75. /package/dist/{extras/deck-pull.d.ts → deck-pull.d.ts} +0 -0
  76. /package/dist/{atoms/deck-punch.d.ts → deck-punch.d.ts} +0 -0
  77. /package/dist/{extras/deck-quote.d.ts → deck-quote.d.ts} +0 -0
  78. /package/dist/{layouts/deck-section.d.ts → deck-section.d.ts} +0 -0
  79. /package/dist/{molecules/deck-shortcut.d.ts → deck-shortcut.d.ts} +0 -0
  80. /package/dist/{atoms/deck-source.d.ts → deck-source.d.ts} +0 -0
  81. /package/dist/{layouts/deck-split.d.ts → deck-split.d.ts} +0 -0
  82. /package/dist/{molecules/deck-stack.d.ts → deck-stack.d.ts} +0 -0
  83. /package/dist/{molecules/deck-stat.d.ts → deck-stat.d.ts} +0 -0
  84. /package/dist/{molecules/deck-step-list.d.ts → deck-step-list.d.ts} +0 -0
  85. /package/dist/{extras/deck-table.d.ts → deck-table.d.ts} +0 -0
  86. /package/dist/{layouts/deck-takeaway.d.ts → deck-takeaway.d.ts} +0 -0
  87. /package/dist/{molecules/deck-tier-list.d.ts → deck-tier-list.d.ts} +0 -0
  88. /package/dist/{runtime/deck-transition.d.ts → deck-transition.d.ts} +0 -0
  89. /package/dist/{extras/deck-versus.d.ts → deck-versus.d.ts} +0 -0
  90. /package/dist/{application/deep-link.d.ts → deep-link.d.ts} +0 -0
  91. /package/dist/{shared/escape-html.d.ts → escape-html.d.ts} +0 -0
  92. /package/dist/{shared/fit-controller.d.ts → fit-controller.d.ts} +0 -0
  93. /package/dist/{shared/graph-layout.d.ts → graph-layout.d.ts} +0 -0
  94. /package/dist/{shared/grid-tracks.d.ts → grid-tracks.d.ts} +0 -0
  95. /package/dist/{shared/icon-set.d.ts → icon-set.d.ts} +0 -0
  96. /package/dist/{application/keymap.d.ts → keymap.d.ts} +0 -0
  97. /package/dist/{application/mouse-nav.d.ts → mouse-nav.d.ts} +0 -0
  98. /package/dist/{domain/navigation.d.ts → navigation.d.ts} +0 -0
  99. /package/dist/{shared/parse-csv.d.ts → parse-csv.d.ts} +0 -0
  100. /package/dist/{plugins/shiki.d.ts → shiki.d.ts} +0 -0
  101. /package/dist/{extras/signature.d.ts → signature.d.ts} +0 -0
  102. /package/dist/{shared/slide-fill.d.ts → slide-fill.d.ts} +0 -0
  103. /package/dist/{domain/viewport.d.ts → viewport.d.ts} +0 -0
@@ -1,6 +1,6 @@
1
1
  # Rikiki · LLM reference
2
2
 
3
- This reference documents rikiki v0.7.1.
3
+ This reference documents rikiki v0.7.2.
4
4
 
5
5
  Exhaustive, self-consistent reference for authoring valid **rikiki** decks. Every
6
6
  tag, attribute, slot, and token below was derived from the source in this repo
@@ -227,7 +227,7 @@ Direct children of `<deck-root>`. Each is one slide.
227
227
 
228
228
  | Tag | Purpose | Key attributes | Slots |
229
229
  |-----|---------|----------------|-------|
230
- | `deck-cover` | Opening slide, dark, with brand + meta | `brand` (split on " · "), `brand-src` (logo URL), `speaker`, `company`, `duration`, `audience`, `runtime`; per-row label overrides `speaker-label`, `company-label`, `duration-label`, `audience-label`, `runtime-label` | default `<h1>`, `.sub`/`p[slot=sub]` |
230
+ | `deck-cover` | Opening slide, dark, with brand + meta | `brand` (split on " · "), `brand-src` (logo URL), `speaker`, `company`, `company-src` (client logo URL, shown before the company name), `duration`, `audience`, `runtime`; per-row label overrides `speaker-label`, `company-label`, `duration-label`, `audience-label`, `runtime-label` | default `<h1>`, `.sub`/`p[slot=sub]` |
231
231
  | `deck-section` | Chapter divider (also a chapter boundary for 2D nav) | `num` | default `<h1>` (may use `<em>`) |
232
232
  | `deck-feature` | Headline + lead + one focal block | `eyebrow` | `title` (`<h1>`), `lead`, default (focal block, e.g. `deck-code`) |
233
233
  | `deck-split` | Two or three columns side by side | `eyebrow`, `cols` (`1-1`/`1-2`/`2-1`/`3`), `gap` (1..6 or raw CSS length), `col-gap` (1..6 or raw CSS length) | `title`, `lead`; `left`/`right` (2-col) or `a`/`b`/`c` (3-col) |
@@ -807,12 +807,18 @@ an `element` path that reaches into the Shadow DOM (`deck-feature#detail
807
807
  | `SLIDE_TOP_HEAVY` | warning | measured on the pixels · the ink sits in the top with a dead band under it |
808
808
  | `TALK_SHORTER_THAN_ANNOUNCED` | warning | the notes carry far less speech than the cover announces |
809
809
  | `TEXT_TOO_SMALL` | warning | below the readable floor once the canvas is scaled |
810
+ | `TEXT_LAST_LINE_ORPHAN` | warning | a block of prose ends on a stub under a quarter of the width above it · measured on the painted lines, headings and short blocks excepted · worst one per slide |
810
811
  | `UNKNOWN_ATTRIBUTE` | warning | an attribute the element neither reads nor styles on · the value is dropped |
811
812
  | `DUPLICATE_SLIDE_ID` | warning | two slides answer to the same name |
812
813
  | `EXTERNAL_DEPENDENCY` | warning | the deck fetches from the network at runtime |
813
814
  | `GRAPH_NODE_OUT_OF_BOUNDS` | error | a `deck-node` is painted outside its `deck-graph` canvas · move it inward with `at`, shorten its note, or constrain it with `width` |
814
815
  | `GRAPH_EDGE_CROSSES_NODE` | warning | the line a `deck-edge` actually paints, bends and stroke width included, runs over a node it does not connect · move the obstructing node, or route the edge around it |
815
816
  | `GRAPH_NODE_OVERLAPS_NODE` | error | two `deck-node` of the same `deck-graph` are painted on top of each other · one of them is unreadable |
817
+ | `GRAPH_NODE_COVERS_LABEL` | error | a `deck-node` is painted over a `deck-group` / `deck-lane` / edge caption · move the node with `at`, or the region with its own `at` |
818
+ | `GRAPH_EDGE_SKEWED` | warning | an edge misses horizontal or vertical by a few pixels · a frank diagonal is left alone, a three-degree slope is a slip · align the two `at` coordinates, or set `route="ortho"` |
819
+ | `GRAPH_NODES_OFF_AXIS` | warning | two nodes sit within the alignment slack of the same row or column without sharing it · worst offender per graph |
820
+ | `GRAPH_NODE_SIZES_MIXED` | warning | two nodes of one row (or column) differ by a few pixels in height (or width) · near-equal boxes read as a failed attempt at the same size, plainly different ones are left alone |
821
+ | `GRAPH_LAYOUT_NOT_SEMANTIC` | warning | every node of a graph of three or more sits on one axis, with no `layout` · the `at` coordinates re-do what `layout="row"` / `layout="column"` says |
816
822
 
817
823
  The report also carries `notChecked`, which names what was **not** looked at:
818
824
  revealed steps, accessibility, wording and facts, other viewports, text inside
@@ -1242,7 +1248,7 @@ Pick one deliberately · they make different promises.
1242
1248
 
1243
1249
  **Served** · the folder as you wrote it. HTML, CSS and JS stay separate files,
1244
1250
  so editing a slide needs no build. ES modules mean it needs a **static HTTP
1245
- server**, not a double-click: `python3 -m http.server`, `npx serve`, anything.
1251
+ server**, not a double-click: `npx serve .`, or anything that speaks HTTP.
1246
1252
  Offline once every asset is local.
1247
1253
 
1248
1254
  **Standalone** · one HTML file, produced by `rikiki bundle deck.html out.html`.
@@ -1383,6 +1389,23 @@ script, so a standalone deck keeps them and stays offline. Forget the `<script>`
1383
1389
  and the tag stays an unknown element: it renders its text content, logs nothing,
1384
1390
  and the rest of the deck is unaffected.
1385
1391
 
1392
+ **Past about four added modules, stop adding script tags and bundle.** Each
1393
+ module is compiled on its own and carries its own copy of the shared code, and
1394
+ gzip compresses one large repetitive file far better than several small ones,
1395
+ so script tags stop paying off quickly. Measured on this release, gzipped:
1396
+
1397
+ | what the deck loads | gzip |
1398
+ |---|---|
1399
+ | `dist/index.js` alone | 26 KB |
1400
+ | `dist/index.js` + 3 modules | 30 KB |
1401
+ | `dist/index.js` + 5 modules | 33 KB |
1402
+
1403
+ `rikiki bundle` carries only the components the deck actually writes, in one
1404
+ file, so it is smaller than the plain bundle for any deck that does not use
1405
+ every component · and it is the only option that gets *smaller* as the deck
1406
+ gets simpler, rather than larger. Script tags are the convenient path for one
1407
+ or two extras, not the cheap one.
1408
+
1386
1409
  Every evidence block below (`deck-csv`, `deck-table`, `deck-bar`,
1387
1410
  `deck-kpi-grid`, `deck-annotate`, and plain prose) takes a `deck-source`
1388
1411
  underneath it for the credit line · `deck-source` is a core atom (§6), not an
@@ -1400,7 +1423,7 @@ authoring paths render identically and cannot drift.
1400
1423
  | `deck-persona` | Who is speaking, or who the case study is about · the portrait block is the inverse surface, so the person has a place on the slide | `name`, `person-role` (**not** `role`), `org`, `context` (the quiet line, gapped away from the identity), `src` (a portrait; initials in inverse ink stand in without one), `on-dark` (the block flips to paper with ink initials), `compact` (shrinks the block and the name together, for a supporting persona), `inline` (name, role and context on one wrapping row) | · |
1401
1424
  | `deck-versus` | A directed comparison as a BLOCK inside a slide (`deck-split` covers the case where the comparison is the whole slide) | `pivot`, `winner` (`left`/`right`), `slide` (make the comparison a deck-root slide of its own, with `title` and `lead` slots), `eyebrow` (context label above the title, slide mode only) | `title`, `lead`, `left`, `right`, `footer` (full width, under both sides, slide mode only; a slotted `deck-callout` keeps its own size) |
1402
1425
  | `deck-flow` / `deck-flow-step` | A chain across the width · numbered stages, and only the active one takes the block | flow: `cols`, `reveal` · stage: `label`, `note` | stage default = extra content |
1403
- | `deck-timeline` / `deck-milestone` | A trajectory in time, on an axis | timeline: `direction` (`row`/`column`), `reveal` · milestone: `date`, `label`, `note`, `tone` | · |
1426
+ | `deck-timeline` / `deck-milestone` | A trajectory in time, on an axis | timeline: `direction` (`row`/`column`), `alternate` (row only · milestones alternate above and below the axis, each twice as wide), `reveal` · milestone: `date`, `label`, `note`, `tone` | · |
1404
1427
  | `deck-graph` / `deck-node` / `deck-edge` / `deck-group` / `deck-lane` | Nodes, edges, regions and bands · the primitive behind every boxes-and-arrows slide | graph: `layout` (`free`/`row`/`column`), `reveal` · node: `at` (`x,y` in percent), `label`, `note`, `boxed`, `tone`, `icon`, `width` (an explicit CSS width such as `18ch` or `240px`, so a long label wraps instead of colliding) · edge: `from`, `to`, `label`, `dashed`, `arrow` (`end` default / `start` / `both` / `none`), `route` (`straight` default / `ortho` for right-angle segments), `label-offset` (`x,y` in pixels, moves the label off the line) · each edge publishes the polyline it paints back onto itself as `data-path` (`x1,y1 x2,y2[ ...]`, graph-relative CSS pixels), which is what `rikiki check` reads · group: `at` (`x,y,w,h`), `label`, `solid` · lane: `at` (`top,height`), `label` | node default = extra content |
1405
1428
  | `deck-table` | A hand-authored table with the hierarchy `deck-csv` has · the table stays in your light DOM, so its cells may carry markup | `highlight-rows`, `highlight-cols`, `reveal` | default = your `<table>` |
1406
1429
  | `deck-annotate` | A screenshot the speaker can point at · numbered markers positioned in percent, revealed one per step through the engine's own step mechanism · a real `<figure>`/`<figcaption>`, so it can carry its own caption and source like `deck-figure` | `src`, `alt`, `marks` (`x,y,label` triples separated by `\|`, coordinates in percent), `all-at-once`, `no-legend`, `leader` (draw a line from the target point to a displaced badge), `offset` (`x,y` in pixels, or a named side `above` / `below` / `left` / `right` : the badge is displaced by its own rendered diameter plus `--deck-annotate-anchor-gap` in that direction, and its leader turns on regardless of `leader`), `offsets` (per-mark displacements separated by `\|`, mixing pixel and keyword forms, e.g. `above\|0,-40\|right`; a missing entry falls back to `offset`), `caption`, `source`, `source-href` (turns the credit into a link) | `caption`, `source` |
@@ -1702,3 +1725,7 @@ when a clipping box loses more than a few pixels of content.
1702
1725
  **Too empty is a judgement.** A section title is meant to be sparse. The same
1703
1726
  spec measures how much of the canvas each slide uses and attaches the report to
1704
1727
  the run, without failing · the numbers are advice, and §19 is the answer.
1728
+
1729
+ ## Presentation previews (0.7.2)
1730
+
1731
+ Overview prepares thumbnails incrementally while idle and keeps its grid for reopening. Content or theme changes invalidate the cache. Presenter previews retain their documents and mirror the current slide step, including annotations; the footer reports the current step. Cover layouts display slide numbers unless `no-counter` is set. Custom components can implement `applyStep(step)` to synchronize their reveal state.
package/llms.txt CHANGED
@@ -5,7 +5,7 @@
5
5
  > stylesheet, then the component bundle, then write a `<deck-root>` wrapping
6
6
  > `deck-*` slide elements. No build step to author or run a deck.
7
7
 
8
- This reference documents rikiki v0.7.1.
8
+ This reference documents rikiki v0.7.2.
9
9
 
10
10
  The framework is opinionated:
11
11
 
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "rikiki-deck",
3
- "version": "0.7.1",
3
+ "version": "0.7.2",
4
4
  "description": "A tiny Lit Web Components framework for technical presentations · zero-build for consumers, TypeScript for contributors.",
5
- "author": "Cédric Chariere Fiedler <cedric@siliceum.com>",
5
+ "author": "Cédric Chariere Fiedler <chariere.fiedler.cedric@gmail.com>",
6
6
  "homepage": "https://rikiki.tordu-jardin.fr",
7
7
  "repository": {
8
8
  "type": "git",
@@ -19,6 +19,10 @@
19
19
  "module": "./dist/index.js",
20
20
  "types": "./dist/index.d.ts",
21
21
  "exports": {
22
+ "./check-api": {
23
+ "types": "./bin/lib/check-api.d.ts",
24
+ "import": "./bin/lib/check-api.mjs"
25
+ },
22
26
  ".": {
23
27
  "types": "./dist/index.d.ts",
24
28
  "import": "./dist/index.js"
@@ -44,21 +48,24 @@
44
48
  ".claude/skills/rikiki-debug"
45
49
  ],
46
50
  "scripts": {
47
- "build": "node build-vendor.mjs && node build.mjs && node build-standalone.mjs && tsc --emitDeclarationOnly -p tsconfig.build.json",
51
+ "build": "node build-vendor.mjs && node build.mjs && node build-standalone.mjs && node build-types.mjs",
48
52
  "vendor": "node build-vendor.mjs",
49
53
  "watch": "node build.mjs --watch",
50
54
  "typecheck": "tsc --noEmit",
51
55
  "clean": "rm -rf dist",
52
56
  "bundle": "node bundle.mjs",
57
+ "examples": "node scripts/rebuild-examples.mjs",
58
+ "readme": "node scripts/build-readme.mjs",
53
59
  "deck": "node bin/rikiki.mjs assemble",
54
60
  "deck:example": "node bin/rikiki.mjs assemble decks/example/deck.config.js",
55
61
  "test": "vitest run",
56
62
  "test:e2e": "playwright test",
57
63
  "test:smoke": "playwright test --grep @smoke",
58
64
  "release:smoke": "node scripts/release-smoke.mjs",
59
- "lint": "biome check src scripts",
60
- "format": "biome format --write src scripts",
65
+ "lint": "biome check src scripts tools",
66
+ "format": "biome format --write src scripts tools",
61
67
  "bump": "node scripts/bump-version.mjs",
68
+ "new:component": "node scripts/new-component.mjs",
62
69
  "prepublishOnly": "npm run build && npm test"
63
70
  },
64
71
  "devDependencies": {
@@ -68,7 +75,7 @@
68
75
  "esbuild": "^0.24.0",
69
76
  "lit": "^3.3.3",
70
77
  "marked": "^12.0.2",
71
- "mermaid": "^10.9.6",
78
+ "mermaid": "^10.9.8",
72
79
  "rolldown": "^1.1.1",
73
80
  "shiki": "^1.24.0",
74
81
  "typescript": "^5.6.0",
package/dist/contrast.js DELETED
@@ -1 +0,0 @@
1
- var R=/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i,E=/^#([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])$/i,M=/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i,N=/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i,v=/^rgba?\(\s*([\d.]+)[\s,]+([\d.]+)[\s,]+([\d.]+)(?:[\s,/]+([\d.]+%?))?/i,s=n=>parseInt(n.length===1?n+n:n,16);function T(n){if(n===void 0)return;let t=n.endsWith("%")?Number(n.slice(0,-1))/100:Number(n);return Number.isFinite(t)?Math.min(1,Math.max(0,t)):void 0}function A(n){let t=n.trim(),r=t.match(E)??t.match(R);if(r){let[,u,a,i,c]=r;return{r:s(u),g:s(a),b:s(i),...c?{a:s(c)/255}:{}}}let e=t.match(N)??t.match(M);if(e){let[,u,a,i,c]=e;return{r:s(u),g:s(a),b:s(i),...c?{a:s(c)/255}:{}}}let o=t.match(v);if(o){let u=T(o[4]);return{r:Number(o[1]),g:Number(o[2]),b:Number(o[3]),...u===void 0?{}:{a:u}}}return null}function C(n){return n.a===void 0||n.a>=1}function $(n,t){if(!C(t))throw new Error("flatten: the backdrop must be opaque");let r=n.a??1;return{r:n.r*r+t.r*(1-r),g:n.g*r+t.g*(1-r),b:n.b*r+t.b*(1-r)}}var b=n=>{let t=n/255;return t<=.03928?t/12.92:((t+.055)/1.055)**2.4};function m({r:n,g:t,b:r}){return .2126*b(n)+.7152*b(t)+.0722*b(r)}function w(n,t){let r=m(n),e=m(t),[o,u]=r>=e?[r,e]:[e,r];return(o+.05)/(u+.05)}function d({r:n,g:t,b:r}){let[e,o,u]=[b(n),b(t),b(r)],a=(e*.4124+o*.3576+u*.1805)/.95047,i=e*.2126+o*.7152+u*.0722,c=(e*.0193+o*.1192+u*.9505)/1.08883,f=g=>g>.008856?Math.cbrt(g):7.787*g+16/116,[h,l,x]=[f(a),f(i),f(c)];return[116*l-16,500*(h-l),200*(l-x)]}function H(n,t){let[r,e,o]=d(n),[u,a,i]=d(t);return Math.hypot(r-u,e-a,o-i)}var S=10;function X(n){let t=new Map,r=n.replace(/\/\*[\s\S]*?\*\//g,"");for(let e of r.matchAll(/(--[\w-]+)\s*:\s*([^;{}]+);/g))t.set(e[1],e[2].trim());return t}function p(n,t,r=new Set){if(r.has(t))return null;r.add(t);let e=n.get(t);if(e===void 0)return null;let o=e.match(/^var\(\s*(--[\w-]+)\s*(?:,\s*([^)]*))?\)$/);if(!o)return e;let u=p(n,o[1],r);return u!==null?u:o[2]?o[2].trim():null}function _(n,t){let r=p(n,t);return r===null?null:A(r)}var k={normalText:4.5,largeText:3,uiComponent:3};export{S as DELTA_E_DISTINCT,k as WCAG_AA,w as contrastRatio,H as deltaE,$ as flatten,C as isOpaque,A as parseColor,X as readTokens,m as relativeLuminance,_ as resolveColor,p as resolveToken};
@@ -1,52 +0,0 @@
1
- export interface Rgb {
2
- r: number;
3
- g: number;
4
- b: number;
5
- /** 0 to 1 · absent means fully opaque. A translucent color has NO contrast
6
- * ratio of its own, only one against a named backdrop · see flatten(). */
7
- a?: number;
8
- }
9
- /** Parse `#abc`, `#abcd`, `#aabbcc`, `#aabbccdd`, `rgb(…)` or `rgba(…)` ·
10
- * null for anything else. Alpha is CARRIED, not dropped: a value read as
11
- * opaque when it is not turns a 1.1 contrast into a 20 and makes any guard
12
- * built on it a lie. */
13
- export declare function parseColor(value: string): Rgb | null;
14
- /** True when the color is fully opaque, so it has a luminance of its own. */
15
- export declare function isOpaque(color: Rgb): boolean;
16
- /** Composite `fg` over `bg` (source-over) · the color the eye actually sees.
17
- * `bg` must be opaque; a translucent backdrop has no single answer. */
18
- export declare function flatten(fg: Rgb, bg: Rgb): Rgb;
19
- /** WCAG 2.1 relative luminance, 0 (black) to 1 (white). */
20
- export declare function relativeLuminance({ r, g, b }: Rgb): number;
21
- /** WCAG 2.1 contrast ratio between two colors · 1 to 21, order-independent. */
22
- export declare function contrastRatio(a: Rgb, b: Rgb): number;
23
- /**
24
- * CIE76 colour difference between two opaque colours.
25
- *
26
- * WHY THIS EXISTS ALONGSIDE contrastRatio · the WCAG ratio is luminance only,
27
- * so it cannot tell a saturated accent from the paper it sits on: the mango
28
- * accent scores 1.48 against the siliceum page and is nonetheless one of the
29
- * most visible things on the slide. Judging a SURFACE by luminance alone would
30
- * condemn every colour-coded tile and miss none of the grey ones. A surface is
31
- * distinguishable when it wins on either axis.
32
- *
33
- * The threshold used across this repo is DELTA_E_DISTINCT, below.
34
- */
35
- export declare function deltaE(a: Rgb, b: Rgb): number;
36
- /** Clearly perceptible between two large adjacent areas · the easiest case for
37
- * the eye, and the one a slide always presents. Not a taste threshold. */
38
- export declare const DELTA_E_DISTINCT = 10;
39
- /** Collect every `--name: value;` declaration in a stylesheet · later
40
- * declarations win, matching the cascade for a single theme file. */
41
- export declare function readTokens(css: string): Map<string, string>;
42
- /** Follow a `var(--a, fallback)` chain down to a literal color.
43
- * Returns null on an unresolvable or cyclic reference. */
44
- export declare function resolveToken(tokens: Map<string, string>, name: string, seen?: Set<string>): string | null;
45
- /** Resolve a token straight to RGB · null when it is missing or not a color. */
46
- export declare function resolveColor(tokens: Map<string, string>, name: string): Rgb | null;
47
- /** WCAG 2.1 minimum ratios. Large text is >= 24px, or >= 18.66px bold. */
48
- export declare const WCAG_AA: {
49
- readonly normalText: 4.5;
50
- readonly largeText: 3;
51
- readonly uiComponent: 3;
52
- };
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes