@@ -217,7 +219,7 @@ export async function render(container) {
const date = new Date(currentWeekStart);
date.setDate(date.getDate() + d);
const isToday = date.toDateString() === new Date().toDateString();
- html += `
${DAYS[d]}
${date.getDate()}
`;
@@ -289,6 +291,36 @@ export async function render(container) {
attachGridInteractions(cal);
+ // Open on the working day, not on midnight. A 24-hour grid that starts at 12am shows a new
+ // user four hours of empty night and hides the hours anything is actually scheduled in.
+ // Only on the first render, so it never yanks the view back while someone is scrolling.
+ const scroller = document.getElementById('calendarScroll');
+ if (scroller && !scroller.dataset.scrolled) {
+ scroller.dataset.scrolled = '1';
+ // Earliest scheduled hour if there is one, else the start of a normal working day.
+ const earliest = events.reduce((min, ev) => {
+ const d = new Date(ev.instance_start || ev.start_time);
+ return Math.min(min, d.getHours());
+ }, 24);
+ const target = Math.max(0, (earliest === 24 ? DEFAULT_SCROLL_HOUR : earliest) - 1);
+ // Straight grid arithmetic rather than offsetTop: the scroll container is not a positioned
+ // ancestor, so offsetTop is measured from the page body and carries the whole header stack
+ // with it — which scrolled the view hours past where it was aimed.
+ scroller.scrollTop = target * HOUR_PX;
+ }
+
+ // An empty grid teaches nothing on its own — it looks like a broken page rather than an
+ // invitation. Say what to do, without blocking the gesture it is describing.
+ document.querySelectorAll('.sched-empty-hint').forEach(n => n.remove());
+ if (!events.length && scroller) {
+ const hint = document.createElement('div');
+ hint.className = 'sched-empty-hint';
+ hint.textContent = t('schedule.drag_hint');
+ hint.style.cssText = 'margin:0 0 8px;padding:8px 12px;border-radius:8px;'
+ + 'background:var(--bg-secondary);border:1px solid var(--border);color:var(--text-muted);font-size:12px';
+ scroller.parentElement?.insertBefore(hint, scroller);
+ }
+
// Legend — only in all-screens mode, where the grid mixes targets. Sorted so the order
// is stable between reloads rather than following whatever the query happened to return.
const legend = document.getElementById('schedLegend');