@celestia-island/hikari 0.55.235 → 0.55.236
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/package.json
CHANGED
|
@@ -216,16 +216,53 @@
|
|
|
216
216
|
color: rgb(var(--color-muted));
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
+
// Tone-pill ink, WCAG AA (2026-10-30 record-level leftover; PR #920 R2 S3-⑤).
|
|
220
|
+
//
|
|
221
|
+
// The pill text sits at `--text-2xs` (10px) — WCAG small text — so it owes
|
|
222
|
+
// 4.5:1, and the raw channel colour does not clear that on every palette:
|
|
223
|
+
// hosts swap the preset table wholesale (chest clears every stock key at
|
|
224
|
+
// boot and registers only its brand line), so no palette's value may be
|
|
225
|
+
// hardcoded here. The ink is therefore DERIVED from the live channel in
|
|
226
|
+
// OKLCH, whose perceptual uniformness lets the derivation touch lightness
|
|
227
|
+
// only — hue and chroma pass through, so each tone keeps its identity:
|
|
228
|
+
//
|
|
229
|
+
// light: L capped at 0.5 — darkens only colours too light for the white
|
|
230
|
+
// modal surface (stock amber would sit at 1.9:1);
|
|
231
|
+
// dark: L floored at 0.72 — lifts only colours too dark for the navy one
|
|
232
|
+
// (chest red would sit at 3.3:1).
|
|
233
|
+
//
|
|
234
|
+
// On the two shipped palettes the light cap grips EVERY coloured tone (all
|
|
235
|
+
// six entries sit above L 0.5 — chest light red 0.541 clamps to 0.501); the
|
|
236
|
+
// band's only pass-through is the stock dark positive green (L 0.768,
|
|
237
|
+
// already above the floor). Hue and chroma always survive. Both bounds were
|
|
238
|
+
// solved against the pill's real backdrop —
|
|
239
|
+
// the 10% channel tint composited over the 3%-primary card on
|
|
240
|
+
// `--color-surface` — for the WORST entry of the stock AND chest palettes:
|
|
241
|
+
// every tone lands ≥4.6:1. `light-dark()` resolves through the same
|
|
242
|
+
// color-scheme the theme engine already drives (`[data-mode] body` in
|
|
243
|
+
// theme.scss sets it alongside the channel swap), and an engine without
|
|
244
|
+
// relative-colour support drops the declaration, falling back to the
|
|
245
|
+
// neutral muted ink above — still AA everywhere: ≥4.87:1 even under the
|
|
246
|
+
// coloured pills' own tinted backdrop (4.87–7.20 across both palettes and
|
|
247
|
+
// modes; 5.98–8.06 on the plain neutral pill) — rather than shipping an
|
|
248
|
+
// unreadable tone colour. The border and background keep the raw channel:
|
|
249
|
+
// only the glyphs owe contrast, the tint is decorative.
|
|
219
250
|
.s-about-modal-row-meta[data-tone="positive"] {
|
|
220
251
|
border-color: rgb(var(--color-success) / 32%);
|
|
221
252
|
background: rgb(var(--color-success) / 10%);
|
|
222
|
-
color:
|
|
253
|
+
color: light-dark(
|
|
254
|
+
oklch(from rgb(var(--color-success)) min(l, 0.5) c h),
|
|
255
|
+
oklch(from rgb(var(--color-success)) max(l, 0.72) c h)
|
|
256
|
+
);
|
|
223
257
|
}
|
|
224
258
|
|
|
225
259
|
.s-about-modal-row-meta[data-tone="caution"] {
|
|
226
260
|
border-color: rgb(var(--color-warning) / 32%);
|
|
227
261
|
background: rgb(var(--color-warning) / 10%);
|
|
228
|
-
color:
|
|
262
|
+
color: light-dark(
|
|
263
|
+
oklch(from rgb(var(--color-warning)) min(l, 0.5) c h),
|
|
264
|
+
oklch(from rgb(var(--color-warning)) max(l, 0.72) c h)
|
|
265
|
+
);
|
|
229
266
|
}
|
|
230
267
|
|
|
231
268
|
// Red state: the component is not wired up / unreachable. The row then
|
|
@@ -233,7 +270,10 @@
|
|
|
233
270
|
.s-about-modal-row-meta[data-tone="danger"] {
|
|
234
271
|
border-color: rgb(var(--color-error) / 32%);
|
|
235
272
|
background: rgb(var(--color-error) / 10%);
|
|
236
|
-
color:
|
|
273
|
+
color: light-dark(
|
|
274
|
+
oklch(from rgb(var(--color-error)) min(l, 0.5) c h),
|
|
275
|
+
oklch(from rgb(var(--color-error)) max(l, 0.72) c h)
|
|
276
|
+
);
|
|
237
277
|
}
|
|
238
278
|
|
|
239
279
|
/* ── Links: licenses, external links, credits names and filings ───────── */
|
|
@@ -239,22 +239,44 @@ describe("HkAboutModal stylesheet contract", () => {
|
|
|
239
239
|
describe("row meta tones", () => {
|
|
240
240
|
const TONE = (tone: string) => `.s-about-modal-row-meta[data-tone=${tone}]`;
|
|
241
241
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
242
|
+
// Channel behind each coloured tone, and the WCAG-AA ink derived from it.
|
|
243
|
+
// The pill text is `--text-2xs` (10px) — small text, 4.5:1 — and the raw
|
|
244
|
+
// channel misses that on both shipped palettes (stock light warning sits
|
|
245
|
+
// at ~1.9:1, chest dark red at ~3.3:1). The ink is therefore an OKLCH
|
|
246
|
+
// derivation from the live channel: hue and chroma pass through, only
|
|
247
|
+
// lightness moves — capped at 0.5 in light mode, floored at 0.72 in dark
|
|
248
|
+
// (bounds solved so the worst stock AND chest entry clears 4.5:1 against
|
|
249
|
+
// the pill's real backdrop: the 10% channel tint over the 3%-primary
|
|
250
|
+
// card on `--color-surface`). Reverting any arm to the raw channel — or
|
|
251
|
+
// dropping one `light-dark()` side — must turn this red.
|
|
252
|
+
const AA_INK = (channel: string) =>
|
|
253
|
+
`light-dark(` +
|
|
254
|
+
`oklch(from rgb(var(--color-${channel})) min(l, 0.5) c h), ` +
|
|
255
|
+
`oklch(from rgb(var(--color-${channel})) max(l, 0.72) c h))`;
|
|
256
|
+
const TONES: Record<string, string> = {
|
|
257
|
+
positive: "success",
|
|
258
|
+
caution: "warning",
|
|
259
|
+
danger: "error",
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
it("paints every tone in the theme channel with its AA-derived ink", () => {
|
|
263
|
+
for (const [tone, channel] of Object.entries(TONES)) {
|
|
264
|
+
const rule = ruleBody(css, TONE(tone));
|
|
265
|
+
expect(rule, `the ${tone}-tone rule must survive compilation`).not.toBe("");
|
|
266
|
+
expect({
|
|
267
|
+
borderColor: declaration(rule, "border-color"),
|
|
268
|
+
background: declaration(rule, "background"),
|
|
269
|
+
color: declaration(rule, "color"),
|
|
270
|
+
}).toEqual({
|
|
271
|
+
// Same geometry across the tones, only the channel differs; the
|
|
272
|
+
// border and tint keep the RAW channel (decorative identity),
|
|
273
|
+
// while the glyphs get the derived ink. (Dart Sass compiles the
|
|
274
|
+
// seed-relative form without spaces around the slash.)
|
|
275
|
+
borderColor: `rgb(var(--color-${channel})/32%)`,
|
|
276
|
+
background: `rgb(var(--color-${channel})/10%)`,
|
|
277
|
+
color: AA_INK(channel),
|
|
278
|
+
});
|
|
279
|
+
}
|
|
258
280
|
});
|
|
259
281
|
});
|
|
260
282
|
});
|