/** * Modul: Kalender (Calendar) * Zweck: Styles für Monats-/Wochen-/Tages-/Agenda-Ansicht, Termin-Karten, Modal * Abhängigkeiten: tokens.css, layout.css */ /* -------------------------------------------------------- * Modul-Akzent * -------------------------------------------------------- */ .calendar-page { --module-accent: var(--module-calendar); } /* -------------------------------------------------------- * Seiten-Layout * -------------------------------------------------------- */ .calendar-page { display: flex; flex-direction: column; height: calc(100dvh - var(--safe-area-inset-top) - var(--nav-bottom-height) - var(--safe-area-inset-bottom)); max-width: var(--content-max-width); margin: 0 auto; overflow: clip; } @media (min-width: 1024px) { .calendar-page { height: 100dvh; } } /* -------------------------------------------------------- * Kalender-Toolbar (Navigation + Ansichts-Umschalter) * -------------------------------------------------------- */ .cal-toolbar { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--color-border); background-color: color-mix(in srgb, var(--color-bg) 90%, transparent); backdrop-filter: var(--blur-sm); -webkit-backdrop-filter: var(--blur-sm); position: sticky; top: 0; z-index: var(--z-sticky); flex-shrink: 0; border-top: 3px solid var(--module-accent); } .cal-toolbar__nav { display: flex; align-items: center; gap: var(--space-1); } .cal-toolbar__nav .btn { color: var(--color-text-secondary); } .cal-toolbar__label { font-size: var(--text-base); font-weight: var(--font-weight-semibold); flex: 1; text-align: center; white-space: nowrap; } .cal-toolbar__today { font-size: var(--text-sm); color: var(--color-accent); font-weight: var(--font-weight-medium); padding: var(--space-1) var(--space-2); border-radius: var(--radius-sm); background: var(--color-accent-light); cursor: pointer; border: none; white-space: nowrap; } .cal-toolbar__views { display: flex; gap: var(--space-0h); background-color: var(--color-surface-2); border-radius: var(--radius-sm); padding: var(--space-0h); } .cal-toolbar__view-btn { font-size: var(--text-xs); font-weight: var(--font-weight-medium); padding: var(--space-1) var(--space-2); border-radius: var(--radius-xs); border: none; background: none; color: var(--color-text-secondary); cursor: pointer; transition: all var(--transition-fast); min-height: var(--target-lg); white-space: nowrap; } .cal-toolbar__view-btn:hover:not(.cal-toolbar__view-btn--active) { color: var(--color-text-primary); } .cal-toolbar__view-btn--active { background-color: var(--color-surface); color: var(--color-text-primary); box-shadow: var(--shadow-sm); } /* ── Schmale Viewports (< 580px): Views in zweite Zeile ── */ @media (max-width: 579px) { .cal-toolbar { flex-wrap: wrap; row-gap: var(--space-2); padding-bottom: var(--space-2); } /* Nächste-Nav ans Ende der ersten Zeile bringen */ .cal-toolbar > .cal-toolbar__nav:last-child { order: 4; } /* Views in volle zweite Zeile */ .cal-toolbar__views { order: 10; flex-basis: 100%; justify-content: center; } .cal-toolbar__view-btn { flex: 1; } } /* -------------------------------------------------------- * Monatsansicht * -------------------------------------------------------- */ .month-view { flex: 1; display: flex; flex-direction: column; overflow: hidden; } .month-weekdays { display: grid; grid-template-columns: repeat(7, 1fr); border-bottom: 1px solid var(--color-border); flex-shrink: 0; } .month-weekday { padding: var(--space-2) 0; text-align: center; font-size: var(--text-xs); font-weight: var(--font-weight-semibold); color: var(--color-text-secondary); text-transform: uppercase; letter-spacing: 0.05em; } .month-grid { flex: 1; display: grid; grid-template-columns: repeat(7, 1fr); grid-auto-rows: 1fr; overflow-y: auto; } .month-day { border-right: 1px solid var(--color-border-subtle); border-bottom: 1px solid var(--color-border-subtle); padding: var(--space-1); min-height: 80px; cursor: pointer; transition: background-color var(--transition-fast); overflow: hidden; } .month-day:nth-child(7n) { border-right: none; } .month-day:hover { background-color: var(--color-surface-2); } .month-day--outside { background-color: var(--color-bg); opacity: 0.5; } .month-day__number { font-size: var(--text-sm); font-weight: var(--font-weight-medium); color: var(--color-text-secondary); width: var(--space-6); height: var(--space-6); display: flex; align-items: center; justify-content: center; border-radius: var(--radius-full); margin-bottom: var(--space-1); } .month-day--today .month-day__number { background-color: var(--color-accent); color: var(--color-text-on-accent); font-weight: var(--font-weight-bold); } .month-day--today { background-color: var(--color-accent-light); } .month-day__event { display: flex; align-items: center; gap: 4px; font-size: var(--text-xs); font-weight: var(--font-weight-medium); padding: var(--space-px) var(--space-1); border-radius: var(--radius-xs); margin-bottom: var(--space-0h); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; color: var(--color-text-on-accent); line-height: 1.6; filter: saturate(0.4); } .month-day__event span, .allday-event span, .week-event__title span, .agenda-event__title span, .event-popup__title span { min-width: 0; overflow: hidden; text-overflow: ellipsis; } .event-icon { width: 16px; height: 16px; flex: 0 0 auto; opacity: 0.9; } .event-icon--compact { width: 12px; height: 12px; } .month-day__more { font-size: var(--text-xs); color: var(--color-text-secondary); padding: var(--space-px) var(--space-1); cursor: pointer; } /* -------------------------------------------------------- * Wochenansicht * -------------------------------------------------------- */ .week-view { flex: 1; display: flex; flex-direction: column; overflow: hidden; } .week-view__header { display: grid; flex-shrink: 0; border-bottom: 1px solid var(--color-border); } .week-view__time-gutter { width: 48px; flex-shrink: 0; } .week-view__day-header { padding: var(--space-2) var(--space-1); text-align: center; border-left: 1px solid var(--color-border-subtle); } .week-view__day-name { font-size: var(--text-xs); font-weight: var(--font-weight-semibold); color: var(--color-text-secondary); text-transform: uppercase; letter-spacing: 0.05em; } .week-view__day-num { font-size: var(--text-xl); font-weight: var(--font-weight-bold); color: var(--color-text-primary); width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; border-radius: var(--radius-full); margin: 0 auto; } .week-view__day-num--today { background-color: var(--color-accent); color: var(--color-text-on-accent); } .week-view__scroll { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; position: relative; } .week-view__body { display: flex; min-height: calc(24 * var(--cal-hour-height)); /* 24h × 56px pro Stunde */ position: relative; } .week-view__times { width: 48px; flex-shrink: 0; position: relative; } .week-view__time-slot { height: var(--cal-hour-height); padding-right: var(--space-2); display: flex; align-items: flex-start; justify-content: flex-end; padding-top: var(--space-1); } .week-view__time-label { font-size: var(--text-xs); color: var(--color-text-disabled); white-space: nowrap; } .week-view__columns { flex: 1; display: grid; position: relative; } .week-view__col { border-left: 1px solid var(--color-border-subtle); position: relative; } .week-view__hour-line { position: absolute; left: 0; right: 0; height: 1px; background-color: var(--color-border-subtle); pointer-events: none; } .week-view__now-line { position: absolute; left: 0; right: 0; height: 2px; background-color: var(--color-danger); z-index: 2; pointer-events: none; } .week-view__now-line::before { content: ''; position: absolute; left: -4px; top: -4px; width: 10px; height: 10px; border-radius: var(--radius-full); background-color: var(--color-danger); } .week-event { position: absolute; border-radius: var(--radius-xs); padding: var(--space-0h) var(--space-1); font-size: var(--text-xs); font-weight: var(--font-weight-medium); color: var(--color-text-on-accent); overflow: hidden; cursor: pointer; z-index: 1; line-height: 1.4; filter: saturate(0.4); transition: filter var(--transition-fast); } .week-event:hover { filter: saturate(0.4) brightness(0.9); } .week-event__title { display: flex; align-items: center; gap: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .week-event__time { font-size: var(--text-xs); opacity: 0.85; } .event-attachment-preview { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-2); } .event-attachment-preview img { width: 100%; max-height: 180px; object-fit: cover; border-radius: var(--radius-md); border: 1px solid var(--color-border-subtle); } .event-attachment-preview a { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--color-accent); word-break: break-word; } .document-dropzone { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-2); min-height: 148px; padding: var(--space-5); border: 1.5px dashed color-mix(in srgb, var(--module-calendar) 48%, var(--color-border)); border-radius: var(--radius-md); background: color-mix(in srgb, var(--module-calendar) 7%, var(--color-surface)); color: var(--color-text-secondary); text-align: center; cursor: pointer; transition: border-color var(--transition-fast), background-color var(--transition-fast), transform var(--transition-fast); } .document-dropzone:hover, .document-dropzone--active { border-color: var(--module-calendar); background: color-mix(in srgb, var(--module-calendar) 12%, var(--color-surface)); } .document-dropzone--active { transform: translateY(-1px); } .document-dropzone__icon { width: 42px; height: 42px; display: inline-flex; align-items: center; justify-content: center; border-radius: var(--radius-md); color: var(--module-calendar); background: color-mix(in srgb, var(--module-calendar) 15%, transparent); } .document-dropzone__icon svg { width: 22px; height: 22px; } .document-dropzone__title { color: var(--color-text-primary); font-weight: var(--font-weight-semibold); } .document-dropzone__hint, .document-dropzone__file { max-width: 100%; color: var(--color-text-tertiary); font-size: var(--text-xs); overflow-wrap: anywhere; } .document-dropzone__file { color: var(--module-calendar); font-weight: var(--font-weight-medium); } /* -------------------------------------------------------- * Tagesansicht * -------------------------------------------------------- */ .day-view { flex: 1; display: flex; flex-direction: column; overflow: hidden; } .day-view__header { padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--color-border); text-align: center; flex-shrink: 0; } .day-view__date-label { font-size: var(--text-lg); font-weight: var(--font-weight-bold); } .day-view__scroll { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; } .day-view__body { display: flex; min-height: calc(24 * var(--cal-hour-height)); position: relative; } .day-view__times { width: 48px; flex-shrink: 0; } .day-view__col { flex: 1; border-left: 1px solid var(--color-border-subtle); position: relative; } /* -------------------------------------------------------- * Agenda-Ansicht * -------------------------------------------------------- */ .agenda-view { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: var(--space-2) var(--space-4) var(--space-6); } .agenda-day { margin-bottom: var(--space-4); } .agenda-day__header { display: flex; align-items: baseline; gap: var(--space-3); padding: var(--space-2) 0 var(--space-1); border-bottom: 2px solid var(--color-border); margin-bottom: var(--space-2); position: sticky; top: 0; background-color: var(--color-bg); z-index: var(--z-base); } .agenda-day__date { font-size: var(--text-sm); font-weight: var(--font-weight-bold); color: var(--color-text-primary); } .agenda-day__weekday { font-size: var(--text-sm); color: var(--color-text-secondary); } .agenda-day__header--today .agenda-day__date { color: var(--color-accent); } .agenda-event { display: flex; align-items: stretch; gap: var(--space-3); padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm); margin-bottom: var(--space-1); cursor: pointer; transition: background-color var(--transition-fast); } .agenda-event:hover { background-color: var(--color-surface-2); } .agenda-event__color { width: 3px; border-radius: var(--radius-full); flex-shrink: 0; filter: saturate(0.4); } .agenda-event__body { flex: 1; min-width: 0; } .agenda-event__title { display: flex; align-items: center; gap: var(--space-1); font-size: var(--text-base); font-weight: var(--font-weight-medium); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .event-title-picker { display: grid; grid-template-columns: 72px minmax(0, 1fr); gap: var(--space-3); align-items: end; } .event-icon-picker { position: relative; } .event-title-picker__title { min-width: 0; } .event-icon-picker__trigger { width: 52px; height: 44px; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--color-border); border-radius: var(--radius-sm); background: var(--color-surface); color: var(--color-text-primary); cursor: pointer; transition: border-color var(--transition-fast), background-color var(--transition-fast), transform var(--transition-fast); } .event-icon-picker__trigger:hover, .event-icon-picker__trigger:focus-visible { border-color: var(--color-accent); background: var(--color-accent-light); } .event-icon-picker__trigger:active { transform: scale(0.98); } .event-icon-picker__trigger i, .event-icon-picker__trigger svg { width: 22px; height: 22px; } .event-icon-picker__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(44px, 1fr)); gap: var(--space-2); margin: calc(var(--space-2) * -1) 0 var(--space-4) 0; padding: var(--space-3); border: 1px solid var(--color-border); border-radius: var(--radius-md); background: var(--color-surface-2); } .event-icon-picker__grid[hidden] { display: none !important; } .event-icon-picker__option { height: 42px; display: inline-flex; align-items: center; justify-content: center; border: 1px solid transparent; border-radius: var(--radius-sm); background: var(--color-surface); color: var(--color-text-secondary); cursor: pointer; transition: border-color var(--transition-fast), color var(--transition-fast), background-color var(--transition-fast), transform var(--transition-fast); } .event-icon-picker__option:hover, .event-icon-picker__option:focus-visible { color: var(--color-text-primary); border-color: var(--color-border); transform: translateY(-1px); } .event-icon-picker__option--active { color: var(--color-accent); border-color: var(--color-accent); background: var(--color-accent-light); } .event-icon-picker__option i, .event-icon-picker__option svg { width: 20px; height: 20px; } .reminder-custom { margin-top: var(--space-3); } .reminder-custom[hidden] { display: none !important; } .agenda-event__meta { font-size: var(--text-sm); color: var(--color-text-secondary); display: flex; align-items: center; gap: var(--space-2); margin-top: 2px; } .agenda-event__assigned { display: inline-flex; align-items: center; gap: var(--space-1); } .agenda-event__avatar { width: 16px; height: 16px; border-radius: var(--radius-full); display: inline-flex; align-items: center; justify-content: center; font-size: var(--text-xs); font-weight: var(--font-weight-bold); color: var(--color-text-on-accent); flex-shrink: 0; } .agenda-empty { text-align: center; padding: var(--space-8); color: var(--color-text-secondary); font-size: var(--text-sm); } /* -------------------------------------------------------- * Calendar-Modal Content-Styles (Overlay/Panel via shared modal.js) * -------------------------------------------------------- */ /* Farbauswahl */ .color-picker { display: flex; flex-wrap: wrap; gap: var(--space-2); } .color-swatch { width: 28px; height: 28px; border-radius: var(--radius-full); border: 2px solid transparent; cursor: pointer; transition: transform var(--transition-fast), border-color var(--transition-fast); position: relative; } .color-swatch::before { content: ''; position: absolute; inset: -10px; border-radius: var(--radius-full); } .color-swatch:hover { transform: scale(1.15); } .color-swatch--active { border-color: var(--color-text-primary); transform: scale(1.1); } /* -------------------------------------------------------- * Termin-Detailansicht (Popup beim Klick) * -------------------------------------------------------- */ .event-popup { position: fixed; z-index: calc(var(--z-modal) - 1); background-color: var(--color-surface); border-radius: var(--radius-md); box-shadow: var(--shadow-lg); padding: var(--space-4); min-width: 240px; max-width: 320px; animation: fadeIn var(--transition-fast) ease; } .event-popup__color-bar { height: 4px; border-radius: var(--radius-full); margin-bottom: var(--space-3); filter: saturate(0.4); } .event-popup__title { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-base); font-weight: var(--font-weight-semibold); margin-bottom: var(--space-2); } .event-popup__meta { font-size: var(--text-sm); color: var(--color-text-secondary); display: flex; flex-direction: column; gap: var(--space-1); } .event-popup__actions { display: flex; gap: var(--space-2); margin-top: var(--space-3); padding-top: var(--space-3); border-top: 1px solid var(--color-border); } .event-popup__attachment { margin-top: var(--space-2); } .event-popup__attachment--image img { width: 100%; max-height: 220px; object-fit: cover; border-radius: var(--radius-md); border: 1px solid var(--color-border-subtle); } .event-popup__attachment--file { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--color-accent); } /* -------------------------------------------------------- * Ganztägige Ereignisse (oben in Wochen-/Tagesansicht) * -------------------------------------------------------- */ .allday-row { display: grid; border-bottom: 1px solid var(--color-border); min-height: 28px; flex-shrink: 0; } .allday-cell { border-left: 1px solid var(--color-border-subtle); padding: 2px; min-width: 0; overflow: hidden; } .allday-event { display: flex; align-items: center; gap: 4px; font-size: var(--text-xs); font-weight: var(--font-weight-medium); padding: var(--space-px) var(--space-1); border-radius: var(--radius-xs); color: var(--color-text-on-accent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-bottom: var(--space-0h); cursor: pointer; filter: saturate(0.4); } @media (max-width: 640px) { .event-title-picker { grid-template-columns: 1fr; } } /* -------------------------------------------------------- * Kalender-Name-Label (Agenda, Popup) * -------------------------------------------------------- */ .event-cal-label { display: inline-flex; align-items: center; gap: 4px; font-size: var(--text-xs); color: var(--color-text-disabled); } .event-cal-label::before { content: ''; display: inline-block; width: 7px; height: 7px; border-radius: var(--radius-full); background: var(--cal-color, currentColor); flex-shrink: 0; filter: saturate(0.4); }