591 lines
15 KiB
CSS
591 lines
15 KiB
CSS
/**
|
|
* 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-10;
|
|
@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-42 grid col-span-2 bg-white py-2 border-b border-primary col-span-2 pl-24 z-2 overflow-x-hidden;
|
|
box-shadow: 0 0.25rem 0.5rem -0.25rem var(--color-gray-200);
|
|
|
|
&::before {
|
|
@apply absolute left-0 top-1/2 -translate-y-1/2 w-24 pr-4 text-right;
|
|
@apply uppercase text-xs font-mono text-secondary font-medium;
|
|
content: 'All day';
|
|
}
|
|
|
|
li.events {
|
|
@apply flex flex-col gap-1 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);
|
|
|
|
a.event {
|
|
@apply flex items-center text-xs gap-1 px-1 py-px 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%);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 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;
|
|
}
|
|
}
|
|
}
|
|
@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);
|
|
}
|
|
}
|