diff --git a/assets/css/app.css b/assets/css/app.css
index f808696..b623a0c 100644
--- a/assets/css/app.css
+++ b/assets/css/app.css
@@ -417,11 +417,19 @@ button {
width: 0.8rem;
height: 0.8rem;
border-radius: 6px;
- background: rgba(255, 255, 255, 0.08);
+ background: rgba(132, 193, 208, 0.55);
+}
+
+.calendar-dot--bad {
+ background: rgba(255, 117, 117, 0.85);
+}
+
+.calendar-dot--warn {
+ background: rgba(255, 171, 122, 0.82);
}
.calendar-dot--1 {
- background: rgba(126, 239, 205, 0.32);
+ background: rgba(116, 226, 183, 0.7);
}
.calendar-dot--2 {
@@ -444,6 +452,24 @@ button {
font-size: 11px;
}
+.calendar-link {
+ cursor: pointer;
+}
+
+.calendar-cell--active {
+ transition: transform 140ms ease, filter 140ms ease, stroke 140ms ease, stroke-width 140ms ease;
+ transform-box: fill-box;
+ transform-origin: center;
+}
+
+.calendar-link:hover .calendar-cell--active,
+.calendar-link:focus .calendar-cell--active,
+.calendar-link:focus-visible .calendar-cell--active {
+ filter: brightness(1.08);
+ stroke: rgba(255, 255, 255, 0.8);
+ stroke-width: 1.1;
+}
+
.line-chart,
.bar-chart {
min-height: 17rem;
diff --git a/assets/js/app.js b/assets/js/app.js
index 1364b7d..18b4df1 100644
--- a/assets/js/app.js
+++ b/assets/js/app.js
@@ -366,6 +366,32 @@
return;
}
+ function calendarColor(entry) {
+ if (!entry) {
+ return "rgba(255, 255, 255, 0.06)";
+ }
+
+ const ratio = Math.max(0, Math.min(1, Number(entry.score) / Math.max(Number(entry.max || 1), 1)));
+
+ if (ratio <= 0.36) {
+ return `rgba(255, 117, 117, ${0.28 + (ratio * 0.8)})`;
+ }
+
+ if (ratio <= 0.52) {
+ return `rgba(255, 171, 122, ${0.28 + (ratio * 0.7)})`;
+ }
+
+ if (ratio <= 0.68) {
+ return `rgba(132, 193, 208, ${0.24 + (ratio * 0.55)})`;
+ }
+
+ if (ratio <= 0.84) {
+ return `rgba(116, 226, 183, ${0.28 + (ratio * 0.6)})`;
+ }
+
+ return `rgba(112, 240, 182, ${0.38 + (ratio * 0.52)})`;
+ }
+
const map = new Map(items.map(item => [item.date, item]));
const end = new Date();
const start = new Date(end);
@@ -386,12 +412,13 @@
cursor.setDate(cursor.getDate() + 1);
}
- const width = Math.ceil(days.length / 7) * 17 + 56;
+ const totalWeeks = Math.floor((days.length - 1) / 7) + 1;
const height = 148;
const cellSize = 12;
const cellGap = 5;
const xOffset = 34;
const yOffset = 24;
+ const width = xOffset + ((totalWeeks - 1) * (cellSize + cellGap)) + cellSize + 28;
const monthLabels = [];
let lastMonth = -1;
@@ -400,10 +427,7 @@
const row = item.weekday === 0 ? 6 : item.weekday - 1;
const x = xOffset + (week * (cellSize + cellGap));
const y = yOffset + (row * (cellSize + cellGap));
- const level = item.entry ? Math.max(0, Math.min(1, Number(item.entry.score) / Math.max(Number(item.entry.max || 1), 1))) : 0;
- const fill = item.entry
- ? `rgba(126, 239, 205, ${0.18 + (level * 0.72)})`
- : "rgba(255, 255, 255, 0.06)";
+ const fill = calendarColor(item.entry);
if (item.day <= 7 && item.month !== lastMonth) {
monthLabels.push({
@@ -417,7 +441,16 @@
? `${item.date}: ${formatNumber(Number(item.entry.score))} Punkte ยท ${item.entry.label}`
: `${item.date}: kein Eintrag`;
- return `