feat: v4.0 - multi-day horizontal canvas, duration input, overnight blocks, PDF horizontal layout
Some checks failed
Build & Push Docker / build (push) Has been cancelled

This commit is contained in:
2026-02-20 17:31:41 +01:00
parent e3a5330cc2
commit 47add509ca
11 changed files with 1188 additions and 773 deletions

View File

@@ -709,3 +709,169 @@ body {
background: var(--border);
color: var(--text);
}
/* ============================================================
v4 — Horizontal Canvas (X=time, Y=days)
============================================================ */
.canvas-wrapper {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
background: var(--bg);
}
.canvas-scroll-area {
flex: 1;
overflow: auto;
padding: 12px 16px;
}
/* Time axis row */
.time-axis-row {
display: flex;
align-items: flex-end;
margin-bottom: 2px;
}
.time-corner {
background: transparent;
flex-shrink: 0;
}
.time-tick {
position: absolute;
top: 4px;
font-size: 10px;
color: var(--text-light);
transform: translateX(-50%);
font-variant-numeric: tabular-nums;
pointer-events: none;
white-space: nowrap;
}
/* Day rows */
.day-rows {
display: flex;
flex-direction: column;
gap: 4px;
}
.day-row {
display: flex;
align-items: stretch;
background: var(--white);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
overflow: hidden;
}
.day-label {
display: flex;
align-items: center;
justify-content: flex-end;
padding: 0 10px 0 6px;
font-size: 11px;
font-weight: 600;
color: var(--text-light);
background: #f8fafc;
border-right: 1px solid var(--border);
flex-shrink: 0;
white-space: nowrap;
}
.day-timeline {
flex: 1;
position: relative;
background: var(--white);
cursor: crosshair;
overflow: hidden;
}
/* Hour grid lines in timeline */
.grid-line {
position: absolute;
top: 0;
bottom: 0;
width: 1px;
background: var(--border);
pointer-events: none;
z-index: 1;
}
/* Block element (horizontal) */
.block-el {
position: absolute;
border-radius: 4px;
overflow: hidden;
cursor: grab;
z-index: 10;
box-shadow: 0 1px 3px rgba(0,0,0,0.18);
transition: box-shadow 0.12s;
user-select: none;
touch-action: none;
display: flex;
align-items: center;
}
.block-el:hover {
box-shadow: 0 3px 8px rgba(0,0,0,0.25);
z-index: 20;
}
.block-el:active {
cursor: grabbing;
}
.block-el.overnight {
opacity: 0.85;
border-right: 3px dashed rgba(255,255,255,0.5);
}
.block-inner {
padding: 2px 6px;
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: center;
min-width: 0;
width: 100%;
}
.block-title {
font-size: 11px;
font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
line-height: 1.3;
}
.block-time {
font-size: 9px;
opacity: 0.8;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
line-height: 1.2;
}
/* Resize handle on right edge */
.block-el::after {
content: '';
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 6px;
cursor: ew-resize;
background: rgba(255,255,255,0.2);
border-radius: 0 4px 4px 0;
opacity: 0;
transition: opacity 0.12s;
}
.block-el:hover::after {
opacity: 1;
}