+
+ {/* Year grid lines */}
+ {yearMarkers.map(m => (
+
+ ))}
+
+ {/* Lane backgrounds */}
+ {(['long', 'medium', 'short'] as const).map(l => (
+
+ ))}
+
+ {/* Events */}
+ {events.map(ev => {
+ const x = toDay(ev.start_date) * SCALE
+ const w = evWidth(ev)
+ const y = laneY(ev.level)
+ const c = LEVEL_COLORS[ev.level]
+ const isSelected = refDate >= ev.start_date && (!ev.end_date || refDate <= ev.end_date)
+
+ return (
+
onDateChange(ev.start_date)}
+ title={`${ev.name}\n${ev.start_date}${ev.end_date ? ' → ' + ev.end_date : ' (en cours)'}`}
+ className="absolute flex items-center overflow-hidden rounded cursor-pointer transition-all"
+ style={{
+ left: x + 'px',
+ top: y + 3 + 'px',
+ width: w + 'px',
+ height: LANE_H - 6 + 'px',
+ background: isSelected
+ ? c.border
+ : c.bg,
+ border: `1px solid ${c.border}`,
+ opacity: isSelected ? 1 : 0.8,
+ zIndex: isSelected ? 10 : 1,
+ }}
+ >
+
+ {ev.name}
+
+
+ )
+ })}
+
+ {/* Today line */}
+
+
+ {/* Selected date line (if not today) */}
+ {refDate !== new Date().toISOString().split('T')[0] && (
+
+ )}
+
+ {/* Year axis */}
+
+ {yearMarkers.map(m => (
+
+ {m.label}
+
+ ))}
+
+
+ {/* Today label */}
+
+ ▲ aujourd'hui
+
+