/** * UI Components - Shared reusable components * * This file contains all shared UI components used across the application. * Feature files should NOT define these components - only use them. * * Components: * - swp-btn (buttons) * - swp-status-badge (status/role badges) * - swp-plan-card (subscription plan cards) * - swp-avatar (user avatars with size variants) * - swp-icon-btn (icon-only buttons) * - swp-card (content cards with section-label/footer) * - swp-section-label (card section headers) * - swp-section-header (section header with action link) * - swp-section-action (action link in section header) * - swp-add-button (dashed border add button) * - BASE PATTERNS: table, list-item, icon-container (Grid+Subgrid reusable patterns) */ /* =========================================== BASE PATTERNS - Grid + Subgrid Tables =========================================== */ swp-table-header-base { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; background: var(--color-background-alt); border-bottom: 1px solid var(--color-border); swp-table-cell-base { font-size: var(--font-size-xs); font-weight: var(--font-weight-semibold); text-transform: uppercase; letter-spacing: 0.5px; color: var(--color-text-secondary); } } swp-table-body-base { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; } swp-table-row-base { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; align-items: center; border-bottom: 1px solid var(--color-border); transition: background var(--transition-fast); &:last-child { border-bottom: none; } &:hover { background: var(--color-background-hover); } } /* =========================================== BASE PATTERNS - List Items (Grid+Subgrid) =========================================== */ swp-list-base { display: contents; } swp-list-item-base { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; align-items: center; padding: var(--card-padding); background: var(--color-background-alt); border-radius: var(--radius-lg); cursor: pointer; transition: background var(--transition-fast); &:hover { background: var(--color-background-hover); } } /* =========================================== BASE PATTERNS - Icon Container =========================================== */ swp-icon-container { display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; background: var(--color-background-hover); border-radius: var(--radius-xl); color: var(--color-text-secondary); font-size: var(--font-size-xl); flex-shrink: 0; } /* =========================================== DATA TABLE (Generic Grid + Subgrid) grid-template-columns defineres i feature CSS =========================================== */ swp-data-table { display: grid; swp-data-table-header { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; background: var(--color-background-alt); swp-data-table-cell { font-size: var(--font-size-xs); font-weight: var(--font-weight-semibold); text-transform: uppercase; letter-spacing: 0.5px; color: var(--color-text-secondary); padding: var(--spacing-4); } } swp-data-table-row { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; align-items: center; border-bottom: 1px solid var(--color-border); transition: background var(--transition-fast); &:last-child { border-bottom: none; } &:hover { background: var(--color-background-hover); } } swp-data-table-cell { padding: var(--spacing-4); font-size: var(--font-size-base); color: var(--color-text); &.mono { font-family: var(--font-mono); } &.muted { color: var(--color-text-muted); } &.right { text-align: right; } } } /* =========================================== BUTTONS (swp-btn) =========================================== */ swp-btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--spacing-2); padding: var(--spacing-3) var(--spacing-6); font-size: var(--font-size-base); font-weight: var(--font-weight-medium); font-family: var(--font-family); border-radius: var(--radius-md); border: 1px solid transparent; cursor: pointer; transition: all var(--transition-fast); text-decoration: none; & i { font-size: 18px; } /* Primary button */ &.primary { background: var(--color-teal); color: white; border-color: var(--color-teal); &:hover { background: #00796b; border-color: #00796b; } &:active { transform: translateY(1px); } &:disabled { background: var(--color-border); border-color: var(--color-border); cursor: not-allowed; } } /* Secondary button */ &.secondary { background: var(--color-surface); border: 1px solid var(--color-border); color: var(--color-text); &:hover { background: var(--color-background-hover); } } /* Ghost button */ &.ghost { background: transparent; color: var(--color-text-secondary); &:hover { color: var(--color-text); } } /* Outline button */ &.outline { background: transparent; border: 1px solid var(--color-teal); color: var(--color-teal); &:hover { background: var(--bg-teal-medium); } &.purple { border-color: var(--color-purple); color: var(--color-purple); &:hover { background: var(--bg-purple-medium); } } } /* Social button */ &.social { background: var(--color-background); color: var(--color-text); border-color: var(--color-border); &:hover { background: var(--color-background-hover); border-color: var(--color-text-muted); } & img { width: 20px; height: 20px; } } /* Size variants */ &.sm { padding: var(--spacing-2) var(--spacing-3); font-size: var(--font-size-xs); & i { font-size: 14px; } } &.lg { padding: var(--spacing-4) var(--spacing-8); font-size: var(--font-size-lg); } /* Full width */ &.full-width { width: 100%; } } /* =========================================== STATUS BADGES (swp-status-badge) =========================================== */ swp-status-badge { display: inline-flex; align-items: center; gap: var(--spacing-3); padding: var(--spacing-2) var(--spacing-5); font-size: var(--font-size-xs); font-weight: var(--font-weight-medium); border-radius: var(--radius-pill); &::before { content: ''; width: 6px; height: 6px; border-radius: var(--radius-full); background: currentColor; } /* Status variants - green */ &.approved, &.active, &.valid, &.confirmed { background: var(--bg-green-strong); color: var(--color-green); } /* Status variants - amber */ &.draft, &.invited, &.expiring, &.warning, &.pending { background: var(--bg-amber-strong); color: #b45309; } /* Use color-amber for pending specifically */ &.pending { color: var(--color-amber); } /* Role variants */ &.owner, &.enrolled, &.ferie { background: var(--bg-teal-strong); color: var(--color-teal); } &.admin { background: var(--bg-purple-strong); color: var(--color-purple); } &.leader, &.fri, &.info, &.inprogress, &.in-progress { background: var(--bg-blue-strong); color: var(--color-blue); } &.employee { background: var(--color-background-alt); color: var(--color-text-secondary); } /* Danger/red variants */ &.sygdom, &.danger { background: var(--bg-red-strong); color: var(--color-red); } /* Completed - muted */ &.completed { background: var(--color-background-hover); color: var(--color-text-secondary); } } /* =========================================== PLAN CARDS (swp-plan-card) =========================================== */ swp-plan-card { display: flex; flex-direction: column; background: var(--color-surface); border: 2px solid var(--color-border); border-radius: var(--radius-xl); padding: var(--spacing-10); transition: all var(--transition-normal); &.selected, &.current { border-color: var(--color-teal); box-shadow: 0 0 0 3px var(--bg-teal-strong); swp-btn.secondary { background: var(--color-background-alt); color: var(--color-text-secondary); cursor: default; pointer-events: none; } } &.popular { border-color: var(--color-amber); } &.enterprise { background: var(--gradient-enterprise); border-color: var(--color-purple); } } /* Plan badge */ swp-plan-badge { display: inline-flex; align-items: center; gap: var(--spacing-2); padding: var(--spacing-2) var(--spacing-3); font-size: var(--font-size-xs); font-weight: var(--font-weight-semibold); text-transform: uppercase; letter-spacing: 0.5px; border-radius: var(--radius-pill); width: fit-content; & i { font-size: 14px; } &.current, &.selected { background: var(--bg-teal-strong); color: var(--color-teal); } &.popular { background: var(--bg-amber-strong); color: var(--color-amber); } &.enterprise { background: var(--bg-purple-strong); color: var(--color-purple); } &.free { background: var(--bg-green-strong); color: var(--color-green); } } /* Plan action */ swp-plan-action { margin-top: auto; padding-top: var(--card-padding); swp-btn { width: 100%; } } /* =========================================== AVATARS (swp-avatar) =========================================== */ swp-avatar { border-radius: 50%; background: var(--color-teal); color: white; display: flex; align-items: center; justify-content: center; font-weight: var(--font-weight-semibold); flex-shrink: 0; /* Default size (md = 40px) */ width: 40px; height: 40px; font-size: var(--font-size-sm); /* Size variants */ &.size-xs { width: 24px; height: 24px; font-size: 10px; } &.size-sm { width: 36px; height: 36px; font-size: var(--font-size-xs); } &.size-lg { width: 80px; height: 80px; font-size: var(--font-size-2xl); } /* Color variants */ &.purple { background: var(--color-purple); } &.blue { background: var(--color-blue); } &.amber { background: var(--color-amber); } &.teal { background: var(--color-teal); } } /* =========================================== ICON BUTTONS (swp-icon-btn) =========================================== */ swp-icon-btn { width: 32px; height: 32px; display: flex; align-items: center; justify-content: center; border-radius: var(--radius-md); background: transparent; border: none; color: var(--color-text-secondary); cursor: pointer; transition: all var(--transition-fast); & i { font-size: 18px; } &:hover { background: var(--color-background-alt); color: var(--color-text); } &.danger:hover { background: var(--bg-red-medium); color: var(--color-red); } } /* =========================================== CARDS (swp-card) =========================================== */ swp-card { display: block; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--border-radius-lg); padding: var(--card-padding); } /* Section label - simple card header */ swp-section-label { display: block; font-size: var(--font-size-xs); font-weight: var(--font-weight-semibold); color: var(--color-text); text-transform: uppercase; letter-spacing: 0.5px; padding-bottom: var(--spacing-4); border-bottom: 1px solid var(--color-border); margin-bottom: var(--spacing-6); &.spaced { margin-top: var(--spacing-6); } } /* Section header - wrapper when action link is needed */ swp-section-header { display: flex; justify-content: space-between; align-items: center; padding-bottom: var(--spacing-4); border-bottom: 1px solid var(--color-border); margin-bottom: var(--spacing-6); swp-section-label { padding-bottom: 0; border-bottom: none; margin-bottom: 0; } } swp-section-action { font-size: var(--font-size-sm); color: var(--color-teal); cursor: pointer; transition: opacity var(--transition-fast); &:hover { opacity: 0.8; } } swp-card-content { display: block; } swp-card-footer { display: flex; justify-content: space-between; align-items: center; padding: var(--spacing-6) var(--card-padding); background: var(--color-background-alt); border-top: 1px solid var(--color-border); margin: var(--spacing-6) calc(-1 * var(--card-padding)) calc(-1 * var(--card-padding)); border-radius: 0 0 var(--border-radius-lg) var(--border-radius-lg); } /* =========================================== ADD BUTTON (dashed border style) =========================================== */ swp-add-button { display: flex; align-items: center; justify-content: center; gap: var(--spacing-2); padding: var(--spacing-5); margin-top: var(--spacing-5); border: 2px dashed var(--color-border); border-radius: var(--radius-md); color: var(--color-text-secondary); font-size: var(--font-size-md); cursor: pointer; transition: all var(--transition-fast); &:hover { border-color: var(--color-teal); color: var(--color-teal); background: var(--bg-teal-subtle); } } /* =========================================== USER INFO PATTERN (shared across auth, waitlist, employees, drawers) =========================================== */ swp-user-info { display: flex; align-items: center; gap: var(--spacing-4); } swp-user-info-card { display: flex; align-items: center; gap: var(--spacing-4); padding: var(--spacing-4); background: var(--color-background); border: 1px solid var(--color-border); border-radius: var(--radius-lg); } swp-user-details { display: flex; flex-direction: column; gap: var(--spacing-1); flex: 1; 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; } /* =========================================== FORM INPUTS (shared base styling) =========================================== */ /* Global textarea styling */ textarea { width: 100%; padding: var(--spacing-3) var(--spacing-4); font-size: var(--font-size-base); font-family: var(--font-family); color: var(--color-text); background: var(--color-background-alt); border: 1px solid var(--color-border); border-radius: var(--radius-sm); resize: vertical; &::placeholder { color: var(--color-text-muted); } &:hover { background: var(--color-background); } &:focus { outline: none; background: var(--color-surface); border-color: var(--color-teal); } } swp-form-group { display: flex; flex-direction: column; gap: var(--spacing-2); } swp-form-label { display: block; font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); color: var(--color-text); } swp-form-input { position: relative; input, select, textarea { width: 100%; padding: var(--spacing-3) var(--spacing-4); font-size: var(--font-size-base); font-family: var(--font-family); color: var(--color-text); background: var(--color-background); border: 1px solid var(--color-border); border-radius: var(--border-radius); transition: border-color var(--transition-fast), box-shadow var(--transition-fast); &::placeholder { color: var(--color-text-muted); } &:focus { outline: none; border-color: var(--color-teal); box-shadow: var(--shadow-focus-ring); } } select { cursor: pointer; appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 12px center; padding-right: 40px; } textarea { resize: vertical; min-height: 80px; } &.date-range { display: flex; align-items: center; gap: var(--spacing-3); input { flex: 1; } span { color: var(--color-text-secondary); } } } /* =========================================== DRAWER FORM PATTERNS Scoped styles for forms inside drawers =========================================== */ [data-drawer] { /* Form row - vertical layout */ swp-form-row { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; &.spaced { margin-top: 24px; } } /* Form labels - uppercase style */ swp-form-label { font-size: 11px; font-weight: 400; color: var(--color-text-secondary); text-transform: uppercase; letter-spacing: 0.5px; .optional, .auto { font-weight: 400; text-transform: none; color: var(--color-text-muted); } } /* Form value - read-only display */ swp-form-value { font-size: 15px; font-weight: 500; color: var(--color-text); } /* Form divider */ swp-form-divider { display: block; height: 1px; background: var(--color-border); margin: 20px 0; } /* Form hint text */ swp-form-hint { display: block; font-size: 12px; color: var(--color-text-muted); margin: -8px 0 16px 0; line-height: 1.4; } /* Form group - gray card background */ swp-form-group { display: block; padding: 16px; background: var(--color-background-alt); border-radius: 8px; margin-top: 16px; swp-form-row:last-child { margin-bottom: 0; } } /* Form select wrapper */ swp-form-select { display: block; select { width: 100%; padding: 10px 12px; border: 1px solid var(--color-border); border-radius: 6px; font-size: 14px; font-family: var(--font-family); color: var(--color-text); background: var(--color-surface); cursor: pointer; &:focus { outline: none; border-color: var(--color-teal); } } } /* Text inputs */ input[type="text"], input[type="date"] { width: 100%; padding: 10px 12px; border: 1px solid var(--color-border); border-radius: 6px; font-size: 14px; font-family: var(--font-family); color: var(--color-text); background: var(--color-surface); &::placeholder { color: var(--color-text-muted); } &:focus { outline: none; border-color: var(--color-teal); } } /* Date range inputs */ swp-date-range { display: flex; align-items: center; gap: 12px; input { flex: 1; &.inactive { opacity: 0.5; background: var(--color-background-alt); &:focus { opacity: 1; background: var(--color-surface); } } } span { color: var(--color-text-secondary); } } /* Drawer header with background */ swp-drawer-header { background: var(--color-background-alt); padding: 20px 24px; } swp-drawer-title { font-size: 18px; } /* Drawer body padding */ swp-drawer-body { padding: 24px; } /* Drawer footer with background */ swp-drawer-footer { display: flex; gap: 12px; padding: 20px 24px; border-top: 1px solid var(--color-border); background: var(--color-background-alt); swp-btn { flex: 1; } } } /* =========================================== DRAWER DATA ROWS (checkbox + label + input) For rate-style drawer content =========================================== */ [data-drawer] swp-data-table { display: grid; grid-template-columns: 28px 1fr 100px; } [data-drawer] swp-data-row { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; align-items: center; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--color-border); &:last-child { border-bottom: none; } input[type="checkbox"] { width: 18px; height: 18px; accent-color: var(--color-teal); } } [data-drawer] swp-data-label { font-size: var(--font-size-base); &.disabled { opacity: 0.4; } } [data-drawer] swp-data-input { display: flex; align-items: center; justify-self: end; gap: 4px; font-size: var(--font-size-sm); color: var(--color-text-secondary); input { width: 100px; padding: 6px 8px; border: 1px solid var(--color-border); border-radius: var(--radius-sm); font-size: var(--font-size-sm); font-family: var(--font-mono); text-align: right; } &.disabled input { opacity: 0.4; background: var(--color-background); } } [data-drawer] swp-section-label { margin-bottom: 12px; } [data-drawer] swp-data-section { margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--color-border); } /* =========================================== EMPTY STATE PATTERN =========================================== */ swp-empty-state { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: var(--spacing-10) var(--spacing-6); text-align: center; & i { font-size: 48px; color: var(--color-border); margin-bottom: var(--spacing-4); } & span { font-size: var(--font-size-base); color: var(--color-text-secondary); } } /* =========================================== TAGS (Generic) =========================================== */ swp-tags-row { display: flex; align-items: center; gap: var(--spacing-2); flex-wrap: wrap; } swp-tag { display: inline-flex; align-items: center; gap: var(--spacing-1); padding: var(--spacing-1) var(--spacing-3); font-size: var(--font-size-xs); font-weight: var(--font-weight-semibold); text-transform: uppercase; letter-spacing: 0.3px; border-radius: var(--radius-sm); background: var(--color-background); color: var(--color-text-secondary); &.master { background: var(--bg-purple-strong); color: var(--color-purple); } &.senior { background: var(--bg-blue-strong); color: var(--color-blue); } &.junior { background: var(--bg-amber-strong); color: #b45309; } &.cert { background: var(--bg-teal-strong); color: var(--color-teal); } &.popular { background: var(--bg-amber-strong); color: #b45309; } &.combo { background: var(--bg-teal-strong); color: var(--color-teal); } &.color { background: var(--bg-purple-strong); color: var(--color-purple); } } /* =========================================== STATUS INDICATOR (Generic) =========================================== */ swp-status-indicator { 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); } } /* =========================================== FACT BOXES (Inline) =========================================== */ swp-fact-boxes-inline { display: flex; gap: var(--spacing-12); margin-top: var(--spacing-1); flex-wrap: wrap; } swp-fact-inline { display: flex; align-items: baseline; gap: var(--spacing-2); swp-fact-inline-value { font-size: var(--font-size-lg); font-weight: var(--font-weight-semibold); font-family: var(--font-mono); color: var(--color-text); } swp-fact-inline-label { font-size: var(--font-size-sm); color: var(--color-text-secondary); } } /* =========================================== EDIT SECTION (Grid + Subgrid) =========================================== */ swp-edit-section { display: grid; grid-template-columns: 140px 1fr; gap: var(--spacing-4); } swp-edit-row { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; align-items: center; input { font-size: var(--font-size-base); padding: var(--spacing-4) var(--spacing-5); border-radius: var(--radius-sm); background: var(--color-background-alt); border: 1px solid var(--color-border); color: var(--color-text); transition: all var(--transition-fast); cursor: text; &:hover { background: var(--color-background); } &:focus { outline: none; background: var(--color-surface); border-color: var(--color-teal); } &[data-type="number"] { font-family: var(--font-mono); text-align: right; width: 150px; justify-self: end; } } } swp-edit-label { font-size: var(--font-size-md); color: var(--color-text-secondary); } swp-edit-value { font-size: var(--font-size-base); color: var(--color-text); padding: var(--spacing-4) var(--spacing-5); border-radius: var(--radius-sm); background: var(--color-background-alt); border: 1px solid transparent; transition: all var(--transition-fast); cursor: text; &:hover { background: var(--color-background); } &:focus { outline: none; background: var(--color-surface); border-color: var(--color-teal); } &.mono { font-family: var(--font-mono); width: 150px; text-align: right; justify-self: end; } } swp-edit-select { display: block; select { width: 100%; padding: var(--spacing-2) var(--spacing-4); font-size: var(--font-size-base); border: 1px solid var(--color-border); border-radius: var(--radius-sm); background: var(--color-surface); cursor: pointer; &:focus { outline: none; border-color: var(--color-teal); } } } /* =========================================== VIEW TRANSITIONS (List/Detail swap) =========================================== */ .view-fade-out { opacity: 0; } .view-fade-in { opacity: 1; } /* =========================================== BACK LINK =========================================== */ swp-back-link { display: inline-flex; align-items: center; gap: var(--spacing-2); color: var(--color-text-secondary); font-size: var(--font-size-sm); cursor: pointer; transition: color var(--transition-fast); &:hover { color: var(--color-teal); } i { font-size: 16px; } } /* =========================================== DETAIL GRID (2-column layout) =========================================== */ swp-detail-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--spacing-8); > div { display: flex; flex-direction: column; gap: var(--spacing-8); } } @media (max-width: 900px) { swp-detail-grid { grid-template-columns: 1fr; } }