calendar/src/components/CalendarDay.vue
2025-08-23 18:09:58 -06:00

134 lines
2.8 KiB
Vue

<script setup>
const props = defineProps({
day: Object,
})
</script>
<template>
<div
class="cell"
:class="[
props.day.monthClass,
{
today: props.day.isToday,
weekend: props.day.isWeekend,
firstday: props.day.isFirstDay,
selected: props.day.isSelected,
holiday: props.day.isHoliday,
},
]"
:data-date="props.day.date"
>
<h1>{{ props.day.displayText }}</h1>
<span v-if="props.day.lunarPhase" class="lunar-phase">{{ props.day.lunarPhase }}</span>
<!-- Holiday indicator -->
<div v-if="props.day.holiday" class="holiday-info">
<span class="holiday-name" :title="props.day.holiday.name">
{{ props.day.holiday.name }}
</span>
</div>
</div>
</template>
<style scoped>
.cell {
position: relative;
border-right: 1px solid var(--border-color);
border-bottom: 1px solid var(--border-color);
user-select: none;
touch-action: none;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: flex-start;
padding: 0.25em;
overflow: hidden;
width: 100%;
height: var(--cell-h);
font-weight: 700;
transition: background-color 0.15s ease;
}
.cell h1 {
margin: 0;
padding: 0;
min-width: 1.5em;
font-size: 1em;
font-weight: 700;
color: var(--ink);
transition: background-color 0.15s ease;
}
.cell.weekend h1 {
color: var(--weekend);
}
.cell.firstday h1 {
color: var(--firstday);
text-shadow: 0 0 0.1em var(--strong);
}
.cell.today h1 {
border-radius: 2em;
background: var(--today);
border: 0.2em solid var(--today);
margin: -0.2em;
color: var(--strong);
font-weight: bold;
}
.cell.selected {
filter: hue-rotate(180deg);
}
.cell.selected h1 {
color: var(--strong);
}
.lunar-phase {
position: absolute;
top: 0.1em;
right: 0.1em;
font-size: 0.8em;
opacity: 0.7;
}
.cell.holiday {
/* Remove solid background & border color overrides; use gradient overlay instead */
position: relative;
}
.cell.holiday::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(
135deg,
var(--holiday-grad-start, rgba(255, 255, 255, 0.1)) 0%,
var(--holiday-grad-end, rgba(255, 255, 255, 0)) 70%
);
pointer-events: none;
mix-blend-mode: normal; /* can switch to 'overlay' or 'screen' if thematic */
}
.cell.holiday h1 {
/* Slight emphasis without forcing a specific hue */
color: var(--holiday);
text-shadow: 0 0 0.3em rgba(255, 255, 255, 0.4);
}
.holiday-info {
position: absolute;
bottom: 0.1em;
left: 0.1em;
right: 0.1em;
line-height: 1;
max-height: 2.4em;
overflow: hidden;
font-size: 0.8em;
}
.holiday-name {
display: block;
color: var(--holiday-label);
padding: 0.15em 0.35em 0.15em 0.25em;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
</style>