@taprootio/espalier 4.18.0 → 4.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ # 4.19.0
2
+
3
+ Filled action labels meet their contrast target, and the theme fit report says when a brand colour did not survive the compile.
4
+
5
+ - **The default filled action changed colour in the light scheme, and this is visible on any site that has not pinned it.** `--esp-color-action-background` resolved to the `raised3` ramp stop in both schemes, which is L 0.80 in the light ramp — a lightness where no ink, not even pure black, reaches the Lc 75 that APCA asks of a button label. Contrast enforcement walked the label to black and stopped 3.7 short, so the stock light theme shipped a button it could not make legible. The mapping is now chosen per scheme: `muted` in light, giving a mid-band surface with a pale label at Lc 76.0, and `raised3` in dark, which is what it already was — **the dark scheme's action pair is unchanged**, at Lc 81.6. Those are the stops a theme declaring an `action` role has always compiled to, so naming a role no longer moves the button either. A theme that pins `semanticMappings.actionBackground` is unaffected.
6
+ - The date picker now reads each of its inks against the surface it sits on. Its focus rings take `--esp-color-text`, which is enforced against the page ground the calendar paints on; they had been taking `--esp-color-action-text`, which is only guaranteed on a filled action and happened to match only while the light theme's action label was near-black. A ring drawn *inside* a selected day is the exception — that cell paints the action surface, so its ring takes `--esp-color-action-text`, and so does today's marker when today is the selected day, where it previously took `--esp-color-border`. A selected day now paints the action pair itself — `--esp-color-action-background` under `--esp-color-action-text` — which is the one surface/ink pairing the engine enforces, reaching Lc 76.0 in light where the old layer-3 ground left its label at 71.3 with nothing guaranteeing it. **A selected day is a deeper, filled swatch in the light scheme as a result.** The dark scheme is unchanged: there the layer-3 and action surfaces resolve to the same colour.
7
+ - `themeFitLints()` gains **`action-anchor-inversion`**. It fires when a filled action renders the opposite way round from the swatches it names — a surface whose swatch wants dark ink took light ink instead, or a declared `action.color`/`action.ink` pair's lightness order reversed. This is the one case where reading the report's per-token deltas does not help: an action's ramp stop is chosen by the engine rather than named by the theme, so re-seating the ramp — the remedy for every other anchored token — cannot move it, and the fix is to pin the token. A brand whose action colour is a light gold or a pastel is the case to watch.
8
+ - `themeFitLints()` gains **`apca-target-unmet`**. It fires when enforcement moved a text token as far as its ramp allows and the pair still missed the legibility floor. The message says which of two things went wrong, measured rather than assumed: the emitted ink is on the weaker side when the opposite pole would have cleared that ground, or the ground itself cannot carry the floor under any ink. It judges against the token's own tier or Lc 75, whichever is lower, so a caption that misses the preferred Lc 90 tier on a tinted wash stays quiet while genuinely illegible text does not.
9
+ - **Both lints are gated.** `espalier theme check` already exits non-zero on any lint, so a theme that trips either one will start failing that command. The per-surface `lints` arrays are part of the committed `--expect` tables, so a theme whose action pair or contrast floor is affected needs one reviewed `--update-expect` refresh.
10
+ - `ThemeFitToken` gains `pairing`, `"declared"` or `"derived"`, on a role-paired ink. `action.ink` defaults to the canvas colour, so an ink that was *derived* is the page ground by contract and is re-lit to the far end of the ramp on purpose — its large `anchor.deltaE` is the contract working, not a brand that went missing. The field is what lets `action-anchor-inversion` leave that case alone. It validates as optional, so a fit table written before this release reports the addition as ordinary drift rather than an unreadable-file error.
11
+ - A theme that declares `action.ink` now derives that ink's ramp stop from the action surface it actually sits on, the same way an undeclared ink already did. Naming the slot still chooses the colour family; the ramp still supplies the lightness. In a light scheme both rules already agreed, so nothing moves there. In a dark scheme the named slot used to start on the wrong side of the ramp and rely on enforcement to carry it back, emitting a weaker label than the ramp could give.
12
+ - The lightness-ramp guide now says which stop its seating procedure cannot reach, and why pinning a light action swatch may still not give you a legible button: under APCA the Lc 75 label tier is unreachable across a mid band of roughly L 0.55 to L 0.83, so a swatch inside it cannot hold a button label at its own lightness — though pinning the stop just past the band often can.
13
+
1
14
  # 4.18.0
2
15
 
3
16
  A brand logo holds its place before it loads, the header's menu button is one button, and a stored theme's declared roles finally take effect.