diff --git a/src/app.js b/src/app.js
index 2afebc1..97674c2 100644
--- a/src/app.js
+++ b/src/app.js
@@ -989,20 +989,27 @@
parts.push(`${vText}h`);
}
+ const selYmd = ymd(selectedDay());
days.forEach((d, i) => {
const isToday = i === days.length - 1;
+ const isSel = d.ymd === selYmd;
const x = ML + i * (barW + gap);
const h = (d.sleepHours / yMax) * innerH;
const y = MT + innerH - h;
const title = `${d.date.toLocaleDateString(undefined, { weekday: "long", month: "short", day: "numeric" })} — ${d.sleepHours.toFixed(1)}h`;
+ if (isSel) {
+ parts.push(``);
+ }
parts.push(
`` +
`${escapeText(title)}`
);
- if (showDayLabel(i, days.length)) {
+ // The selected day always gets a label (accent-colored), even on wide
+ // windows that would otherwise skip it.
+ if (showDayLabel(i, days.length) || isSel) {
parts.push(
- `` +
+ `` +
`${escapeText(dayLabel(d.date, isToday))}`
);
}
@@ -1040,10 +1047,15 @@
{ key: "meals", label: "Meals", cls: "bar-eat" },
];
+ const selYmd = ymd(selectedDay());
days.forEach((d, i) => {
const isToday = i === days.length - 1;
+ const isSel = d.ymd === selYmd;
const groupX = ML + i * (groupW + groupGap);
+ if (isSel) {
+ parts.push(``);
+ }
series.forEach((s, j) => {
const val = d[s.key];
const x = groupX + j * (barW + innerBarGap);
@@ -1057,9 +1069,9 @@
);
});
- if (showDayLabel(i, days.length)) {
+ if (showDayLabel(i, days.length) || isSel) {
parts.push(
- `` +
+ `` +
`${escapeText(dayLabel(d.date, isToday))}`
);
}
@@ -1095,20 +1107,25 @@
parts.push(`${vText}`);
}
+ const selYmd = ymd(selectedDay());
days.forEach((d, i) => {
const isToday = i === days.length - 1;
+ const isSel = d.ymd === selYmd;
const x = ML + i * (barW + gap);
const h = (d.grams / yMax) * innerH;
const y = MT + innerH - h;
const title = `${d.date.toLocaleDateString(undefined, { weekday: "long", month: "short", day: "numeric" })} — ${Math.round(d.grams)} g`;
+ if (isSel) {
+ parts.push(``);
+ }
parts.push(
`` +
`${escapeText(title)}`
);
- if (showDayLabel(i, days.length)) {
+ if (showDayLabel(i, days.length) || isSel) {
parts.push(
- `` +
+ `` +
`${escapeText(dayLabel(d.date, isToday))}`
);
}
@@ -1157,15 +1174,17 @@
parts.push(`${hr}h`);
}
+ const selYmd = ymd(selectedDay());
for (let i = 0; i < N; i++) {
const day = new Date(today);
day.setDate(day.getDate() - (N - 1 - i)); // oldest at top, today at bottom
const dayStart = startOfDay(day).getTime();
const dayEnd = dayStart + dayMs;
const isToday = ymd(day) === ymd(new Date());
+ const isSel = ymd(day) === selYmd;
const y = MT + i * (rowH + rowGap);
- parts.push(``);
+ parts.push(``);
for (const wdw of windows) {
const s = Math.max(wdw.start, dayStart);
@@ -1177,7 +1196,7 @@
}
const label = isToday ? "Today" : `${day.toLocaleDateString(undefined, { weekday: "short" })} ${day.getDate()}`;
- parts.push(`${escapeText(label)}`);
+ parts.push(`${escapeText(label)}`);
const title = day.toLocaleDateString(undefined, { weekday: "long", month: "short", day: "numeric" });
parts.push(`${escapeText(title)}`);
@@ -1584,6 +1603,13 @@
const cellW = innerW / N;
const parts = [];
+ const selCol = dayIndex.get(ymd(selectedDay()));
+ if (selCol !== undefined) {
+ parts.push(
+ ``
+ );
+ }
exercises.forEach((x, r) => {
const y = MT + r * (rowH + rowGap);
const max = Math.max(1, ...counts[r]);
diff --git a/src/changelog.json b/src/changelog.json
index 9cbd70d..957c980 100644
--- a/src/changelog.json
+++ b/src/changelog.json
@@ -1,4 +1,5 @@
[
+ { "date": "2026-07-15", "text": "The charts highlight the selected day, so it's easy to spot which bars, rows and cells you're looking at" },
{ "date": "2026-07-15", "text": "New Sleep trend chart: today's running sleep total through the day, against yesterday and the average over your chart window (7/14/30 days)" },
{ "date": "2026-07-15", "text": "Quick actions that don't fit right now are dimmed (asleep → everything but Sleep end; awake → Sleep end) — still tappable for corrections" },
{ "date": "2026-07-15", "text": "Editing an event no longer pops the date picker over the whole screen on iPhone" },
diff --git a/src/style.css b/src/style.css
index 0a88327..c68f044 100644
--- a/src/style.css
+++ b/src/style.css
@@ -603,6 +603,16 @@ dialog menu {
}
.chart-svg .bar { cursor: pointer; }
.chart-svg .bar-faded { opacity: 0.7; }
+/* The selected day's slice in every per-day chart: a soft accent band behind
+ the bars/cells (visible even when the day's values are all zero) plus an
+ accent-colored day label. */
+.chart-svg .day-highlight {
+ fill: var(--accent);
+ fill-opacity: 0.08;
+ stroke: var(--accent);
+ stroke-opacity: 0.45;
+}
+.chart-svg text.day-label-sel { fill: var(--accent); font-weight: 600; }
.chart-svg .bar-sleep { fill: var(--sleep); }
.chart-svg .bar-pee { fill: var(--pee); }
.chart-svg .bar-poo { fill: var(--poo); }
@@ -897,6 +907,13 @@ input.switch:checked::after { transform: translateX(18px); }
}
.chart-svg .stl-sleep { fill: var(--sleep); }
.chart-svg .stl-today { fill: var(--accent); font-weight: 600; }
+/* Selected day: accent ring on the row's track + accent label. */
+.chart-svg .stl-track.stl-selected {
+ stroke: var(--accent);
+ stroke-width: 1.2;
+ stroke-opacity: 0.8;
+}
+.chart-svg .stl-sel { fill: var(--accent); }
.chart-svg .stl-hit { fill: transparent; cursor: pointer; }
.chart-svg .stl-hit:hover { fill: var(--accent); fill-opacity: 0.08; }