fix(a11y): raise faint ink text to meet WCAG AA contrast

Dim text tokens (base-content/40-50, #4f7099) sat at 3.0-4.1:1 on the
navy paper, below the 4.5:1 minimum. Brighten text uses to #7ea6cd
(~6:1) and split the overloaded --ink-faint into --ink-dim so borders,
stripes and diagram edges keep their intended faintness.
This commit is contained in:
Julien Calixte
2026-07-02 23:05:53 +02:00
parent 6264c9959b
commit 9c8ba9a752
8 changed files with 40 additions and 38 deletions

View File

@@ -31,7 +31,7 @@
color: var(--color-secondary); color: var(--color-secondary);
} }
.sub { .sub {
color: #4f7099; color: #7ea6cd;
font-size: 11px; font-size: 11px;
letter-spacing: 0.04em; letter-spacing: 0.04em;
} }

View File

@@ -104,7 +104,7 @@ const funcCount = computed(() => props.blueprint.functions.length)
<div class="flex flex-wrap items-baseline gap-2"> <div class="flex flex-wrap items-baseline gap-2">
<span class="text-lg font-bold tracking-wide text-secondary">FULL VIEW</span> <span class="text-lg font-bold tracking-wide text-secondary">FULL VIEW</span>
</div> </div>
<p class="mb-4 mt-1 text-xs text-base-content/50"> <p class="mb-4 mt-1 text-xs text-base-content/75">
The standard composition and its {{ funcCount }} functions. Select a function above to The standard composition and its {{ funcCount }} functions. Select a function above to
focus it. focus it.
</p> </p>
@@ -208,7 +208,7 @@ code {
padding: 8px 12px; padding: 8px 12px;
} }
.tb-k { .tb-k {
color: #4f7099; color: #7ea6cd;
font-size: 10px; font-size: 10px;
letter-spacing: 0.14em; letter-spacing: 0.14em;
text-transform: uppercase; text-transform: uppercase;
@@ -364,7 +364,7 @@ code {
background: rgba(255, 255, 255, 0.02); background: rgba(255, 255, 255, 0.02);
} }
.panel .cap .id { .panel .cap .id {
color: #4f7099; color: #7ea6cd;
} }
.panel .body { .panel .body {
padding: 16px; padding: 16px;
@@ -384,7 +384,7 @@ code {
font-size: 10px; font-size: 10px;
letter-spacing: 0.16em; letter-spacing: 0.16em;
text-transform: uppercase; text-transform: uppercase;
color: color-mix(in srgb, var(--color-base-content) 50%, transparent); color: color-mix(in srgb, var(--color-base-content) 75%, transparent);
margin-bottom: 0.35rem; margin-bottom: 0.35rem;
} }
.rk .rule { .rk .rule {
@@ -425,7 +425,7 @@ code {
color: var(--color-secondary); color: var(--color-secondary);
} }
.sig-note { .sig-note {
color: #4f7099; color: #7ea6cd;
} }
.sig-types { .sig-types {
margin-top: 8px; margin-top: 8px;
@@ -459,7 +459,7 @@ code {
margin-top: 34px; margin-top: 34px;
padding-top: 14px; padding-top: 14px;
border-top: 1px solid rgba(200, 226, 255, 0.14); border-top: 1px solid rgba(200, 226, 255, 0.14);
color: #4f7099; color: #7ea6cd;
font-size: 11px; font-size: 11px;
line-height: 1.8; line-height: 1.8;
} }

View File

@@ -8,7 +8,8 @@ const PAL = {
boxFill: "#103763", boxFill: "#103763",
boxStroke: "#3d5f85", boxStroke: "#3d5f85",
ink: "#dbe9f7", ink: "#dbe9f7",
inkFaint: "#4f7099", inkFaint: "#4f7099", // decorative edges only
inkDim: "#7ea6cd", // dim text — meets WCAG AA on navy paper
cyan: "#8fd0ff", cyan: "#8fd0ff",
amber: "#ffb84d", amber: "#ffb84d",
} }
@@ -94,7 +95,7 @@ const edges = computed(() =>
stroke-width="1.5" stroke-width="1.5"
/> />
<text :x="b.x + 12" :y="b.y + 15" :fill="PAL.ink" font-size="12">{{ b.label }}</text> <text :x="b.x + 12" :y="b.y + 15" :fill="PAL.ink" font-size="12">{{ b.label }}</text>
<text :x="b.x + 12" :y="b.y + 27" :fill="PAL.inkFaint" font-size="9.5">{{ b.sub }}</text> <text :x="b.x + 12" :y="b.y + 27" :fill="PAL.inkDim" font-size="9.5">{{ b.sub }}</text>
</g> </g>
<g v-for="b in rightBoxes" :key="b.label"> <g v-for="b in rightBoxes" :key="b.label">
@@ -111,12 +112,10 @@ const edges = computed(() =>
<text :x="b.x + 12" :y="b.y + 21" :fill="PAL.amber" font-size="12">{{ b.label }}</text> <text :x="b.x + 12" :y="b.y + 21" :fill="PAL.amber" font-size="12">{{ b.label }}</text>
</g> </g>
<text :x="lx" :y="H - 4" :fill="PAL.inkFaint" font-size="10" letter-spacing="1.5"> <text :x="lx" :y="H - 4" :fill="PAL.inkDim" font-size="10" letter-spacing="1.5">
CAPABILITIES (compose onto host) CAPABILITIES (compose onto host)
</text> </text>
<text :x="rx" :y="H - 4" :fill="PAL.inkFaint" font-size="10" letter-spacing="1.5"> <text :x="rx" :y="H - 4" :fill="PAL.inkDim" font-size="10" letter-spacing="1.5">FUNCTIONS</text>
FUNCTIONS
</text>
</svg> </svg>
</template> </template>

View File

@@ -16,13 +16,13 @@ defineProps<{ fn: BlueprintFunction }>()
>{{ c }}</span >{{ c }}</span
> >
</div> </div>
<p class="mb-4 mt-1 text-xs text-base-content/50">{{ fn.verb }}</p> <p class="mb-4 mt-1 text-xs text-base-content/75">{{ fn.verb }}</p>
<section v-if="fn.state.length" class="block-sec"> <section v-if="fn.state.length" class="block-sec">
<div class="k"><span>State touched</span><span class="rule" /></div> <div class="k"><span>State touched</span><span class="rule" /></div>
<div v-for="[name, type] in fn.state" :key="name" class="flex gap-2"> <div v-for="[name, type] in fn.state" :key="name" class="flex gap-2">
<span>{{ name }}</span <span>{{ name }}</span
><span class="text-base-content/40">:</span><span class="text-secondary">{{ type }}</span> ><span class="text-base-content/70">:</span><span class="text-secondary">{{ type }}</span>
</div> </div>
</section> </section>
@@ -34,11 +34,11 @@ defineProps<{ fn: BlueprintFunction }>()
<div v-for="b in fn.behaviors" :key="b.sig" class="beh"> <div v-for="b in fn.behaviors" :key="b.sig" class="beh">
<div class="text-accent">{{ b.sig }}</div> <div class="text-accent">{{ b.sig }}</div>
<div class="flex gap-2 text-xs text-base-content/70"> <div class="flex gap-2 text-xs text-base-content/70">
<span class="w-7 shrink-0 text-base-content/40">pre</span <span class="w-7 shrink-0 text-base-content/70">pre</span
><span class="text-base-content">{{ b.pre }}</span> ><span class="text-base-content">{{ b.pre }}</span>
</div> </div>
<div class="flex gap-2 text-xs text-base-content/70"> <div class="flex gap-2 text-xs text-base-content/70">
<span class="w-7 shrink-0 text-base-content/40">eff</span <span class="w-7 shrink-0 text-base-content/70">eff</span
><span class="text-base-content">{{ b.eff }}</span> ><span class="text-base-content">{{ b.eff }}</span>
</div> </div>
</div> </div>
@@ -71,7 +71,7 @@ defineProps<{ fn: BlueprintFunction }>()
</ul> </ul>
</section> </section>
<p v-for="n in fn.notes" :key="n" class="text-[11px] italic text-base-content/40"> {{ n }}</p> <p v-for="n in fn.notes" :key="n" class="text-[11px] italic text-base-content/70"> {{ n }}</p>
</div> </div>
</template> </template>
@@ -100,7 +100,7 @@ defineProps<{ fn: BlueprintFunction }>()
font-size: 10px; font-size: 10px;
letter-spacing: 0.16em; letter-spacing: 0.16em;
text-transform: uppercase; text-transform: uppercase;
color: color-mix(in srgb, var(--color-base-content) 50%, transparent); color: color-mix(in srgb, var(--color-base-content) 75%, transparent);
margin-bottom: 0.35rem; margin-bottom: 0.35rem;
} }
.k .rule { .k .rule {

View File

@@ -261,7 +261,8 @@ function barStyle(e: MonthEvent) {
<style scoped> <style scoped>
.specimen { .specimen {
--ink: var(--color-base-content); --ink: var(--color-base-content);
--ink-faint: #4f7099; --ink-faint: #4f7099; /* decorative only: borders, stripes, fills */
--ink-dim: #7ea6cd; /* dim text — meets WCAG AA on navy paper */
--amber: var(--color-accent); --amber: var(--color-accent);
--amber-dim: color-mix(in srgb, var(--color-accent) 14%, transparent); --amber-dim: color-mix(in srgb, var(--color-accent) 14%, transparent);
--cyan: var(--color-secondary); --cyan: var(--color-secondary);
@@ -272,7 +273,7 @@ function barStyle(e: MonthEvent) {
font-size: 13px; font-size: 13px;
} }
.note { .note {
color: var(--ink-faint); color: var(--ink-dim);
font-size: 11px; font-size: 11px;
font-style: italic; font-style: italic;
margin: 0 0 10px; margin: 0 0 10px;
@@ -311,7 +312,7 @@ function barStyle(e: MonthEvent) {
.scope-btn { .scope-btn {
padding: 4px 11px; padding: 4px 11px;
font-size: 11px; font-size: 11px;
color: var(--ink-faint); color: var(--ink-dim);
border-left: 1px solid var(--line); border-left: 1px solid var(--line);
} }
.scope-btn:first-child { .scope-btn:first-child {
@@ -338,7 +339,7 @@ function barStyle(e: MonthEvent) {
letter-spacing: 0.08em; letter-spacing: 0.08em;
} }
.badge-note { .badge-note {
color: var(--ink-faint); color: var(--ink-dim);
} }
/* month grid */ /* month grid */
@@ -383,7 +384,7 @@ function barStyle(e: MonthEvent) {
color: color-mix(in srgb, var(--ink) 70%, transparent); color: color-mix(in srgb, var(--ink) 70%, transparent);
} }
.daycell.adjacent .dnum { .daycell.adjacent .dnum {
color: var(--ink-faint); color: var(--ink-dim);
opacity: 0.55; opacity: 0.55;
} }
/* event bars, positioned over the day cells of their week */ /* event bars, positioned over the day cells of their week */
@@ -465,7 +466,7 @@ function barStyle(e: MonthEvent) {
.wk-hour { .wk-hour {
padding: 6px; padding: 6px;
font-size: 10px; font-size: 10px;
color: var(--ink-faint); color: var(--ink-dim);
border-right: 1px solid var(--line); border-right: 1px solid var(--line);
text-align: right; text-align: right;
} }

View File

@@ -263,7 +263,8 @@ const gridStyle = computed(() => ({ gridTemplateColumns: `repeat(${frame.value.c
<style scoped> <style scoped>
.specimen { .specimen {
--ink: var(--color-base-content); --ink: var(--color-base-content);
--ink-faint: #4f7099; --ink-faint: #4f7099; /* decorative only: borders, stripes, fills */
--ink-dim: #7ea6cd; /* dim text — meets WCAG AA on navy paper */
--amber: var(--color-accent); --amber: var(--color-accent);
--amber-dim: color-mix(in srgb, var(--color-accent) 14%, transparent); --amber-dim: color-mix(in srgb, var(--color-accent) 14%, transparent);
--cyan: var(--color-secondary); --cyan: var(--color-secondary);
@@ -274,7 +275,7 @@ const gridStyle = computed(() => ({ gridTemplateColumns: `repeat(${frame.value.c
font-size: 13px; font-size: 13px;
} }
.note { .note {
color: var(--ink-faint); color: var(--ink-dim);
font-size: 11px; font-size: 11px;
font-style: italic; font-style: italic;
margin: 0 0 10px; margin: 0 0 10px;
@@ -288,7 +289,7 @@ const gridStyle = computed(() => ({ gridTemplateColumns: `repeat(${frame.value.c
font-size: 12px; font-size: 12px;
} }
.badge-note { .badge-note {
color: var(--ink-faint); color: var(--ink-dim);
} }
.search { .search {
flex: 1; flex: 1;
@@ -298,7 +299,7 @@ const gridStyle = computed(() => ({ gridTemplateColumns: `repeat(${frame.value.c
color: var(--ink); color: var(--ink);
} }
.ph { .ph {
color: var(--ink-faint); color: var(--ink-dim);
} }
.q { .q {
color: var(--amber); color: var(--amber);
@@ -452,7 +453,7 @@ const gridStyle = computed(() => ({ gridTemplateColumns: `repeat(${frame.value.c
.empty-state { .empty-state {
padding: 16px 12px; padding: 16px 12px;
text-align: center; text-align: center;
color: var(--ink-faint); color: var(--ink-dim);
} }
.empty-state .big { .empty-state .big {
font-size: 22px; font-size: 22px;

View File

@@ -314,7 +314,8 @@ const frame = computed<Frame>(() => {
<style scoped> <style scoped>
.specimen { .specimen {
--ink: var(--color-base-content); --ink: var(--color-base-content);
--ink-faint: #4f7099; --ink-faint: #4f7099; /* decorative only: borders, stripes, fills */
--ink-dim: #7ea6cd; /* dim text — meets WCAG AA on navy paper */
--amber: var(--color-accent); --amber: var(--color-accent);
--amber-dim: color-mix(in srgb, var(--color-accent) 14%, transparent); --amber-dim: color-mix(in srgb, var(--color-accent) 14%, transparent);
--cyan: var(--color-secondary); --cyan: var(--color-secondary);
@@ -325,7 +326,7 @@ const frame = computed<Frame>(() => {
font-size: 13px; font-size: 13px;
} }
.note { .note {
color: var(--ink-faint); color: var(--ink-dim);
font-size: 11px; font-size: 11px;
font-style: italic; font-style: italic;
margin: 0 0 10px; margin: 0 0 10px;
@@ -339,7 +340,7 @@ const frame = computed<Frame>(() => {
font-size: 12px; font-size: 12px;
} }
.badge-note { .badge-note {
color: var(--ink-faint); color: var(--ink-dim);
} }
.search { .search {
flex: 1; flex: 1;
@@ -349,7 +350,7 @@ const frame = computed<Frame>(() => {
color: var(--ink); color: var(--ink);
} }
.ph { .ph {
color: var(--ink-faint); color: var(--ink-dim);
} }
.q { .q {
color: var(--amber); color: var(--amber);
@@ -412,7 +413,7 @@ const frame = computed<Frame>(() => {
color: var(--ink); color: var(--ink);
} }
.txt .s { .txt .s {
color: var(--ink-faint); color: var(--ink-dim);
font-size: 11px; font-size: 11px;
} }
.chev { .chev {
@@ -474,7 +475,7 @@ const frame = computed<Frame>(() => {
color: var(--red); color: var(--red);
} }
.swipehint { .swipehint {
color: var(--ink-faint); color: var(--ink-dim);
font-size: 10px; font-size: 10px;
margin-left: auto; margin-left: auto;
padding-right: 8px; padding-right: 8px;
@@ -545,7 +546,7 @@ const frame = computed<Frame>(() => {
.empty-state { .empty-state {
padding: 20px 12px; padding: 20px 12px;
text-align: center; text-align: center;
color: var(--ink-faint); color: var(--ink-dim);
} }
.empty-state .big { .empty-state .big {
font-size: 22px; font-size: 22px;

View File

@@ -112,7 +112,7 @@ import { BLUEPRINTS } from "@/data/blueprints"
.c-meta { .c-meta {
display: flex; display: flex;
gap: 14px; gap: 14px;
color: #4f7099; color: #7ea6cd;
font-size: 11px; font-size: 11px;
} }
.c-open { .c-open {