/** * calendar * * z-index: top is currently 10; overlapping events increment, assuming this won't be 10! */ /** * month view */ .calendar.month { @apply grid col-span-3 pb-6 2xl:pb-8 pt-2; /*grid-template-rows: 2rem 1fr; */ /* force month container to fit window */ grid-template-rows: 2rem calc(100% - 2rem); overflow-y: hidden; hgroup { @apply grid grid-cols-7 w-full gap-1; > span { @apply uppercase text-right pr-4 font-bold; } } ol { @apply grid grid-cols-7 w-full gap-1; contain: paint; grid-auto-rows: 1fr; /*max-height: var(--month-calendar-height); */ /* day element */ li { @apply bg-white relative px-1 pt-8 border-t-md border-gray-900 overflow-y-auto; transition: scale 150ms ease-in-out; /* day number */ &::before { @apply sticky top-0 -mt-8 -translate-y-8 right-0 w-auto h-8 z-1; @apply flex items-center justify-end pr-3 text-sm font-medium bg-inherit; content: attr(data-day-number); } &.day--outside { @apply bg-gray-50 text-gray-700; } &.day--today { @apply bg-cyan-100; } /* need to handle this for various 4, 5, and 7 day configs */ &:nth-child(-n+7) { /* first 7 items */ @apply border-t-2; } &:nth-last-child(-n+7) { /* last 7 items */ @apply border-b-md; } /*&:last-child { @apply rounded-br-lg; }*/ /* progressive "show more" button */ div.more-events { @apply absolute bottom-0 h-6 bg-inherit z-2 flex items-center; width: calc(100% - 0.5rem); } button.day-more { @apply text-xs px-1 h-4; } &[data-event-visible="0"] { .event:nth-child(n+1) { @apply hidden; } } &[data-event-visible="1"] { .event:nth-child(n+2) { @apply hidden; } } &[data-event-visible="2"] { .event:nth-child(n+3) { @apply hidden; } } &[data-event-visible="3"] { .event:nth-child(n+4) { @apply hidden; } } &[data-event-visible="4"] { .event:nth-child(n+5) { @apply hidden; } } &[data-event-visible="5"] { .event:nth-child(n+6) { @apply hidden; } } &[data-event-visible="6"] { .event:nth-child(n+7) { @apply hidden; } } &[data-event-visible="7"] { .event:nth-child(n+8) { @apply hidden; } } &[data-event-visible="8"] { .event:nth-child(n+9) { @apply hidden; } } &[data-event-visible="9"] { .event:nth-child(n+10) { @apply hidden; } } /* events */ .event { @apply flex items-center text-xs gap-1 px-1 py-px font-medium truncate rounded-sm bg-transparent; transition: background-color 125ms ease-in-out; animation: event-slide 350ms ease-in-out both; .indicator { --indicator-bg: var(--event-color); } .title { @apply grow truncate; } time { @apply text-2xs shrink-0 mt-px; } &:hover { background-color: color-mix(in srgb, var(--event-color) 25%, #fff 100%); } &.hidden { @apply hidden; } } /* expanded days with truncated events */ &.is-expanded { position: relative; height: min-content; padding-bottom: 1px; z-index: 3; border: 1.5px solid black; border-radius: 0.5rem; scale: 1.05; width: 120%; margin-left: -10%; margin-bottom: -100%; /* needed to break out of row in webkit */ div.more-events { @apply relative h-8; } .event { animation: none; } } } } } /** * time-based views */ .calendar.time { @apply grid; grid-template-columns: 6rem auto; grid-template-rows: 5rem auto 5rem; --row-height: 2.5rem; --now-row: 1; --now-col-start: 1; --now-col-end: 2; /* if we have an all day event, change the grid */ &.allday { grid-template-columns: 6rem auto; grid-template-rows: 5rem min-content auto 5rem; } /* top day bar */ hgroup { @apply bg-white col-span-2 border-b-2 border-primary pl-24 sticky z-11; @apply top-20; span.name { @apply font-semibold uppercase text-sm; } a.number { @apply flex items-center justify-center text-xl h-10 w-10 rounded-full bg-gray-100 font-semibold; aspect-ratio: 1 / 1; &:hover { @apply bg-gray-200; } } div.day-header { @apply relative flex flex-col gap-1 justify-end items-start pb-2 h-full; animation: header-slide 250ms ease-in; &:not(:last-of-type)::after { @apply block w-px bg-gray-200 absolute -right-2 top-20; content: ''; height: calc(100dvh - 16rem); } &.active { a.number { @apply bg-teal-500 text-white; &:hover { @apply bg-teal-600; } } } } } /* all day bar */ ol.day { @apply sticky top-40 grid col-span-2 bg-white border-b border-primary z-10 overflow-x-hidden; box-shadow: 0 0.25rem 0.5rem -0.25rem rgba(0,0,0,0.15); padding: 0.25rem 0 0.2rem 6rem; &::before { @apply absolute left-0 top-1.5 w-24 pr-4 text-right; @apply uppercase text-xs font-mono text-secondary font-medium; content: 'All day'; } li.event-wrapper { @apply flex relative overflow-x-hidden; grid-row-start: var(--event-row); grid-row-end: var(--event-end); grid-column-start: var(--event-col); grid-column-end: calc(var(--event-col) + 1); &.event-wrapper--overflow { @apply hidden; } a.event { @apply flex items-center text-xs gap-1 px-1 py-px mb-2px font-medium rounded-sm w-full; background-color: var(--event-bg); color: var(--event-fg); > span { @apply truncate; } &:hover { background-color: color-mix(in srgb, var(--event-bg) 100%, #000 10%); } } &.event-wrapper--more { label.event--more { @apply text-xs cursor-pointer rounded m-1 h-3.5 leading-none; @apply focus:outline-2 focus:outline-offset-2 focus:outline-cyan-600; input.more-checkbox { @apply hidden; } } } } &:has(input.more-checkbox:checked) { li.event-wrapper--overflow { @apply flex; } li.event-wrapper--more { @apply hidden; } } } /* time column */ ol.time { @apply grid z-0 pt-4; grid-template-rows: repeat(var(--grid-rows, 96), var(--row-height)); time { @apply relative flex items-center justify-end items-start pr-4; @apply text-xs text-secondary font-mono; &::after { @apply block absolute h-px bg-gray-200; width: calc(100cqw - 6rem); content: ''; top: 0.6rem; left: 6rem; } } } /* event positioning */ ol.events { @apply grid py-4; grid-template-rows: repeat(var(--grid-rows, 96), var(--row-height)); --event-col: 0; --event-row: 0; --event-end: 4; --event-bg: var(--color-gray-100); --event-fg: var(--color-primary); li.event { @apply flex rounded-md relative border border-white overflow-hidden; background-color: var(--event-bg); color: var(--event-fg); grid-row-start: var(--event-row); grid-row-end: var(--event-end); grid-column-start: var(--event-col); grid-column-end: calc(var(--event-col) + 1); width: calc(100% - var(--event-overlap-offset, 100%)); margin-left: var(--event-overlap-offset, 0%); z-index: var(--event-z, 1); top: 0.6rem; a.event { @apply flex flex-col grow px-3 py-2 gap-2px text-sm; > span { @apply font-semibold leading-none break-all; } > time { @apply text-2xs font-medium whitespace-nowrap; } } &:hover { /*animation: event-hover 125ms ease forwards;*/ transform: translateY(-2px); transition: transform 125ms ease-in; /*width: 100%;*/ /*z-index: 20; /* enough to make sure it's always on top of other events */ } } } /* bottom controls */ footer { @apply bg-white flex items-center justify-between col-span-2 border-t-md border-primary; @apply sticky bottom-0 pt-2 pb-6 z-10; a.timezone { @apply text-xs bg-gray-100 rounded px-2 py-1; } div.right { @apply flex items-center gap-4 justify-end; } } /* now indicator */ .now-indicator { @apply relative pointer-events-none z-10 border-t-3 border-red-600 opacity-90 -ml-2; grid-row: var(--now-row); grid-column: var(--now-col-start) / var(--now-col-end); width: calc(100% + 1rem); top: calc(0.6rem + (var(--row-height) * var(--now-offset, 0))); &::before { @apply block w-3 h-3 rounded-full bg-red-600 -translate-y-1/2 -mt-[1.5px]; content: ""; } } } /* step handling */ .calendar.time[data-density="30"] { /* half-hourly */ --row-height: 2rem; ol.time li:nth-child(2n) { visibility: hidden; /* preserves space + row alignment */ } } .calendar.time[data-density="60"] { /* hourly */ --row-height: 1.25rem; ol.time li:not(:nth-child(4n + 1)) { visibility: hidden; /* preserves space + row alignment */ } &.week { ol.events { a.event { @apply p-2; } li.event[data-span="1"] { a.event > span, a.event > time { @apply text-xs; } } li.event[data-span="1"], li.event[data-span="2"] { a.event { @apply flex-col gap-0 py-1; > span { @apply min-h-4 line-clamp-1; } } } } } } /** * day view */ .calendar.day { container: day / inline-size; hgroup { @apply flex items-start justify-start; } } /** * week view */ .calendar.week { container: week / inline-size; --days: 7; hgroup { @apply grid gap-x-2; grid-template-columns: repeat(var(--days), 1fr); } ol.day { @apply gap-x-2; grid-template-columns: repeat(var(--days), 1fr); } ol.events { @apply gap-x-2; grid-template-columns: repeat(var(--days), 1fr); --col: calc(100% / var(--days)); /* draw a 1px line at the start of each column repeat + highlight weekends */ /* need to factor in weekends on/off */ background-image: linear-gradient( to right, var(--color-gray-10) var(--col), transparent var(--col), transparent calc((var(--col) * 6) + 5px), var(--color-gray-10) calc((var(--col) * 6) + 5px) ); background-position: 0; background-size: 100%; background-repeat: no-repeat; } &[data-weekstart="1"] { ol.events { background-image: linear-gradient( to right, transparent, transparent calc((var(--col) * 5) + 5px), var(--color-gray-10) calc((var(--col) * 5) + 5px) ); } } } /** * four-day view */ .calendar.four { container: four / inline-size; --days: 4; hgroup { @apply grid gap-x-2; grid-template-columns: repeat(var(--days), 1fr); } ol.day { @apply gap-x-2; grid-template-columns: repeat(var(--days), 1fr); } ol.events { @apply gap-x-2; grid-template-columns: repeat(var(--days), 1fr); --col: calc(100% / var(--days)); background-image: repeating-linear-gradient( to right, transparent, transparent var(--col), var(--color-gray-200) var(--col), var(--color-gray-200) calc(var(--col) + 1px) ); background-position: 0; background-size: 100%; background-repeat: no-repeat; } } /** * calendar list in the left bar */ #calendar-toggles { @apply pb-6; summary { @apply flex items-center gap-1 justify-start; span { @apply capitalize; } a { @apply hidden -mt-2px; } &:hover { a { @apply flex; } } } li.calendar-toggle { @apply relative; /* hide the edit link by default */ .edit-link { @apply hidden absolute pl-4 right-1 top-1/2 -translate-y-1/2 underline text-sm; background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 33%); } /* show menu on hover */ &:hover { .edit-link { @apply block; } } /* limit calendar titles to 1 line */ .checkbox-label span { @apply line-clamp-1; } } } /** * media queries */ @media (width >= theme(--breakpoint-2xl)) /* 96rem */ { .calendar.time { hgroup { @apply top-22; } ol.day { @apply top-42; } } } @media (height <= 50rem) { .calendar.time { grid-template-rows: 4rem auto 5rem; &.allday { grid-template-rows: 4rem min-content auto 5rem; } ol.day { @apply top-38; } hgroup { div.day-header { @apply flex-row items-center justify-start gap-2; .name { order: 2; } &:not(:last-of-type)::after { @apply top-16; } } } } } /** * animations */ @keyframes event-slide { from { opacity: 0; transform: translateX(-1rem); } to { opacity: 1; transform: translateX(0); } } @keyframes event-hover { from { transform: translateY(0); z-index: 1; } to { transform: translateY(-2px); z-index: 10; } } @keyframes header-slide { from { opacity: 0; transform: translateX(-0.25rem); } to { opacity: 1; transform: translateX(0); } }