PlanTempusApp/PlanTempus.Application/wwwroot/css/employees.css
Janus C. H. Knudsen 120367acbb Enhances Services module with detail view and interactions
Adds comprehensive service detail view with multiple tabs and dynamic interactions
Implements client-side navigation between service list and detail views
Introduces mock service data catalog for flexible component rendering
Extends localization support for new service detail screens

Improves user experience by adding edit capabilities and smooth view transitions
2026-01-16 22:03:22 +01:00

1020 lines
22 KiB
CSS

/**
* Employees Styles - User & Role Management
*
* Employees-specific styling only.
* Reuses: swp-stat-card (stats.css), swp-stats-row (stats.css), swp-tab-bar (tabs.css),
* swp-btn, swp-status-badge, swp-icon-btn, swp-card, swp-section-label,
* swp-add-button, swp-tags-row, swp-tag, swp-status-indicator,
* swp-fact-boxes-inline, swp-fact-inline, swp-edit-section/row/label/value/select,
* swp-detail-grid, swp-back-link (components.css),
* swp-row-toggle (cash.css),
* swp-sticky-header, swp-header-content (page.css),
* swp-toggle-slider, swp-checkbox-list (controls.css)
*
* Creates: swp-employee-table, swp-employee-row, swp-user-info,
* swp-employee-avatar-large, swp-employee-detail-header, swp-employee-status,
* swp-salary-table, swp-document-list/item/info/name/meta/actions,
* swp-subsection/title, swp-simple-list/item/text
*/
/* ===========================================
USERS HEADER
=========================================== */
swp-users-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: var(--section-gap);
}
swp-users-count {
display: flex;
align-items: center;
gap: var(--spacing-4);
font-size: var(--font-size-sm);
color: var(--color-text-secondary);
strong {
color: var(--color-text);
font-weight: var(--font-weight-semibold);
}
}
swp-users-progress {
width: 120px;
height: 6px;
background: var(--color-border);
border-radius: var(--radius-sm);
overflow: hidden;
swp-users-progress-bar {
display: block;
height: 100%;
background: var(--color-teal);
border-radius: var(--radius-sm);
transition: width var(--transition-normal);
}
}
/* ===========================================
EMPLOYEE TABLE (uses swp-data-table + swp-card from components.css)
=========================================== */
swp-card.employees-list {
padding: 0;
overflow: hidden;
}
swp-card.employees-list swp-data-table {
grid-template-columns: minmax(220px, 1fr) 120px 140px 120px 40px;
}
swp-card.employees-list swp-data-table-header,
swp-card.employees-list swp-data-table-row {
padding: 0 var(--spacing-10);
}
swp-card.employees-list swp-data-table-header swp-data-table-cell {
padding-top: var(--spacing-5);
padding-bottom: var(--spacing-5);
}
swp-card.employees-list swp-data-table-row {
cursor: pointer;
}
swp-card.employees-list swp-data-table-cell {
padding: var(--spacing-5) 0;
&:last-child {
display: flex;
align-items: center;
justify-content: center;
}
}
/* ===========================================
USER INFO (Avatar + Details)
=========================================== */
swp-user-info {
display: flex;
align-items: center;
gap: var(--spacing-3);
}
swp-user-avatar {
width: 36px;
height: 36px;
border-radius: 50%;
background: var(--color-teal);
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: var(--font-size-xs);
font-weight: var(--font-weight-semibold);
flex-shrink: 0;
&.purple { background: var(--color-purple); }
&.blue { background: var(--color-blue); }
&.amber { background: var(--color-amber); }
}
swp-user-details {
min-width: 0;
}
swp-user-name {
display: block;
font-size: var(--font-size-base);
font-weight: var(--font-weight-medium);
color: var(--color-text);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
swp-user-email {
display: block;
font-size: var(--font-size-sm);
color: var(--color-text-secondary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* ===========================================
TABLE ACTIONS
=========================================== */
swp-table-actions {
display: flex;
align-items: center;
gap: var(--spacing-2);
justify-content: flex-end;
}
/* ===========================================
PERMISSIONS MATRIX
=========================================== */
swp-permissions-matrix {
display: block;
background: var(--color-surface);
border-radius: var(--radius-lg);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
overflow: hidden;
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: var(--spacing-5) var(--spacing-6);
text-align: center;
border-bottom: 1px solid var(--color-border);
font-size: var(--font-size-base);
&:first-child {
text-align: left;
font-weight: var(--font-weight-medium);
}
}
thead th {
background: var(--color-background-alt);
font-size: var(--font-size-xs);
font-weight: var(--font-weight-semibold);
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--color-text-secondary);
}
tbody tr:last-child td {
border-bottom: none;
}
.permission-name {
display: flex;
align-items: center;
gap: var(--spacing-3);
font-size: var(--font-size-base);
color: var(--color-text);
i {
font-size: 18px;
color: var(--color-text-secondary);
}
}
.check {
color: var(--color-teal);
font-size: 20px;
}
.no-access {
color: var(--color-border);
font-size: 16px;
}
}
/* ===========================================
EMPLOYEE DETAIL VIEW
=========================================== */
swp-employee-avatar-large {
width: 80px;
height: 80px;
border-radius: 50%;
background: var(--color-teal);
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: var(--font-size-2xl);
font-weight: var(--font-weight-semibold);
flex-shrink: 0;
&.purple { background: var(--color-purple); }
&.blue { background: var(--color-blue); }
&.amber { background: var(--color-amber); }
}
swp-employee-detail-header {
display: flex;
gap: var(--spacing-12);
}
swp-employee-info {
flex: 1;
display: flex;
flex-direction: column;
gap: var(--spacing-2);
min-width: 0;
}
swp-employee-name-row {
display: flex;
align-items: center;
gap: var(--spacing-8);
}
swp-employee-name {
font-size: var(--font-size-2xl);
font-weight: var(--font-weight-semibold);
color: var(--color-text);
}
/* ===========================================
EMPLOYEE STATUS (alias for swp-status-indicator)
=========================================== */
swp-employee-status {
display: inline-flex;
align-items: center;
gap: var(--spacing-2);
padding: var(--spacing-2) var(--spacing-4);
font-size: var(--font-size-sm);
font-weight: var(--font-weight-medium);
border-radius: var(--radius-md);
cursor: pointer;
transition: all var(--transition-fast);
margin-left: auto;
&[data-active="true"] {
background: var(--bg-green-strong);
color: var(--color-green);
border: 1px solid var(--bg-green-border);
}
&[data-active="false"] {
background: var(--bg-red-medium);
color: var(--color-red);
border: 1px solid var(--bg-red-border);
}
.icon {
font-size: var(--font-size-base);
}
}
/* ===========================================
VIEW CONTAINERS (Employee-specific)
=========================================== */
swp-employees-list-view,
swp-employee-detail-view {
transition: opacity 100ms ease;
}
swp-employees-list-view {
display: block;
}
swp-employee-detail-view {
display: none;
min-height: calc(100vh - 60px);
}
/* ===========================================
SCHEDULE GRID (Hours tab)
=========================================== */
swp-schedule-grid {
display: flex;
flex-direction: column;
}
swp-schedule-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: var(--spacing-4) 0;
border-bottom: 1px solid var(--color-border);
&:last-child {
border-bottom: none;
}
&.off {
color: var(--color-text-secondary);
swp-schedule-time {
color: var(--color-text-secondary);
}
}
swp-schedule-day {
font-size: var(--font-size-base);
font-weight: var(--font-weight-medium);
}
swp-schedule-time {
font-size: var(--font-size-base);
font-family: var(--font-mono);
color: var(--color-teal);
}
}
/* ===========================================
SERVICE LIST (Services tab)
=========================================== */
swp-service-list {
display: flex;
flex-direction: column;
}
swp-service-item {
display: grid;
grid-template-columns: 1fr auto auto;
gap: var(--spacing-6);
align-items: center;
padding: var(--spacing-4) 0;
border-bottom: 1px solid var(--color-border);
&:last-child {
border-bottom: none;
}
swp-service-name {
font-size: var(--font-size-base);
font-weight: var(--font-weight-medium);
}
swp-service-duration {
font-size: var(--font-size-sm);
color: var(--color-text-secondary);
}
swp-service-price {
font-size: var(--font-size-base);
font-family: var(--font-mono);
color: var(--color-teal);
font-weight: var(--font-weight-medium);
}
}
/* ===========================================
DOCUMENT LIST (HR tab)
=========================================== */
swp-document-list {
display: flex;
flex-direction: column;
gap: var(--spacing-2);
}
swp-document-item {
display: flex;
align-items: center;
gap: var(--spacing-3);
padding: 12px 16px;
background: var(--color-background-alt);
border-radius: var(--radius-md);
border: 1px solid var(--color-border);
i, swp-document-icon {
font-size: 20px;
color: var(--color-text-secondary);
flex-shrink: 0;
}
i.ph-file-pdf {
color: var(--color-red);
}
swp-document-info {
flex: 1;
min-width: 0;
swp-document-name {
display: block;
font-size: var(--font-size-base);
font-weight: var(--font-weight-medium);
color: var(--color-text);
}
swp-document-meta {
display: block;
font-size: var(--font-size-sm);
color: var(--color-text-secondary);
margin-top: 2px;
}
}
swp-document-actions {
display: flex;
align-items: center;
gap: var(--spacing-2);
flex-shrink: 0;
}
}
/* ===========================================
NOTES AREA
=========================================== */
swp-notes-area {
display: block;
min-height: 100px;
padding: var(--spacing-4);
background: var(--color-background-alt);
border-radius: var(--radius-sm);
font-size: var(--font-size-base);
color: var(--color-text-secondary);
line-height: 1.6;
&:focus {
outline: none;
color: var(--color-text);
}
}
/* ===========================================
SALARY TABLE (uses swp-data-table from components.css)
=========================================== */
swp-card.salary-history swp-data-table {
grid-template-columns: 1fr 120px 60px;
}
swp-card.salary-history swp-data-table-header {
background: transparent;
border-bottom: 1px solid var(--color-border);
}
swp-card.salary-history swp-data-table-row {
cursor: pointer;
&:hover swp-data-table-cell i {
color: var(--color-teal);
}
}
swp-card.salary-history swp-data-table-cell {
padding: var(--spacing-4) var(--spacing-2);
&:first-child {
padding-left: 0;
}
&:last-child {
padding-right: 0;
text-align: right;
}
i {
color: var(--color-text-muted);
font-size: 16px;
}
}
/* ===========================================
SUBSECTION TITLE
=========================================== */
swp-subsection {
display: block;
margin-bottom: var(--spacing-6);
&:last-of-type {
margin-bottom: 0;
}
swp-subsection-title {
display: block;
font-size: var(--font-size-sm);
font-weight: var(--font-weight-semibold);
color: var(--color-text-secondary);
margin-bottom: var(--spacing-3);
}
}
/* ===========================================
SIMPLE LIST
=========================================== */
swp-simple-list {
display: flex;
flex-direction: column;
gap: var(--spacing-2);
}
swp-simple-item {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--spacing-3);
padding: 12px 16px;
background: var(--color-background-alt);
border-radius: var(--radius-md);
border: 1px solid var(--color-border);
swp-simple-item-text {
flex: 1;
font-size: var(--font-size-base);
font-family: var(--font-mono);
color: var(--color-text);
}
}
/* ===========================================
FOCUS HIGHLIGHT (double-click to edit)
=========================================== */
@keyframes focus-blink {
0%, 100% { background: transparent; }
25%, 75% { background: var(--bg-teal-medium); }
}
swp-data-row.focus-highlight {
animation: focus-blink 1s ease-out;
& input {
outline: 2px solid var(--color-teal);
outline-offset: 2px;
}
}
/* ===========================================
STATS BOOKINGS TABLE
=========================================== */
.stats-bookings {
swp-data-table {
grid-template-columns: 90px 60px minmax(120px, 1fr) minmax(150px, 1fr) 80px 100px 100px;
}
swp-data-table-row swp-data-table-cell {
&:nth-child(1),
&:nth-child(2),
&:nth-child(5) {
font-family: var(--font-mono);
font-size: 12px;
color: var(--color-text-secondary);
}
&:nth-child(3) {
font-weight: var(--font-weight-medium);
}
&:nth-child(6) {
font-family: var(--font-mono);
font-size: 12px;
font-weight: var(--font-weight-semibold);
text-align: right;
}
}
swp-data-table-header swp-data-table-cell:nth-child(6) {
text-align: right;
}
}
/* ===========================================
SCHEDULE SCROLL CONTAINER
=========================================== */
swp-schedule-scroll {
display: block;
max-width: var(--page-max-width);
margin: 0 auto;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
cursor: grab;
}
swp-schedule-scroll.dragging {
cursor: grabbing;
user-select: none;
}
swp-schedule-scroll.dragging * {
pointer-events: none;
}
/* Når drawer er åben: page-container styles (padding animeres via JS) */
body.schedule-drawer-open swp-tab-content[data-tab="schedule"] swp-page-container {
max-width: none;
margin: 0;
}
/* ===========================================
WORK SCHEDULE TABLE
=========================================== */
swp-schedule-table {
display: grid;
grid-template-columns: 180px repeat(7, minmax(100px, 1fr));
min-width: max-content;
border-radius: var(--radius-md);
overflow: hidden;
border: 1px solid var(--color-border);
background: var(--color-surface);
}
swp-schedule-cell {
display: flex;
flex-direction: column;
justify-content: center;
padding: 12px 16px;
min-height: 60px;
background: var(--color-surface);
border-right: 1px solid var(--color-border);
border-bottom: 1px solid var(--color-border);
user-select: none;
}
/* Last column: no right border */
swp-schedule-cell:nth-child(8n) {
border-right: none;
}
/* Last row: no bottom border */
swp-schedule-cell:nth-last-child(-n+8) {
border-bottom: none;
}
swp-schedule-cell.header {
background: var(--color-background-alt);
font-weight: var(--font-weight-medium);
font-size: 13px;
color: var(--color-text-secondary);
min-height: 48px;
text-align: center;
align-items: center;
}
swp-schedule-cell.header.week-number {
font-size: 15px;
font-weight: var(--font-weight-semibold);
color: var(--color-text);
}
swp-schedule-cell.header.closed {
background: color-mix(in srgb, #f59e0b 10%, var(--color-background-alt));
border-top: 2px solid #f59e0b;
border-left: 2px solid #f59e0b;
border-right: 2px solid #f59e0b;
border-bottom: none;
swp-day-name {
color: #d97706;
}
}
swp-schedule-cell.employee {
align-items: flex-start;
gap: 2px;
}
swp-schedule-cell.day {
align-items: center;
text-align: center;
position: relative;
}
swp-schedule-cell.day.closed-day {
background: color-mix(in srgb, #f59e0b 6%, var(--color-surface));
border-left: 2px solid #f59e0b;
border-right: 2px solid #f59e0b;
swp-time-badge {
opacity: 0.5;
}
}
/* Last cell in closed column gets bottom border */
swp-schedule-cell.day.closed-day:nth-last-child(-n+8) {
border-bottom: 2px solid #f59e0b;
}
/* Schedule employee info */
swp-schedule-cell swp-employee-name {
font-size: var(--font-size-sm);
font-weight: var(--font-weight-medium);
color: var(--color-text);
}
swp-schedule-cell swp-employee-hours {
font-family: var(--font-mono);
font-size: 12px;
color: var(--color-text-muted);
}
/* Day header */
swp-day-name {
font-weight: var(--font-weight-medium);
color: var(--color-text);
}
swp-day-date {
font-size: 12px;
color: var(--color-text-muted);
font-weight: var(--font-weight-normal);
}
/* Time display variants */
swp-time-badge {
font-family: var(--font-mono);
font-size: 12px;
font-weight: 500;
padding: 4px 8px;
border-radius: 4px;
background: color-mix(in srgb, var(--color-teal) 10%, white);
color: var(--color-text);
white-space: nowrap;
min-width: 90px;
text-align: center;
display: inline-block;
}
swp-time-badge.off {
background: transparent;
color: var(--color-text-muted);
}
swp-time-badge.off.off-override {
background: color-mix(in srgb, #7c3aed 12%, white);
color: #6d28d9;
}
swp-time-badge.vacation {
background: color-mix(in srgb, #f59e0b 15%, white);
color: #b45309;
}
swp-time-badge.sick {
background: color-mix(in srgb, #ef4444 15%, white);
color: #dc2626;
}
/* Edit mode */
body.schedule-edit-mode swp-schedule-cell.day {
cursor: pointer;
}
body.schedule-edit-mode swp-schedule-cell.day:hover {
background: var(--color-background-alt);
}
body.schedule-edit-mode swp-schedule-cell.day.selected {
background: color-mix(in srgb, var(--color-teal) 12%, white);
border: 2px solid var(--color-teal);
margin: -1px;
padding: 11px 15px;
}
body.schedule-edit-mode swp-schedule-cell.header:not(.week-number) {
cursor: pointer;
}
body.schedule-edit-mode swp-schedule-cell.header:not(.week-number):hover {
background: var(--color-border);
}
/* Status options in drawer */
swp-status-options {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
swp-status-option {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 10px;
border: none;
border-radius: 4px;
cursor: pointer;
transition: all var(--transition-fast);
font-size: 13px;
font-weight: var(--font-weight-medium);
background: var(--color-background-alt);
color: var(--color-text-secondary);
&::before {
content: '';
width: 6px;
height: 6px;
border-radius: 50%;
flex-shrink: 0;
}
&[data-status="work"] {
--status-color: var(--color-teal);
}
&[data-status="off"] {
--status-color: #7c3aed;
}
&[data-status="vacation"] {
--status-color: #f59e0b;
}
&[data-status="sick"] {
--status-color: #e53935;
}
&::before {
background: var(--status-color);
}
&:hover {
background: var(--color-border);
}
&.selected {
background: color-mix(in srgb, var(--status-color) 15%, white);
color: var(--status-color);
}
}
/* Time range slider */
swp-time-range {
display: flex;
align-items: center;
gap: 12px;
}
swp-time-range-slider {
position: relative;
flex: 1;
height: 20px;
display: flex;
align-items: center;
}
swp-time-range-track {
position: absolute;
width: 100%;
height: 4px;
background: var(--color-border);
border-radius: 2px;
}
swp-time-range-fill {
position: absolute;
height: 4px;
background: var(--color-teal);
border-radius: 2px;
cursor: grab;
&:active {
cursor: grabbing;
}
}
swp-time-range-slider input[type="range"] {
position: absolute;
width: 100%;
height: 4px;
-webkit-appearance: none;
appearance: none;
background: transparent;
pointer-events: none;
margin: 0;
&::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 14px;
height: 14px;
background: var(--color-teal);
border: 2px solid white;
border-radius: 50%;
cursor: pointer;
pointer-events: auto;
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}
&::-moz-range-thumb {
width: 14px;
height: 14px;
background: var(--color-teal);
border: 2px solid white;
border-radius: 50%;
cursor: pointer;
pointer-events: auto;
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}
}
swp-time-range-label {
display: flex;
flex-direction: column;
align-items: center;
gap: 2px;
min-width: 100px;
text-align: center;
background: var(--color-background-alt);
padding: 6px 12px;
border-radius: 4px;
}
swp-time-range-times {
font-size: 13px;
font-family: var(--font-mono);
font-weight: var(--font-weight-medium);
color: var(--color-text);
white-space: nowrap;
}
swp-time-range-duration {
font-size: 11px;
font-family: var(--font-mono);
color: var(--color-text-secondary);
white-space: nowrap;
}
/* Schedule drawer employee display */
swp-employee-display {
display: flex;
align-items: center;
gap: 10px;
swp-employee-avatar {
width: 32px;
height: 32px;
border-radius: 50%;
background: linear-gradient(135deg, var(--color-teal) 0%, #00695c 100%);
color: white;
display: flex;
align-items: center;
justify-content: center;
font-weight: var(--font-weight-semibold);
font-size: 12px;
flex-shrink: 0;
}
&.empty swp-employee-avatar {
background: var(--color-border);
color: var(--color-text-muted);
}
&.multi swp-employee-avatar {
background: var(--color-text-muted);
}
}
/* ===========================================
RESPONSIVE
=========================================== */
@media (max-width: 1024px) {
swp-employee-table {
grid-template-columns: minmax(180px, 1fr) 100px 120px 100px 40px;
}
}
@media (max-width: 768px) {
swp-employee-table {
grid-template-columns: minmax(160px, 1fr) 90px 110px 90px 40px;
}
swp-employee-cell {
padding: var(--spacing-3) 0;
}
swp-employee-table-header,
swp-employee-row {
padding: 0 var(--spacing-4);
}
swp-users-header {
flex-direction: column;
align-items: flex-start;
gap: var(--spacing-4);
swp-btn {
width: 100%;
justify-content: center;
}
}
}