Some checks failed
CI / lint-and-test (push) Failing after 45s
- Added Node.js setup and webapp testing steps to the CI workflow for improved integration. - Updated HTML to link multiple CSS files for better modularity and organization of styles. - Removed deprecated `style.css` and introduced new CSS files for base styles, calendar, day detail, hints, markers, states, and duty list to enhance maintainability and readability. - Implemented new styles for improved presentation of duty information and user interactions. - Added unit tests for new API functions and contact link rendering to ensure functionality and reliability.
331 lines
6.4 KiB
CSS
331 lines
6.4 KiB
CSS
/* === Duty list & timeline */
|
|
.duty-list {
|
|
font-size: 0.9rem;
|
|
}
|
|
|
|
.duty-list h2 {
|
|
font-size: 0.85rem;
|
|
color: var(--muted);
|
|
margin: 0 0 8px 0;
|
|
}
|
|
|
|
.duty-list-day {
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.duty-list-day--today .duty-list-day-title {
|
|
color: var(--today);
|
|
font-weight: 700;
|
|
}
|
|
|
|
.duty-list-day--today .duty-list-day-title::before {
|
|
content: "";
|
|
display: inline-block;
|
|
width: 4px;
|
|
height: 1em;
|
|
background: var(--today);
|
|
border-radius: 2px;
|
|
margin-right: 8px;
|
|
vertical-align: middle;
|
|
}
|
|
|
|
/* Timeline: dates | track (line + dot) | cards */
|
|
.duty-list.duty-timeline {
|
|
position: relative;
|
|
}
|
|
|
|
.duty-list.duty-timeline::before {
|
|
content: "";
|
|
position: absolute;
|
|
left: calc(var(--timeline-date-width) + var(--timeline-track-width) / 2 - 1px);
|
|
top: 0;
|
|
bottom: 0;
|
|
width: 2px;
|
|
background: var(--muted);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.duty-timeline-day {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.duty-timeline-day--today {
|
|
scroll-margin-top: 200px;
|
|
}
|
|
|
|
.duty-timeline-row {
|
|
display: grid;
|
|
grid-template-columns: var(--timeline-date-width) var(--timeline-track-width) 1fr;
|
|
gap: 0 4px;
|
|
align-items: start;
|
|
margin-bottom: 8px;
|
|
min-height: 1px;
|
|
}
|
|
|
|
.duty-timeline-date {
|
|
position: relative;
|
|
font-size: 0.8rem;
|
|
color: var(--muted);
|
|
padding-top: 10px;
|
|
padding-bottom: 10px;
|
|
flex-shrink: 0;
|
|
overflow: visible;
|
|
}
|
|
|
|
.duty-timeline-date::before {
|
|
content: "";
|
|
position: absolute;
|
|
left: 0;
|
|
bottom: 4px;
|
|
width: calc(100% + var(--timeline-track-width) / 2);
|
|
height: 2px;
|
|
background: linear-gradient(
|
|
to right,
|
|
color-mix(in srgb, var(--muted) 40%, transparent) 0%,
|
|
color-mix(in srgb, var(--muted) 40%, transparent) 50%,
|
|
var(--muted) 70%,
|
|
var(--muted) 100%
|
|
);
|
|
}
|
|
|
|
.duty-timeline-date::after {
|
|
content: "";
|
|
position: absolute;
|
|
left: calc(100% + (var(--timeline-track-width) / 2) - 1px);
|
|
bottom: 2px;
|
|
width: 2px;
|
|
height: 6px;
|
|
background: var(--muted);
|
|
}
|
|
|
|
.duty-timeline-day--today .duty-timeline-date {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
padding-top: 4px;
|
|
color: var(--today);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.duty-timeline-day--today .duty-timeline-date::before,
|
|
.duty-timeline-day--today .duty-timeline-date::after {
|
|
display: none;
|
|
}
|
|
|
|
.duty-timeline-date-label,
|
|
.duty-timeline-date-day {
|
|
display: block;
|
|
line-height: 1.25;
|
|
}
|
|
|
|
.duty-timeline-date-day {
|
|
align-self: flex-start;
|
|
text-align: left;
|
|
padding-left: 0;
|
|
margin-left: 0;
|
|
}
|
|
|
|
.duty-timeline-date-dot {
|
|
display: block;
|
|
width: 100%;
|
|
height: 8px;
|
|
min-height: 8px;
|
|
position: relative;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.duty-timeline-date-dot::before {
|
|
content: "";
|
|
position: absolute;
|
|
left: 0;
|
|
top: 50%;
|
|
margin-top: -1px;
|
|
width: calc(100% + var(--timeline-track-width) / 2);
|
|
height: 1px;
|
|
background: color-mix(in srgb, var(--today) 45%, transparent);
|
|
}
|
|
|
|
.duty-timeline-date-dot::after {
|
|
content: "";
|
|
position: absolute;
|
|
left: calc(100% + (var(--timeline-track-width) / 2) - 1px);
|
|
top: 50%;
|
|
margin-top: -3px;
|
|
width: 2px;
|
|
height: 6px;
|
|
background: var(--today);
|
|
}
|
|
|
|
.duty-timeline-day--today .duty-timeline-date .duty-timeline-date-label {
|
|
color: var(--today);
|
|
}
|
|
|
|
.duty-timeline-day--today .duty-timeline-date .duty-timeline-date-day {
|
|
color: var(--muted);
|
|
font-weight: 400;
|
|
font-size: 0.75rem;
|
|
}
|
|
|
|
.duty-timeline-track {
|
|
min-width: 0;
|
|
}
|
|
|
|
.duty-timeline-card-wrap {
|
|
min-width: 0;
|
|
}
|
|
|
|
/* Flip-card: front = duty info + button, back = contacts */
|
|
.duty-flip-card {
|
|
perspective: 600px;
|
|
position: relative;
|
|
min-height: 0;
|
|
overflow: hidden;
|
|
border-radius: 8px;
|
|
background: transparent;
|
|
}
|
|
|
|
.duty-flip-inner {
|
|
transition: transform 0.4s;
|
|
transform-style: preserve-3d;
|
|
position: relative;
|
|
min-height: 0;
|
|
background: transparent;
|
|
}
|
|
|
|
.duty-flip-card[data-flipped="true"] .duty-flip-inner {
|
|
transform: rotateY(180deg);
|
|
}
|
|
|
|
.duty-flip-front {
|
|
position: relative;
|
|
backface-visibility: hidden;
|
|
-webkit-backface-visibility: hidden;
|
|
}
|
|
|
|
.duty-flip-back {
|
|
backface-visibility: hidden;
|
|
-webkit-backface-visibility: hidden;
|
|
position: absolute;
|
|
inset: 0;
|
|
transform: rotateY(180deg);
|
|
}
|
|
|
|
.duty-flip-btn {
|
|
position: absolute;
|
|
right: 8px;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
width: 36px;
|
|
height: 36px;
|
|
padding: 0;
|
|
border: none;
|
|
border-radius: 50%;
|
|
background: var(--surface);
|
|
color: var(--accent);
|
|
cursor: pointer;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
transition: background var(--transition-fast), color var(--transition-fast);
|
|
}
|
|
|
|
.duty-flip-btn:hover {
|
|
background: color-mix(in srgb, var(--accent) 20%, var(--surface));
|
|
}
|
|
|
|
.duty-flip-btn:focus {
|
|
outline: none;
|
|
}
|
|
|
|
.duty-flip-btn:focus-visible {
|
|
outline: 2px solid var(--accent);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
.duty-timeline-card.duty-item,
|
|
.duty-list .duty-item {
|
|
display: grid;
|
|
grid-template-columns: 1fr;
|
|
gap: 2px 0;
|
|
align-items: baseline;
|
|
padding: 8px 10px;
|
|
margin-bottom: 0;
|
|
border-radius: 8px;
|
|
background: var(--surface);
|
|
border-left: 3px solid var(--duty);
|
|
}
|
|
|
|
.duty-item--unavailable {
|
|
border-left-color: var(--unavailable);
|
|
}
|
|
|
|
.duty-item--vacation {
|
|
border-left-color: var(--vacation);
|
|
}
|
|
|
|
.duty-item .duty-item-type {
|
|
grid-column: 1;
|
|
grid-row: 1;
|
|
font-size: 0.75rem;
|
|
color: var(--muted);
|
|
}
|
|
|
|
.duty-item .name {
|
|
grid-column: 2;
|
|
grid-row: 1 / -1;
|
|
min-width: 0;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.duty-item .time {
|
|
grid-column: 1;
|
|
grid-row: 2;
|
|
align-self: start;
|
|
font-size: 0.8rem;
|
|
color: var(--muted);
|
|
}
|
|
|
|
.duty-timeline-card .duty-item-type { grid-column: 1; grid-row: 1; }
|
|
.duty-timeline-card .name { grid-column: 1; grid-row: 2; min-width: 0; }
|
|
.duty-timeline-card .time { grid-column: 1; grid-row: 3; }
|
|
|
|
/* Contact info: phone and Telegram username links in duty timeline cards */
|
|
.duty-contact-row {
|
|
grid-column: 1;
|
|
grid-row: 4;
|
|
font-size: 0.8rem;
|
|
color: var(--muted);
|
|
margin-top: 2px;
|
|
}
|
|
|
|
.duty-contact-link,
|
|
.duty-contact-phone,
|
|
.duty-contact-username {
|
|
color: var(--accent);
|
|
text-decoration: none;
|
|
}
|
|
|
|
.duty-contact-link:hover,
|
|
.duty-contact-phone:hover,
|
|
.duty-contact-username:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.duty-contact-link:focus,
|
|
.duty-contact-phone:focus,
|
|
.duty-contact-username:focus {
|
|
outline: none;
|
|
}
|
|
|
|
.duty-contact-link:focus-visible,
|
|
.duty-contact-phone:focus-visible,
|
|
.duty-contact-username:focus-visible {
|
|
outline: 2px solid var(--accent);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
.duty-item--current {
|
|
border-left-color: var(--today);
|
|
background: color-mix(in srgb, var(--today) 12%, var(--surface));
|
|
}
|