/* V2 Base - Shared variables */ :root { /* Grid measurements */ --hour-height: 64px; --time-axis-width: 60px; --grid-columns: 7; --day-column-min-width: 200px; --day-start-hour: 6; --day-end-hour: 18; --header-height: 70px; /* Colors - UI */ --color-border: #e0e0e0; --color-surface: #fff; --color-background: #f5f5f5; --color-background-hover: #f0f0f0; --color-background-alt: #fafafa; --color-text: #333333; --color-text-secondary: #666; --color-primary: #1976d2; --color-team-bg: #e3f2fd; --color-team-text: #1565c0; /* Colors - Grid */ --color-hour-line: rgba(0, 0, 0, 0.2); --color-grid-line-light: rgba(0, 0, 0, 0.05); --color-unavailable: rgba(0, 0, 0, 0.02); /* Named color palette for events (fra V1) */ --b-color-red: #e53935; --b-color-pink: #d81b60; --b-color-magenta: #c200c2; --b-color-purple: #8e24aa; --b-color-violet: #5e35b1; --b-color-deep-purple: #4527a0; --b-color-indigo: #3949ab; --b-color-blue: #1e88e5; --b-color-light-blue: #03a9f4; --b-color-cyan: #3bc9db; --b-color-teal: #00897b; --b-color-green: #43a047; --b-color-light-green: #8bc34a; --b-color-lime: #c0ca33; --b-color-yellow: #fdd835; --b-color-amber: #ffb300; --b-color-orange: #fb8c00; --b-color-deep-orange: #f4511e; /* Base mix for color-mix() function */ --b-mix: #fff; /* Shadows */ --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1); --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1); /* Transitions */ --transition-fast: 150ms ease; } * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: var(--color-background); } /* V2 Layout - Calendar structure, grid, navigation */ .calendar-wrapper { height: 100vh; display: flex; flex-direction: column; } swp-calendar { display: grid; grid-template-rows: auto 1fr; height: 100%; background: var(--color-surface); } /* Nav */ swp-calendar-nav { display: flex; gap: 12px; padding: 8px 16px; border-bottom: 1px solid var(--color-border); align-items: center; font-size: 13px; } /* View switcher - small chips */ swp-view-switcher { display: flex; gap: 4px; background: var(--color-background-alt); padding: 3px; border-radius: 6px; } .view-chip { padding: 4px 10px; border: none; border-radius: 4px; cursor: pointer; background: transparent; color: var(--color-text-secondary); font-size: 12px; font-weight: 500; transition: all 0.15s ease; &:hover { background: var(--color-surface); color: var(--color-text); } &.active { background: var(--color-surface); color: var(--color-text); box-shadow: 0 1px 2px rgba(0,0,0,0.1); } } /* Workweek dropdown */ .workweek-dropdown { padding: 4px 8px; border: 1px solid var(--color-border); border-radius: 4px; background: var(--color-surface); font-size: 12px; cursor: pointer; &:hover { border-color: var(--color-text-secondary); } &:focus { outline: 2px solid var(--color-primary); outline-offset: 1px; } } /* Resource selector (picker view) */ swp-resource-selector { &.hidden { display: none; } fieldset { border: 1px solid var(--color-border); border-radius: 6px; padding: 6px 12px; margin: 0; } legend { font-size: 11px; font-weight: 500; color: var(--color-text-secondary); padding: 0 6px; } .resource-checkboxes { display: flex; flex-wrap: wrap; gap: 4px 16px; } label { display: flex; align-items: center; gap: 4px; font-size: 12px; cursor: pointer; white-space: nowrap; &:hover { color: var(--color-primary); } } input[type="checkbox"] { width: 14px; height: 14px; cursor: pointer; } } /* Navigation group */ swp-nav-group { display: flex; gap: 2px; } swp-nav-button { padding: 6px 12px; border: 1px solid var(--color-border); border-radius: 4px; cursor: pointer; background: var(--color-surface); font-size: 12px; &:hover { background: var(--color-background-hover); } &.btn-small { padding: 4px 8px; font-size: 11px; } } swp-week-info { margin-left: auto; text-align: right; swp-week-number { font-weight: 600; font-size: 12px; display: block; } swp-date-range { font-size: 11px; color: var(--color-text-secondary); } } /* Container */ swp-calendar-container { display: grid; grid-template-columns: var(--time-axis-width) 1fr; grid-template-rows: auto 1fr; overflow: hidden; height: 100%; } /* Time axis */ swp-time-axis { grid-column: 1; grid-row: 1 / 3; display: grid; grid-template-rows: auto 1fr; border-right: 1px solid var(--color-border); background: var(--color-surface); overflow: hidden; user-select: none; } swp-header-spacer { border-bottom: 1px solid var(--color-border); background: var(--color-surface); z-index: 1; } swp-header-drawer { display: grid; grid-template-columns: subgrid; grid-column: 1 / -1; grid-row: 2; overflow: hidden; background: var(--color-background-alt); border-bottom: 1px solid var(--color-border); } swp-time-axis-content { display: flex; flex-direction: column; position: relative; } swp-hour-marker { height: var(--hour-height); padding: 4px 8px; font-size: 11px; color: var(--color-text-secondary); text-align: right; position: relative; &::after { content: ''; position: absolute; top: -1px; right: 0; width: 5px; height: 1px; background: var(--color-hour-line); } &:first-child::after { display: none; } } /* Grid container */ swp-grid-container { grid-column: 2; grid-row: 1 / 3; display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: subgrid; overflow: hidden; } /* Viewport/Track for slide animation */ swp-header-viewport { display: grid; grid-template-columns: repeat(var(--grid-columns), minmax(var(--day-column-min-width), 1fr)); grid-template-rows: auto auto; min-width: calc(var(--grid-columns) * var(--day-column-min-width)); overflow-y: scroll; overflow-x: hidden; &::-webkit-scrollbar { background: transparent; } &::-webkit-scrollbar-thumb { background: transparent; } } swp-content-viewport { overflow: hidden; min-height: 0; width: 100%; } swp-header-track { display: grid; grid-template-columns: subgrid; grid-column: 1 / -1; grid-row: 1; } swp-content-track { display: flex; height: 100%; > swp-scrollable-content { flex: 0 0 100%; height: 100%; } } /* Header */ swp-calendar-header { display: grid; grid-template-columns: subgrid; grid-column: 1 / -1; grid-auto-rows: auto; background: var(--color-surface); &[data-levels="date"] > swp-day-header { grid-row: 1; } &[data-levels="resource date"] { > swp-resource-header { grid-row: 1; } > swp-day-header { grid-row: 2; } } &[data-levels="team resource date"] { > swp-team-header { grid-row: 1; } > swp-resource-header { grid-row: 2; } > swp-day-header { grid-row: 3; } } &[data-levels="department resource date"] { > swp-department-header { grid-row: 1; } > swp-resource-header { grid-row: 2; } > swp-day-header { grid-row: 3; } } } swp-day-header, swp-resource-header, swp-team-header, swp-department-header { padding: 8px; text-align: center; border-right: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border); user-select: none; } swp-team-header { background: var(--color-team-bg); color: var(--color-team-text); font-weight: 500; grid-column: span var(--team-cols, 1); } swp-department-header { background: var(--color-team-bg); color: var(--color-team-text); font-weight: 500; grid-column: span var(--department-cols, 1); } swp-resource-header { background: var(--color-background-alt); font-size: 13px; } swp-day-header { swp-day-name { display: block; font-size: 11px; color: var(--color-text-secondary); text-transform: uppercase; } swp-day-date { display: block; font-size: 24px; font-weight: 300; } &[data-hidden="true"] { display: none; } } /* Scrollable content */ swp-scrollable-content { display: block; overflow: auto; } swp-time-grid { display: block; position: relative; min-height: calc((var(--day-end-hour) - var(--day-start-hour)) * var(--hour-height)); min-width: calc(var(--grid-columns) * var(--day-column-min-width)); /* Timelinjer */ &::after { content: ''; position: absolute; inset: 0; z-index: 2; background-image: repeating-linear-gradient( to bottom, transparent, transparent calc(var(--hour-height) - 1px), var(--color-hour-line) calc(var(--hour-height) - 1px), var(--color-hour-line) var(--hour-height) ); pointer-events: none; } } /* Kvarterlinjer - 3 linjer per time (15, 30, 45 min) */ swp-grid-lines { display: block; position: absolute; inset: 0; z-index: 1; background-image: repeating-linear-gradient( to bottom, transparent 0, transparent calc(var(--hour-height) / 4 - 1px), var(--color-grid-line-light) calc(var(--hour-height) / 4 - 1px), var(--color-grid-line-light) calc(var(--hour-height) / 4), transparent calc(var(--hour-height) / 4), transparent calc(var(--hour-height) / 2 - 1px), var(--color-grid-line-light) calc(var(--hour-height) / 2 - 1px), var(--color-grid-line-light) calc(var(--hour-height) / 2), transparent calc(var(--hour-height) / 2), transparent calc(var(--hour-height) * 3 / 4 - 1px), var(--color-grid-line-light) calc(var(--hour-height) * 3 / 4 - 1px), var(--color-grid-line-light) calc(var(--hour-height) * 3 / 4), transparent calc(var(--hour-height) * 3 / 4), transparent var(--hour-height) ); } swp-day-columns { position: absolute; inset: 0; display: grid; grid-template-columns: repeat(var(--grid-columns), minmax(var(--day-column-min-width), 1fr)); min-width: calc(var(--grid-columns) * var(--day-column-min-width)); } swp-day-column { position: relative; border-right: 1px solid var(--color-border); } swp-events-layer { position: absolute; inset: 0; z-index: 10; } /* Unavailable time zones (outside working hours) */ swp-unavailable-layer { position: absolute; inset: 0; z-index: 5; pointer-events: none; } swp-unavailable-zone { position: absolute; left: 0; right: 0; background: var(--color-unavailable, rgba(0, 0, 0, 0.05)); pointer-events: none; } /* V2 Events - Event styling (from V1 calendar-events-css.css) */ /* Event base styles */ swp-day-columns swp-event { --b-text: var(--color-text); position: absolute; border-radius: 3px; overflow: hidden; cursor: pointer; transition: background-color 200ms ease, box-shadow 150ms ease, transform 150ms ease; z-index: 10; left: 2px; right: 2px; font-size: 12px; padding: 4px 6px; user-select: none; /* Color system using color-mix() */ background-color: color-mix(in srgb, var(--b-primary) 10%, var(--b-mix)); color: var(--b-text); border-left: 4px solid var(--b-primary); /* Enable container queries for responsive layout */ container-type: size; container-name: event; /* CSS Grid layout for time, title, and description */ display: grid; grid-template-columns: auto 1fr; grid-template-rows: auto 1fr; gap: 2px 4px; align-items: start; /* Dragging state */ &.dragging { position: absolute; z-index: 999999; left: 2px; right: 2px; width: auto; cursor: grabbing; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); } /* Ghost clone (stays in original position during drag) */ &.drag-ghost { opacity: 0.3; pointer-events: none; } /* Hover state */ &:hover { background-color: color-mix(in srgb, var(--b-primary) 15%, var(--b-mix)); } } swp-day-columns swp-event:hover { z-index: 20; } /* Resize handle - actual draggable element */ swp-resize-handle { position: absolute; bottom: 0; left: 0; right: 0; height: 15px; cursor: ns-resize; z-index: 25; display: flex; align-items: center; justify-content: center; opacity: 0; transition: opacity 150ms ease; } /* Show handle on hover */ swp-day-columns swp-event:hover swp-resize-handle { opacity: 1; } /* Handle visual indicator (grip lines) */ swp-resize-handle::before { content: ''; width: 30px; height: 4px; background: rgba(255, 255, 255, 0.9); border-radius: 2px; box-shadow: 0 -2px 0 rgba(255, 255, 255, 0.9), 0 2px 0 rgba(255, 255, 255, 0.9), 0 0 4px rgba(0, 0, 0, 0.2); } /* Global resizing state */ .swp--resizing { user-select: none !important; cursor: ns-resize !important; } .swp--resizing * { cursor: ns-resize !important; } swp-day-columns swp-event-time { grid-column: 1; grid-row: 1; font-size: 0.875rem; font-weight: 500; white-space: nowrap; } swp-day-columns swp-event-title { grid-column: 2; grid-row: 1; font-size: 0.875rem; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } swp-day-columns swp-event-description { grid-column: 1 / -1; grid-row: 2; display: block; font-size: 0.875rem; opacity: 0.8; line-height: 1.3; overflow: hidden; word-wrap: break-word; /* Ensure description fills available height for gradient effect */ min-height: 100%; align-self: stretch; /* Fade-out effect for long descriptions */ -webkit-mask-image: linear-gradient(to bottom, black 70%, transparent 100%); mask-image: linear-gradient(to bottom, black 70%, transparent 100%); } /* Container queries for height-based layout */ /* Hide description when event is too short (< 30px) */ @container event (height < 30px) { swp-day-columns swp-event-description { display: none; } } /* Full description for tall events (>= 100px) */ @container event (height >= 100px) { swp-day-columns swp-event-description { max-height: none; } } /* Multi-day events */ swp-multi-day-event { position: relative; height: 28px; margin: 2px 4px; padding: 0 8px; border-radius: 4px; display: flex; align-items: center; font-size: 0.875rem; font-weight: 500; cursor: pointer; transition: all var(--transition-fast); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; user-select: none; /* Color system using color-mix() */ --b-text: var(--color-text); background-color: color-mix(in srgb, var(--b-primary) 10%, var(--b-mix)); color: var(--b-text); border-left: 4px solid var(--b-primary); &:hover { background-color: color-mix(in srgb, var(--b-primary) 15%, var(--b-mix)); } /* Continuation indicators */ &[data-continues-before="true"] { border-top-left-radius: 0; border-bottom-left-radius: 0; margin-left: 0; padding-left: 20px; &::before { content: '\25C0'; position: absolute; left: 4px; opacity: 0.6; font-size: 0.75rem; } } &[data-continues-after="true"] { border-top-right-radius: 0; border-bottom-right-radius: 0; margin-right: 0; padding-right: 20px; &::after { content: '\25B6'; position: absolute; right: 4px; opacity: 0.6; font-size: 0.75rem; } } &:hover { transform: translateY(-1px); box-shadow: var(--shadow-sm); } } /* All-day events */ swp-allday-event { --b-text: var(--color-text); background-color: color-mix(in srgb, var(--b-primary) 10%, var(--b-mix)); color: var(--b-text); border-left: 4px solid var(--b-primary); cursor: pointer; transition: background-color 200ms ease; user-select: none; &:hover { background-color: color-mix(in srgb, var(--b-primary) 15%, var(--b-mix)); } } /* Event creation preview */ swp-event-preview { position: absolute; left: 8px; right: 8px; background: rgba(33, 150, 243, 0.1); border: 2px dashed var(--color-primary); border-radius: 4px; /* Position via CSS variables */ top: calc(var(--preview-start) * var(--minute-height)); height: calc(var(--preview-duration) * var(--minute-height)); } /* Event filtering styles */ /* When filter is active, all events are dimmed by default */ swp-events-layer[data-filter-active="true"] swp-event { opacity: 0.2; transition: opacity 200ms ease; } /* Events that match the filter stay normal */ swp-events-layer[data-filter-active="true"] swp-event[data-matches="true"] { opacity: 1; } /* Event overlap styling */ /* Event group container for column sharing */ swp-event-group { position: absolute; display: grid; gap: 2px; left: 2px; right: 2px; z-index: 10; } /* Grid column configurations */ swp-event-group.cols-2 { grid-template-columns: 1fr 1fr; } swp-event-group.cols-3 { grid-template-columns: 1fr 1fr 1fr; } swp-event-group.cols-4 { grid-template-columns: 1fr 1fr 1fr 1fr; } /* Stack levels using margin-left */ swp-event-group.stack-level-0 { margin-left: 0px; } swp-event-group.stack-level-1 { margin-left: 15px; } swp-event-group.stack-level-2 { margin-left: 30px; } swp-event-group.stack-level-3 { margin-left: 45px; } swp-event-group.stack-level-4 { margin-left: 60px; } /* Shadow for stacked events (level 1+) */ swp-event[data-stack-link]:not([data-stack-link*='"stackLevel":0']), swp-event-group[data-stack-link]:not([data-stack-link*='"stackLevel":0']) swp-event { box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.1); } /* Child events within grid */ swp-event-group swp-event { position: relative; left: 0; right: 0; } /* All-day event transition for smooth repositioning */ swp-allday-container swp-event.transitioning { transition: grid-area 200ms ease-out, grid-row 200ms ease-out, grid-column 200ms ease-out; } /* Color utility classes */ .is-red { --b-primary: var(--b-color-red); } .is-pink { --b-primary: var(--b-color-pink); } .is-magenta { --b-primary: var(--b-color-magenta); } .is-purple { --b-primary: var(--b-color-purple); } .is-violet { --b-primary: var(--b-color-violet); } .is-deep-purple { --b-primary: var(--b-color-deep-purple); } .is-indigo { --b-primary: var(--b-color-indigo); } .is-blue { --b-primary: var(--b-color-blue); } .is-light-blue { --b-primary: var(--b-color-light-blue); } .is-cyan { --b-primary: var(--b-color-cyan); } .is-teal { --b-primary: var(--b-color-teal); } .is-green { --b-primary: var(--b-color-green); } .is-light-green { --b-primary: var(--b-color-light-green); } .is-lime { --b-primary: var(--b-color-lime); } .is-yellow { --b-primary: var(--b-color-yellow); } .is-amber { --b-primary: var(--b-color-amber); } .is-orange { --b-primary: var(--b-color-orange); } .is-deep-orange { --b-primary: var(--b-color-deep-orange); } /* Header drawer items */ swp-header-item { --b-text: var(--color-text); /* Positioneres via style.gridArea */ height: 22px; margin: 1px 4px; padding: 2px 8px; border-radius: 3px; font-size: 0.75rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: flex; align-items: center; cursor: pointer; user-select: none; transition: background-color 200ms ease; /* Color system - inverted from swp-event */ background-color: color-mix(in srgb, var(--b-primary) 15%, var(--b-mix)); color: var(--b-text); &:hover { background-color: color-mix(in srgb, var(--b-primary) 10%, var(--b-mix)); } /* Dragging state */ &.dragging { opacity: 0.7; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); } }