fix: Monatswechsel-Markierung – Linien über Events, mehr Abstand, immer waagerecht

Vier Korrekturen:
- Linie verschwand hinter Events: Pseudo-Elemente mit z-index 4 statt
  box-shadow inset, damit Trennlinien immer über den Event-Bars liegen
- Waagerechte Linie auch bei Monatswechsel mitten in einer Zeile (vorher
  nur wenn der Monat am Zeilenanfang begann)
- "1" verschwand hinter Events: cell-day und month-marker bekommen
  z-index 3 + position relative, plus Events-Overlay wird in Zeilen mit
  Monatsmarker um ~26px nach unten geschoben
- Mehr Abstand zwischen Monatskürzel und Trennlinie (padding-top 8px,
  margin-bottom am marker positiv statt negativ)
This commit is contained in:
Scarriffle
2026-05-09 17:08:17 +02:00
parent 371678aac4
commit b120d9d430
2 changed files with 63 additions and 9 deletions

View File

@@ -499,17 +499,46 @@ a { color: var(--primary); text-decoration: none; }
.cell-day.today { background: var(--today-color); color: #fff; font-weight: 700; }
/* Month boundary marker: thicker line + month abbreviation on the 1st */
.month-col {
position: relative; /* anchor for divider pseudo-elements */
}
.month-col.first-of-month {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 0;
padding-top: 8px;
}
.month-col.month-divider-left {
box-shadow: inset 3px 0 0 0 var(--month-divider-color, #7090c0);
/* Dividers via pseudo-elements so they render above events (z-index 2) */
.month-col.month-divider-left::before {
content: '';
position: absolute;
left: 0; top: 0; bottom: 0;
width: 3px;
background: var(--month-divider-color, #7090c0);
z-index: 4;
pointer-events: none;
}
.month-col.month-divider-top::after {
content: '';
position: absolute;
top: 0; left: 0; right: 0;
height: 3px;
background: var(--month-divider-color, #7090c0);
z-index: 4;
pointer-events: none;
}
.month-row.month-divider-top {
box-shadow: inset 0 3px 0 0 var(--month-divider-color, #7090c0);
position: relative;
}
.month-row.month-divider-top::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0;
height: 3px;
background: var(--month-divider-color, #7090c0);
z-index: 4;
pointer-events: none;
}
.month-marker {
font-size: 14px;
@@ -519,7 +548,19 @@ a { color: var(--primary); text-decoration: none; }
color: var(--month-label-color, #7090c0);
line-height: 1;
padding: 0 2px;
margin-bottom: -2px;
margin-bottom: 2px;
position: relative;
z-index: 3; /* above events overlay (z-index 2) */
}
/* Make sure the day number stays visible above events */
.cell-day {
position: relative;
z-index: 3;
}
/* Push events overlay down when row contains a first-of-month cell so the
day "1" (which sits below the month marker) isn't hidden by event bars */
.month-row.has-month-marker .month-events-overlay {
top: 56px;
}
/* Events overlay — pointer-events:none so clicks pass to columns */
.month-events-overlay {

View File

@@ -120,6 +120,13 @@ export function renderMonth(container, currentDate, events, onDayClick, onEventC
style="left:${((c / 7) * 100).toFixed(3)}%;width:${(100 / 7).toFixed(3)}%;bottom:2px">${t('more_events', { n: count })}</div>`;
});
// Detect a month boundary in this row. monthChangeIdx is the index of
// the first-of-month cell, or -1 if the row doesn't span a month change.
let monthChangeIdx = -1;
rowCells.forEach((cell, idx) => {
if (cell.getDate() === 1 && idx > 0) monthChangeIdx = idx;
});
// Full-height column divs (click targets + borders)
const monthsShort = t('months_short');
let colsHtml = '';
@@ -134,9 +141,11 @@ export function renderMonth(container, currentDate, events, onDayClick, onEventC
// First-of-month marker: show month abbreviation, push day number below
const isFirstOfMonth = cell.getDate() === 1;
const firstCls = isFirstOfMonth ? 'first-of-month' : '';
// Add divider class on the cell BEFORE a month change (for right border styling)
// and on the cell AT a month change (for left border styling) — except at row start
const dividerCls = (isFirstOfMonth && idx > 0) ? 'month-divider-left' : '';
// Vertical line at month change, horizontal line spanning from change to end of row
const dividerClasses = [];
if (isFirstOfMonth && idx > 0) dividerClasses.push('month-divider-left');
if (monthChangeIdx > 0 && idx >= monthChangeIdx) dividerClasses.push('month-divider-top');
const dividerCls = dividerClasses.join(' ');
const monthLabel = isFirstOfMonth
? `<div class="month-marker">${monthsShort[cell.getMonth()]}</div>`
: '';
@@ -146,9 +155,13 @@ export function renderMonth(container, currentDate, events, onDayClick, onEventC
</div>`;
});
// If the row starts on the 1st of a new month, draw a divider above the row
// If the row starts on the 1st of a new month, draw a full-width divider above the row
const rowDividerCls = rowCells[0].getDate() === 1 ? 'month-divider-top' : '';
bodyHtml += `<div class="month-row ${rowDividerCls}">
// If any cell in the row is first-of-month, push events overlay down so the day
// number isn't hidden by spanning event bars
const hasMonthMarker = rowCells.some(c => c.getDate() === 1);
const rowMarkerCls = hasMonthMarker ? 'has-month-marker' : '';
bodyHtml += `<div class="month-row ${rowDividerCls} ${rowMarkerCls}">
<div class="month-kw-cell">${kw}</div>
<div class="month-row-right">
${colsHtml}