diff --git a/messages/de.json b/messages/de.json
index cb5657f98..4dcc47c51 100644
--- a/messages/de.json
+++ b/messages/de.json
@@ -13727,6 +13727,7 @@
"valuesAllOther": "Alle {count} Werte",
"valuesFewer": "Weniger Werte",
"gkiPair": "Blutzucker {glucose} {unit} / Ketone {ketones} {unit}",
+ "gkiPairShort": "{glucose} / {ketones} {unit}",
"gkiCountOne": "Letzter von {count}",
"gkiCountFew": "Letzter von {count}",
"gkiCountOther": "Letzter von {count}",
diff --git a/messages/en.json b/messages/en.json
index cdc7a3e1c..9e7437925 100644
--- a/messages/en.json
+++ b/messages/en.json
@@ -13727,6 +13727,7 @@
"valuesAllOther": "All {count} values",
"valuesFewer": "Fewer values",
"gkiPair": "Glucose {glucose} {unit} / ketones {ketones} {unit}",
+ "gkiPairShort": "{glucose} / {ketones} {unit}",
"gkiCountOne": "Latest of {count}",
"gkiCountFew": "Latest of {count}",
"gkiCountOther": "Latest of {count}",
diff --git a/messages/es.json b/messages/es.json
index f1fe3f6dc..ed699f11e 100644
--- a/messages/es.json
+++ b/messages/es.json
@@ -13727,6 +13727,7 @@
"valuesAllOther": "Los {count} valores",
"valuesFewer": "Menos valores",
"gkiPair": "Glucosa {glucose} {unit} / cetonas {ketones} {unit}",
+ "gkiPairShort": "{glucose} / {ketones} {unit}",
"gkiCountOne": "Último de {count}",
"gkiCountFew": "Último de {count}",
"gkiCountOther": "Último de {count}",
diff --git a/messages/fr.json b/messages/fr.json
index 9d314b68a..ee58ad000 100644
--- a/messages/fr.json
+++ b/messages/fr.json
@@ -13727,6 +13727,7 @@
"valuesAllOther": "Les {count} valeurs",
"valuesFewer": "Moins de valeurs",
"gkiPair": "Glycémie {glucose} {unit} / cétones {ketones} {unit}",
+ "gkiPairShort": "{glucose} / {ketones} {unit}",
"gkiCountOne": "Dernier sur {count}",
"gkiCountFew": "Dernier sur {count}",
"gkiCountOther": "Dernier sur {count}",
diff --git a/messages/it.json b/messages/it.json
index 76cd79a7d..dd6ed5138 100644
--- a/messages/it.json
+++ b/messages/it.json
@@ -13727,6 +13727,7 @@
"valuesAllOther": "Tutti i {count} valori",
"valuesFewer": "Meno valori",
"gkiPair": "Glicemia {glucose} {unit} / chetoni {ketones} {unit}",
+ "gkiPairShort": "{glucose} / {ketones} {unit}",
"gkiCountOne": "Ultimo di {count}",
"gkiCountFew": "Ultimo di {count}",
"gkiCountOther": "Ultimo di {count}",
diff --git a/messages/ko.json b/messages/ko.json
index 7d3a9009e..07e82b974 100644
--- a/messages/ko.json
+++ b/messages/ko.json
@@ -13727,6 +13727,7 @@
"valuesAllOther": "수치 {count}개 모두",
"valuesFewer": "수치 줄여 보기",
"gkiPair": "혈당 {glucose} {unit} / 케톤 {ketones} {unit}",
+ "gkiPairShort": "{glucose} / {ketones} {unit}",
"gkiCountOne": "{count}개 중 최근",
"gkiCountFew": "{count}개 중 최근",
"gkiCountOther": "{count}개 중 최근",
diff --git a/messages/nl.json b/messages/nl.json
index ffbcddc34..70a91d880 100644
--- a/messages/nl.json
+++ b/messages/nl.json
@@ -13727,6 +13727,7 @@
"valuesAllOther": "Alle {count} waarden",
"valuesFewer": "Minder waarden",
"gkiPair": "Glucose {glucose} {unit} / ketonen {ketones} {unit}",
+ "gkiPairShort": "{glucose} / {ketones} {unit}",
"gkiCountOne": "Laatste van {count}",
"gkiCountFew": "Laatste van {count}",
"gkiCountOther": "Laatste van {count}",
diff --git a/messages/pl.json b/messages/pl.json
index 56015a3d5..1b7aa0d98 100644
--- a/messages/pl.json
+++ b/messages/pl.json
@@ -13727,6 +13727,7 @@
"valuesAllOther": "Wszystkie {count} wartości",
"valuesFewer": "Mniej wartości",
"gkiPair": "Glukoza {glucose} {unit} / ketony {ketones} {unit}",
+ "gkiPairShort": "{glucose} / {ketones} {unit}",
"gkiCountOne": "Ostatni z {count}",
"gkiCountFew": "Ostatni z {count}",
"gkiCountOther": "Ostatni z {count}",
diff --git a/messages/pt-BR.json b/messages/pt-BR.json
index 5e354a4ef..bfc4635be 100644
--- a/messages/pt-BR.json
+++ b/messages/pt-BR.json
@@ -13727,6 +13727,7 @@
"valuesAllOther": "Todos os {count} valores",
"valuesFewer": "Menos valores",
"gkiPair": "Glicose {glucose} {unit} / cetonas {ketones} {unit}",
+ "gkiPairShort": "{glucose} / {ketones} {unit}",
"gkiCountOne": "Último de {count}",
"gkiCountFew": "Último de {count}",
"gkiCountOther": "Último de {count}",
diff --git a/messages/ru.json b/messages/ru.json
index fd3b9d550..2324e9e46 100644
--- a/messages/ru.json
+++ b/messages/ru.json
@@ -13727,6 +13727,7 @@
"valuesAllOther": "Все {count} значений",
"valuesFewer": "Меньше значений",
"gkiPair": "Глюкоза {glucose} {unit} / кетоны {ketones} {unit}",
+ "gkiPairShort": "{glucose} / {ketones} {unit}",
"gkiCountOne": "Последний из {count}",
"gkiCountFew": "Последний из {count}",
"gkiCountOther": "Последний из {count}",
diff --git a/src/components/day/__tests__/day-gki-tile.test.tsx b/src/components/day/__tests__/day-gki-tile.test.tsx
new file mode 100644
index 000000000..d48cbe9b6
--- /dev/null
+++ b/src/components/day/__tests__/day-gki-tile.test.tsx
@@ -0,0 +1,60 @@
+import { describe, expect, it } from "vitest";
+import { renderToStaticMarkup } from "react-dom/server";
+
+import { locales } from "@/lib/i18n/config";
+
+/**
+ * The GKI tile sits in a two-column grid, about 150 px of text wide at phone
+ * width and in the 420 px day layer alike. The pair line under the index has
+ * to fit there whole, so both readings stay readable; the worded pair goes to
+ * assistive tech.
+ */
+
+const POINT = {
+ at: "2026-11-01T08:00:00.000Z",
+ value: 3.8,
+ ketoneId: "k1",
+ glucoseId: "g1",
+ glucoseAt: "2026-11-01T08:00:00.000Z",
+ ketonesMmol: 0.25,
+ glucoseMmol: 12.5,
+};
+
+async function render(locale: string) {
+ const { I18nProvider } = await import("@/lib/i18n/context");
+ const { DayGkiTile } = await import("../day-gki-tile");
+ const messages = (await import(`../../../../messages/${locale}.json`))
+ .default;
+ return renderToStaticMarkup(
+
+
+ ,
+ );
+}
+
+function visiblePair(html: string): string {
+ const match = html.match(
+ /([^<]*)<\/span>/,
+ );
+ if (!match) throw new Error(`no visible pair line in ${html}`);
+ return match[1]!;
+}
+
+describe("", () => {
+ it.each([...locales])(
+ "keeps the pair line short enough for the tile in %s",
+ async (locale) => {
+ const line = visiblePair(await render(locale));
+ expect(line).toMatch(/12[.,]5/);
+ expect(line).toMatch(/0[.,]25/);
+ expect(line.length).toBeLessThanOrEqual(20);
+ },
+ );
+
+ it("names both readings for assistive tech", async () => {
+ const html = await render("en");
+ expect(html).toMatch(
+ /Glucose 12\.5 mmol\/L \/ ketones 0\.25 mmol\/L<\/span>/,
+ );
+ });
+});
diff --git a/src/components/day/day-gki-tile.tsx b/src/components/day/day-gki-tile.tsx
index ed29214d2..cd3f006c3 100644
--- a/src/components/day/day-gki-tile.tsx
+++ b/src/components/day/day-gki-tile.tsx
@@ -23,6 +23,14 @@ export function DayGkiTile({ points }: { points: readonly DayGki[] }) {
const fmt = useFormatters();
const latest = points[points.length - 1];
if (!latest) return null;
+ const pair = {
+ glucose: fmt.number(latest.glucoseMmol, 1),
+ ketones: fmt.number(
+ latest.ketonesMmol,
+ ketoneFractionDigits(latest.ketonesMmol),
+ ),
+ unit: GKI_COMPONENT_UNIT,
+ };
return (
{fmt.number(latest.value, 1)}
-
- {points.length > 1
- ? tCount("day.gkiCount", points.length)
- : t("day.gkiPair", {
- glucose: fmt.number(latest.glucoseMmol, 1),
- ketones: fmt.number(
- latest.ketonesMmol,
- ketoneFractionDigits(latest.ketonesMmol),
- ),
- unit: GKI_COMPONENT_UNIT,
- })}
-
+ {points.length > 1 ? (
+
+ {tCount("day.gkiCount", points.length)}
+
+ ) : (
+ <>
+ {/* The tile is about 150 px of text wide: the numbers alone fit,
+ the worded pair is for assistive tech. */}
+
+ {t("day.gkiPairShort", pair)}
+
+ {t("day.gkiPair", pair)}
+ >
+ )}
);