From 93c23c594ccd779a004d72648e8229f11e3e93cb Mon Sep 17 00:00:00 2001 From: Leo Vasanko Date: Wed, 20 Aug 2025 14:57:04 -0600 Subject: [PATCH] Cleanup, layout fixes, better event colors. --- calendar-main.css | 6 ++++++ calendar.js | 42 +++++++++++++----------------------------- colors.css | 39 ++++++++++++++++++++++++++++++++------- events.css | 6 ++---- layout.css | 10 +++++----- 5 files changed, 58 insertions(+), 45 deletions(-) create mode 100644 calendar-main.css diff --git a/calendar-main.css b/calendar-main.css new file mode 100644 index 0000000..9597771 --- /dev/null +++ b/calendar-main.css @@ -0,0 +1,6 @@ +/* Calendar CSS - Main file with imports */ +@import url('colors.css'); +@import url('layout.css'); +@import url('cells.css'); +@import url('events.css'); +@import url('utilities.css'); diff --git a/calendar.js b/calendar.js index 0e6d13e..165d438 100644 --- a/calendar.js +++ b/calendar.js @@ -113,7 +113,7 @@ class InfiniteCalendar { const handleWheel = e => { e.preventDefault() e.stopPropagation() - const currentYear = parseInt(this.weekLabel.textContent) + const currentYear = parseInt(this.yearLabel.textContent) const topDisplayIndex = Math.floor(this.viewport.scrollTop / this.rowHeight) const currentWeekIndex = topDisplayIndex + this.minVirtualWeek const sensitivity = 1/3 @@ -125,7 +125,7 @@ class InfiniteCalendar { this.navigateToYear(newYear, currentWeekIndex) setTimeout(() => throttled = false, 100) } - this.weekLabel.addEventListener('wheel', handleWheel, { passive: false }) + this.yearLabel.addEventListener('wheel', handleWheel, { passive: false }) } navigateTo(date) { @@ -206,15 +206,15 @@ class InfiniteCalendar { } createHeader() { - this.weekLabel = document.createElement('div') - this.weekLabel.className = 'dow-label' - this.weekLabel.textContent = isoWeekInfo(new Date()).year - this.header.appendChild(this.weekLabel) + this.yearLabel = document.createElement('div') + this.yearLabel.className = 'year-label' + this.yearLabel.textContent = isoWeekInfo(new Date()).year + this.header.appendChild(this.yearLabel) const names = this.getLocalizedWeekdayNames() names.forEach((name, i) => { const c = document.createElement('div') - c.className = 'cell dow' + c.classList.add('dow') const dayIdx = (i + 1) % 7 if (this.weekend[dayIdx]) c.classList.add('weekend') c.textContent = name @@ -294,7 +294,7 @@ class InfiniteCalendar { const topVW = topDisplayIndex + this.minVirtualWeek const monday = this.getMondayForVirtualWeek(topVW) const { year } = isoWeekInfo(monday) - if (this.weekLabel.textContent !== String(year)) this.weekLabel.textContent = year + if (this.yearLabel.textContent !== String(year)) this.yearLabel.textContent = year } createWeekElement(virtualWeek) { @@ -626,7 +626,7 @@ class InfiniteCalendar { title: eventData.title, startDate: eventData.startDate, endDate: eventData.endDate, - color: this.generateEventColor() + colorId: this.generateEventColorId() } const startDate = new Date(fromLocalString(event.startDate)) @@ -641,12 +641,9 @@ class InfiniteCalendar { this.refreshEvents() } - generateEventColor() { - const colors = [ - '#ff6b6b', '#4ecdc4', '#45b7d1', '#96ceb4', '#feca57', - '#ff9ff3', '#54a0ff', '#5f27cd', '#00d2d3', '#ff9f43' - ] - return colors[Math.floor(Math.random() * colors.length)] + generateEventColorId() { + // Return a color ID from 0-11 for 12 evenly spaced hues + return Math.floor(Math.random() * 12) } refreshEvents() { @@ -705,22 +702,9 @@ class InfiniteCalendar { createOverlaySpan(overlay, w) { const span = document.createElement('div') - span.className = 'event-span' + span.className = `event-span event-color-${w.colorId}` span.style.gridColumn = `${w.startIdx + 1} / ${w.endIdx + 2}` span.style.gridRow = `${w._row}` - span.style.height = '1.2em' - span.style.borderRadius = '.4em' - span.style.fontSize = '.75em' - span.style.lineHeight = '1.2' - span.style.padding = '0 .5em' - span.style.whiteSpace = 'nowrap' - span.style.overflow = 'hidden' - span.style.textOverflow = 'ellipsis' - span.style.background = w.color - span.style.color = 'white' - span.style.fontWeight = '600' - span.style.pointerEvents = 'auto' - span.style.zIndex = '1' span.textContent = w.title span.title = `${w.title} (${w.startDate === w.endDate ? w.startDate : w.startDate + ' - ' + w.endDate})` overlay.appendChild(span) diff --git a/colors.css b/colors.css index dcbb2c2..8405899 100644 --- a/colors.css +++ b/colors.css @@ -1,10 +1,9 @@ /* Color tokens */ :root { - --bg: #f6f7fb; --panel: #fff; --today: #f83; - --ink: #111; - --ink-rgb: 17, 17, 17; + --ink: #222; + --inkstrong: #000; --muted: #888; --weekend: #888; --firstday: #000; @@ -27,14 +26,26 @@ .oct { background: hsl(18 78% 95%) } .nov { background: hsl(18 78% 88%) } +.event-color-0 { background: hsl(0, 40%, 80%); } +.event-color-1 { background: hsl(30, 40%, 80%); } +.event-color-2 { background: hsl(60, 40%, 80%); } +.event-color-3 { background: hsl(90, 40%, 80%); } +.event-color-4 { background: hsl(120, 40%, 80%); } +.event-color-5 { background: hsl(150, 40%, 80%); } +.event-color-6 { background: hsl(180, 40%, 80%); } +.event-color-7 { background: hsl(210, 40%, 80%); } +.event-color-8 { background: hsl(240, 40%, 80%); } +.event-color-9 { background: hsl(270, 40%, 80%); } +.event-color-10 { background: hsl(300, 40%, 80%); } +.event-color-11 { background: hsl(330, 40%, 80%); } + /* Color tokens (dark) */ @media (prefers-color-scheme: dark) { :root { - --bg: radial-gradient(1200px 800px at 20% -10%, #1c2130 0%, #0c0f16 35%, #0a0b11 100%); --panel: #111318; --today: #f83; --ink: #ddd; - --ink-rgb: 221, 221, 221; + --inkstrong: #fff; --muted: #888; --weekend: #999; --firstday: #fff; @@ -56,15 +67,29 @@ .sep { background: hsl(18 70% 18%) } .oct { background: hsl(18 70% 26%) } .nov { background: hsl(18 70% 18%) } + + .event-color-0 { background: hsl(0, 40%, 50%); } + .event-color-1 { background: hsl(30, 40%, 50%); } + .event-color-2 { background: hsl(60, 40%, 50%); } + .event-color-3 { background: hsl(90, 40%, 50%); } + .event-color-4 { background: hsl(120, 40%, 50%); } + .event-color-5 { background: hsl(150, 40%, 50%); } + .event-color-6 { background: hsl(180, 40%, 50%); } + .event-color-7 { background: hsl(210, 40%, 50%); } + .event-color-8 { background: hsl(240, 40%, 50%); } + .event-color-9 { background: hsl(270, 40%, 50%); } + .event-color-10 { background: hsl(300, 40%, 50%); } + .event-color-11 { background: hsl(330, 40%, 50%); } + } /* Selection styles */ .weekend { color: var(--weekend) } -.firstday { color: var(--firstday); text-shadow: 0 0 .1em rgba(var(--ink-rgb), .5) } +.firstday { color: var(--firstday); text-shadow: 0 0 .1em; } .selected { background: var(--select); - border: 2px solid rgba(var(--ink-rgb), .3); + border: 2px solid var(--ink); box-shadow: inset 0 0 0 1px rgba(255,255,255,.3); } .selected .event { opacity: .7 } diff --git a/events.css b/events.css index 19cee94..992b3c6 100644 --- a/events.css +++ b/events.css @@ -4,9 +4,8 @@ padding: .1em .3em; margin: .1em 0; border-radius: .2em; - color: white; font-weight: 500; - white-space: nowrap; + white-space: normal; overflow: hidden; text-overflow: ellipsis; width: 100%; @@ -15,14 +14,13 @@ cursor: pointer; z-index: 5; } -.event:hover { opacity: .8 } /* Spanning events in the overlay (grid-positioned, not absolutely measured) */ .event-span { font-size: .75em; padding: 0 .5em; border-radius: .4em; - color: white; + color: var(--inkstrong); font-weight: 600; white-space: nowrap; overflow: hidden; diff --git a/layout.css b/layout.css index d3a1d01..4b2eeb0 100644 --- a/layout.css +++ b/layout.css @@ -51,13 +51,11 @@ header { .calendar-header, #calendar-header { display: grid; grid-template-columns: var(--label-w) repeat(7, var(--cell-w)) var(--overlay-w); - border-bottom: .1em solid var(--muted); + border-bottom: .2em solid var(--muted); align-items: last baseline; flex-shrink: 0; width: 100%; } -.calendar-header .dow-label { display:grid; place-items:center; height: var(--cell-h); color: var(--muted) } -.overlay-header-spacer { grid-column: -2 / -1 } /* Main container */ .calendar-container, #calendar-container { @@ -108,16 +106,18 @@ header { } /* Label cells */ -.dow-label, .week-label { +.year-label, .week-label { display: grid; place-items: center; width: 100%; - height: var(--cell-h); color: var(--muted); cursor: ns-resize; font-size: 1.2em; } +.week-label { + height: var(--cell-h); +} /* 7-day grid inside each week row */ .week-row > .days-grid { grid-column: 2 / span 7;