Reorganizes and optimizes shared CSS components
Consolidates UI components into a centralized components.css file Removes duplicate styles across multiple CSS files Adds utility classes in a new utilities.css file Reduces overall CSS complexity and improves maintainability Removes quick-stats.css and redistributes its styles Updates layout and stylesheet references accordingly
This commit is contained in:
parent
15579acba8
commit
2e6207bb0b
33 changed files with 971 additions and 796 deletions
|
|
@ -13,10 +13,32 @@ Reference for alle genbrugelige komponenter. **LAV ALDRIG EN NY KOMPONENT HVIS D
|
|||
| `swp-page-title` | Titel-wrapper med h1 og p | h1 + subtitle |
|
||||
| `swp-page-actions` | Action buttons i header | Flex gap |
|
||||
| `swp-card` | Standard card wrapper | Border, padding, rounded |
|
||||
| `swp-card-header` | Card header | Flex, title + action |
|
||||
| `swp-card-title` | Card titel med ikon | `<swp-card-title><i>...</i> Text</swp-card-title>` |
|
||||
| `swp-section-label` | Card section label | Uppercase, 11px, border-bottom |
|
||||
| `swp-section-header` | Wrapper for label + action | Flex, space-between |
|
||||
| `swp-section-action` | Action link i section header | Teal, clickable |
|
||||
| `swp-card-content` | Card indhold | Block |
|
||||
|
||||
### Card Header Eksempler
|
||||
|
||||
**Simpel label (uden action):**
|
||||
```html
|
||||
<swp-card>
|
||||
<swp-section-label>Kontakter</swp-section-label>
|
||||
<swp-card-content>...</swp-card-content>
|
||||
</swp-card>
|
||||
```
|
||||
|
||||
**Label med action:**
|
||||
```html
|
||||
<swp-card>
|
||||
<swp-section-header>
|
||||
<swp-section-label>Dagens bookinger</swp-section-label>
|
||||
<swp-section-action>Se alle</swp-section-action>
|
||||
</swp-section-header>
|
||||
<swp-card-content>...</swp-card-content>
|
||||
</swp-card>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Stats Components (stats.css)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
*
|
||||
* For logged-in users to manage their subscription plan,
|
||||
* payment method, and view invoice history.
|
||||
*
|
||||
* Reuses: swp-btn, swp-plan-card, swp-plan-badge, swp-plan-action (components.css)
|
||||
*/
|
||||
|
||||
/* ===========================================
|
||||
|
|
@ -49,46 +51,7 @@ swp-plan-grid {
|
|||
}
|
||||
}
|
||||
|
||||
/* Plan card current state (extends auth.css) */
|
||||
swp-plan-card.current {
|
||||
border-color: var(--color-teal);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-teal) 15%, transparent);
|
||||
}
|
||||
|
||||
swp-plan-badge.current {
|
||||
background: color-mix(in srgb, var(--color-teal) 15%, transparent);
|
||||
color: var(--color-teal);
|
||||
}
|
||||
|
||||
/* Disabled button for current plan */
|
||||
swp-plan-card.current swp-btn.secondary {
|
||||
background: var(--color-background-alt);
|
||||
color: var(--color-text-secondary);
|
||||
cursor: default;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Enterprise plan styling */
|
||||
swp-plan-card.enterprise {
|
||||
background: linear-gradient(135deg, var(--color-surface) 0%, color-mix(in srgb, var(--color-purple) 5%, var(--color-surface)) 100%);
|
||||
border-color: var(--color-purple);
|
||||
}
|
||||
|
||||
swp-plan-badge.popular {
|
||||
background: color-mix(in srgb, var(--color-amber) 15%, transparent);
|
||||
color: var(--color-amber);
|
||||
}
|
||||
|
||||
/* Plan action buttons */
|
||||
swp-plan-action {
|
||||
margin-top: auto;
|
||||
padding-top: var(--card-padding);
|
||||
}
|
||||
|
||||
swp-plan-action swp-btn {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
/* Plan card/badge/action styles in components.css */
|
||||
|
||||
/* ===========================================
|
||||
BILLING GRID (2 columns)
|
||||
|
|
@ -343,37 +306,7 @@ swp-download-btn i {
|
|||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* ===========================================
|
||||
BUTTONS (account-specific)
|
||||
=========================================== */
|
||||
swp-btn.secondary {
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
swp-btn.secondary:hover {
|
||||
background: var(--color-background-hover);
|
||||
}
|
||||
|
||||
swp-btn.outline {
|
||||
background: transparent;
|
||||
border: 1px solid var(--color-teal);
|
||||
color: var(--color-teal);
|
||||
}
|
||||
|
||||
swp-btn.outline:hover {
|
||||
background: color-mix(in srgb, var(--color-teal) 10%, transparent);
|
||||
}
|
||||
|
||||
swp-btn.sm {
|
||||
padding: var(--spacing-2) var(--spacing-3);
|
||||
font-size: var(--font-size-xs);
|
||||
}
|
||||
|
||||
swp-btn.sm i {
|
||||
font-size: 14px;
|
||||
}
|
||||
/* Button styles in components.css */
|
||||
|
||||
/* ===========================================
|
||||
RESPONSIVE
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
*
|
||||
* Login, Signup, Password Reset etc.
|
||||
* Split-screen SaaS layout pattern
|
||||
*
|
||||
* Reuses: swp-btn, swp-plan-card, swp-plan-badge (components.css)
|
||||
*/
|
||||
|
||||
/* ===========================================
|
||||
|
|
@ -124,46 +126,13 @@ swp-selected-plan-header {
|
|||
}
|
||||
|
||||
/* ===========================================
|
||||
PLAN CARD (Selected Plan)
|
||||
PLAN CONTENT (Auth-specific layout)
|
||||
Plan card/badge base styles in components.css
|
||||
=========================================== */
|
||||
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);
|
||||
}
|
||||
|
||||
swp-plan-card.selected {
|
||||
border-color: var(--color-teal);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-teal) 15%, transparent);
|
||||
}
|
||||
|
||||
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;
|
||||
margin-bottom: var(--spacing-4);
|
||||
}
|
||||
|
||||
swp-plan-badge.selected {
|
||||
background: color-mix(in srgb, var(--color-teal) 15%, transparent);
|
||||
color: var(--color-teal);
|
||||
}
|
||||
|
||||
swp-plan-badge i {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
swp-plan-name {
|
||||
display: block;
|
||||
font-size: var(--font-size-2xl);
|
||||
|
|
@ -589,52 +558,7 @@ swp-form-checkbox a:hover {
|
|||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* ===========================================
|
||||
BUTTONS
|
||||
=========================================== */
|
||||
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(--border-radius);
|
||||
border: 1px solid transparent;
|
||||
cursor: pointer;
|
||||
transition: all var(--transition-fast);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
swp-btn.primary {
|
||||
background: var(--color-teal);
|
||||
color: white;
|
||||
border-color: var(--color-teal);
|
||||
}
|
||||
|
||||
swp-btn.primary:hover {
|
||||
background: #00796b;
|
||||
border-color: #00796b;
|
||||
}
|
||||
|
||||
swp-btn.primary:active {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
swp-btn.full-width {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
swp-btn.lg {
|
||||
padding: var(--spacing-4) var(--spacing-8);
|
||||
font-size: var(--font-size-lg);
|
||||
}
|
||||
|
||||
swp-btn i {
|
||||
font-size: 18px;
|
||||
}
|
||||
/* Button base styles in components.css */
|
||||
|
||||
/* ===========================================
|
||||
AUTH FOOTER
|
||||
|
|
@ -692,21 +616,7 @@ swp-social-buttons {
|
|||
gap: var(--spacing-3);
|
||||
}
|
||||
|
||||
swp-btn.social {
|
||||
background: var(--color-background);
|
||||
color: var(--color-text);
|
||||
border-color: var(--color-border);
|
||||
}
|
||||
|
||||
swp-btn.social:hover {
|
||||
background: var(--color-background-hover);
|
||||
border-color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
swp-btn.social img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
/* Social button styles in components.css */
|
||||
|
||||
/* ===========================================
|
||||
FORM MESSAGES
|
||||
|
|
@ -819,72 +729,12 @@ swp-pricing-grid swp-plan-card.popular {
|
|||
transform: scale(1.02);
|
||||
}
|
||||
|
||||
swp-pricing-grid swp-plan-card.enterprise {
|
||||
background: linear-gradient(135deg, var(--color-surface) 0%, color-mix(in srgb, var(--color-purple) 5%, var(--color-surface)) 100%);
|
||||
border-color: var(--color-purple);
|
||||
}
|
||||
|
||||
swp-plan-badge.popular {
|
||||
background: color-mix(in srgb, var(--color-teal) 15%, transparent);
|
||||
color: var(--color-teal);
|
||||
}
|
||||
|
||||
swp-plan-badge.enterprise {
|
||||
background: color-mix(in srgb, var(--color-purple) 15%, transparent);
|
||||
color: var(--color-purple);
|
||||
}
|
||||
|
||||
swp-plan-badge.free {
|
||||
background: color-mix(in srgb, var(--color-green) 15%, transparent);
|
||||
color: var(--color-green);
|
||||
}
|
||||
/* Plan badge/button styles in components.css */
|
||||
|
||||
swp-pricing-grid swp-plan-action {
|
||||
margin-top: var(--spacing-6);
|
||||
}
|
||||
|
||||
/* Button styles for pricing */
|
||||
.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(--border-radius);
|
||||
border: 1px solid transparent;
|
||||
cursor: pointer;
|
||||
transition: all var(--transition-fast);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.swp-btn.primary {
|
||||
background: var(--color-teal);
|
||||
color: white;
|
||||
border-color: var(--color-teal);
|
||||
}
|
||||
|
||||
.swp-btn.primary:hover {
|
||||
background: #00796b;
|
||||
border-color: #00796b;
|
||||
}
|
||||
|
||||
.swp-btn.outline {
|
||||
background: transparent;
|
||||
color: var(--color-purple);
|
||||
border-color: var(--color-purple);
|
||||
}
|
||||
|
||||
.swp-btn.outline:hover {
|
||||
background: color-mix(in srgb, var(--color-purple) 10%, transparent);
|
||||
}
|
||||
|
||||
.swp-btn.full-width {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
swp-pricing-footer {
|
||||
margin-top: var(--spacing-12);
|
||||
text-align: center;
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ swp-booking-employee {
|
|||
gap: var(--spacing-3);
|
||||
}
|
||||
|
||||
/* TODO: Consider using swp-avatar.size-xs from components.css instead */
|
||||
swp-booking-employee swp-avatar-small {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
*
|
||||
* Filter bar, stats, table, forms, and difference box
|
||||
* Reuses: swp-sticky-header, swp-header-content (page.css)
|
||||
* Reuses: swp-btn, swp-status-badge, swp-card-footer (components.css)
|
||||
*/
|
||||
|
||||
/* ===========================================
|
||||
|
|
@ -321,67 +322,14 @@ swp-cash-table-footer {
|
|||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
/* ===========================================
|
||||
STATUS BADGE
|
||||
=========================================== */
|
||||
/* Status badge styles in components.css */
|
||||
|
||||
/* Center status column */
|
||||
swp-cash-th:nth-child(9),
|
||||
swp-cash-td:nth-child(9) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
swp-status-badge::before {
|
||||
content: '';
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: var(--radius-full);
|
||||
background: currentColor;
|
||||
}
|
||||
|
||||
/* Status variants */
|
||||
swp-status-badge.approved,
|
||||
swp-status-badge.active {
|
||||
background: color-mix(in srgb, var(--color-green) 15%, transparent);
|
||||
color: var(--color-green);
|
||||
}
|
||||
|
||||
swp-status-badge.draft,
|
||||
swp-status-badge.invited {
|
||||
background: color-mix(in srgb, var(--color-amber) 15%, transparent);
|
||||
color: #b45309;
|
||||
}
|
||||
|
||||
/* Role variants */
|
||||
swp-status-badge.owner {
|
||||
background: color-mix(in srgb, var(--color-teal) 15%, transparent);
|
||||
color: var(--color-teal);
|
||||
}
|
||||
|
||||
swp-status-badge.admin {
|
||||
background: color-mix(in srgb, var(--color-purple) 15%, transparent);
|
||||
color: var(--color-purple);
|
||||
}
|
||||
|
||||
swp-status-badge.leader {
|
||||
background: color-mix(in srgb, var(--color-blue) 15%, transparent);
|
||||
color: var(--color-blue);
|
||||
}
|
||||
|
||||
swp-status-badge.employee {
|
||||
background: var(--color-background-alt);
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
/* ===========================================
|
||||
TWO-COLUMN GRID (Detail View)
|
||||
=========================================== */
|
||||
|
|
@ -774,78 +722,14 @@ swp-checkbox-field label {
|
|||
line-height: var(--line-height-normal);
|
||||
}
|
||||
|
||||
/* ===========================================
|
||||
CARD FOOTER (Actions)
|
||||
=========================================== */
|
||||
swp-card-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: var(--spacing-8) var(--spacing-10);
|
||||
background: var(--color-background-alt);
|
||||
border-top: 1px solid var(--color-border);
|
||||
margin: var(--spacing-10) calc(-1 * var(--spacing-5)) calc(-1 * var(--spacing-5));
|
||||
border-radius: 0 0 var(--border-radius-lg) var(--border-radius-lg);
|
||||
}
|
||||
/* Card footer base styles in components.css */
|
||||
|
||||
swp-actions-right {
|
||||
display: flex;
|
||||
gap: var(--spacing-5);
|
||||
}
|
||||
|
||||
/* ===========================================
|
||||
BUTTONS
|
||||
=========================================== */
|
||||
swp-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-3);
|
||||
padding: var(--spacing-5) var(--spacing-8);
|
||||
font-size: var(--font-size-md);
|
||||
font-weight: var(--font-weight-medium);
|
||||
font-family: var(--font-family);
|
||||
border-radius: var(--radius-md);
|
||||
cursor: pointer;
|
||||
transition: all var(--transition-fast);
|
||||
border: none;
|
||||
}
|
||||
|
||||
swp-btn i {
|
||||
font-size: var(--font-size-lg);
|
||||
}
|
||||
|
||||
swp-btn.primary {
|
||||
background: var(--color-teal);
|
||||
color: white;
|
||||
}
|
||||
|
||||
swp-btn.primary:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
swp-btn.primary:disabled {
|
||||
background: var(--color-border);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
swp-btn.secondary {
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
swp-btn.secondary:hover {
|
||||
background: var(--color-background-hover);
|
||||
}
|
||||
|
||||
swp-btn.ghost {
|
||||
background: transparent;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
swp-btn.ghost:hover {
|
||||
color: var(--color-text);
|
||||
}
|
||||
/* Button styles in components.css */
|
||||
|
||||
/* ===========================================
|
||||
SYSTEM NOTE
|
||||
|
|
|
|||
434
PlanTempus.Application/wwwroot/css/components.css
Normal file
434
PlanTempus.Application/wwwroot/css/components.css
Normal file
|
|
@ -0,0 +1,434 @@
|
|||
/**
|
||||
* 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)
|
||||
*/
|
||||
|
||||
/* ===========================================
|
||||
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;
|
||||
}
|
||||
|
||||
swp-btn i {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
/* Primary button */
|
||||
swp-btn.primary {
|
||||
background: var(--color-teal);
|
||||
color: white;
|
||||
border-color: var(--color-teal);
|
||||
}
|
||||
|
||||
swp-btn.primary:hover {
|
||||
background: #00796b;
|
||||
border-color: #00796b;
|
||||
}
|
||||
|
||||
swp-btn.primary:active {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
swp-btn.primary:disabled {
|
||||
background: var(--color-border);
|
||||
border-color: var(--color-border);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Secondary button */
|
||||
swp-btn.secondary {
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
swp-btn.secondary:hover {
|
||||
background: var(--color-background-hover);
|
||||
}
|
||||
|
||||
/* Ghost button */
|
||||
swp-btn.ghost {
|
||||
background: transparent;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
swp-btn.ghost:hover {
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
/* Outline button */
|
||||
swp-btn.outline {
|
||||
background: transparent;
|
||||
border: 1px solid var(--color-teal);
|
||||
color: var(--color-teal);
|
||||
}
|
||||
|
||||
swp-btn.outline:hover {
|
||||
background: color-mix(in srgb, var(--color-teal) 10%, transparent);
|
||||
}
|
||||
|
||||
swp-btn.outline.purple {
|
||||
border-color: var(--color-purple);
|
||||
color: var(--color-purple);
|
||||
}
|
||||
|
||||
swp-btn.outline.purple:hover {
|
||||
background: color-mix(in srgb, var(--color-purple) 10%, transparent);
|
||||
}
|
||||
|
||||
/* Social button */
|
||||
swp-btn.social {
|
||||
background: var(--color-background);
|
||||
color: var(--color-text);
|
||||
border-color: var(--color-border);
|
||||
}
|
||||
|
||||
swp-btn.social:hover {
|
||||
background: var(--color-background-hover);
|
||||
border-color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
swp-btn.social img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
/* Size variants */
|
||||
swp-btn.sm {
|
||||
padding: var(--spacing-2) var(--spacing-3);
|
||||
font-size: var(--font-size-xs);
|
||||
}
|
||||
|
||||
swp-btn.sm i {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
swp-btn.lg {
|
||||
padding: var(--spacing-4) var(--spacing-8);
|
||||
font-size: var(--font-size-lg);
|
||||
}
|
||||
|
||||
/* Full width */
|
||||
swp-btn.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);
|
||||
}
|
||||
|
||||
swp-status-badge::before {
|
||||
content: '';
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: var(--radius-full);
|
||||
background: currentColor;
|
||||
}
|
||||
|
||||
/* Status variants */
|
||||
swp-status-badge.approved,
|
||||
swp-status-badge.active {
|
||||
background: color-mix(in srgb, var(--color-green) 15%, transparent);
|
||||
color: var(--color-green);
|
||||
}
|
||||
|
||||
swp-status-badge.draft,
|
||||
swp-status-badge.invited {
|
||||
background: color-mix(in srgb, var(--color-amber) 15%, transparent);
|
||||
color: #b45309;
|
||||
}
|
||||
|
||||
/* Role variants */
|
||||
swp-status-badge.owner {
|
||||
background: color-mix(in srgb, var(--color-teal) 15%, transparent);
|
||||
color: var(--color-teal);
|
||||
}
|
||||
|
||||
swp-status-badge.admin {
|
||||
background: color-mix(in srgb, var(--color-purple) 15%, transparent);
|
||||
color: var(--color-purple);
|
||||
}
|
||||
|
||||
swp-status-badge.leader {
|
||||
background: color-mix(in srgb, var(--color-blue) 15%, transparent);
|
||||
color: var(--color-blue);
|
||||
}
|
||||
|
||||
swp-status-badge.employee {
|
||||
background: var(--color-background-alt);
|
||||
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);
|
||||
}
|
||||
|
||||
swp-plan-card.selected,
|
||||
swp-plan-card.current {
|
||||
border-color: var(--color-teal);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-teal) 15%, transparent);
|
||||
}
|
||||
|
||||
swp-plan-card.popular {
|
||||
border-color: var(--color-amber);
|
||||
}
|
||||
|
||||
swp-plan-card.enterprise {
|
||||
background: linear-gradient(135deg, var(--color-surface) 0%, color-mix(in srgb, var(--color-purple) 5%, var(--color-surface)) 100%);
|
||||
border-color: var(--color-purple);
|
||||
}
|
||||
|
||||
/* Disabled button for current plan */
|
||||
swp-plan-card.current swp-btn.secondary {
|
||||
background: var(--color-background-alt);
|
||||
color: var(--color-text-secondary);
|
||||
cursor: default;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
swp-plan-badge.current,
|
||||
swp-plan-badge.selected {
|
||||
background: color-mix(in srgb, var(--color-teal) 15%, transparent);
|
||||
color: var(--color-teal);
|
||||
}
|
||||
|
||||
swp-plan-badge.popular {
|
||||
background: color-mix(in srgb, var(--color-amber) 15%, transparent);
|
||||
color: var(--color-amber);
|
||||
}
|
||||
|
||||
swp-plan-badge.enterprise {
|
||||
background: color-mix(in srgb, var(--color-purple) 15%, transparent);
|
||||
color: var(--color-purple);
|
||||
}
|
||||
|
||||
swp-plan-badge.free {
|
||||
background: color-mix(in srgb, var(--color-green) 15%, transparent);
|
||||
color: var(--color-green);
|
||||
}
|
||||
|
||||
swp-plan-badge i {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Plan action */
|
||||
swp-plan-action {
|
||||
margin-top: auto;
|
||||
padding-top: var(--card-padding);
|
||||
}
|
||||
|
||||
swp-plan-action 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) */
|
||||
swp-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
||||
/* Size variants */
|
||||
swp-avatar.size-xs {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
swp-avatar.size-sm {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
font-size: var(--font-size-xs);
|
||||
}
|
||||
|
||||
swp-avatar.size-lg {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
font-size: var(--font-size-2xl);
|
||||
}
|
||||
|
||||
/* Color variants */
|
||||
swp-avatar.purple {
|
||||
background: var(--color-purple);
|
||||
}
|
||||
|
||||
swp-avatar.blue {
|
||||
background: var(--color-blue);
|
||||
}
|
||||
|
||||
swp-avatar.amber {
|
||||
background: var(--color-amber);
|
||||
}
|
||||
|
||||
swp-avatar.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);
|
||||
}
|
||||
|
||||
swp-icon-btn:hover {
|
||||
background: var(--color-background-alt);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
swp-icon-btn.danger:hover {
|
||||
background: color-mix(in srgb, var(--color-red) 10%, transparent);
|
||||
color: var(--color-red);
|
||||
}
|
||||
|
||||
swp-icon-btn i {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
/* ===========================================
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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-header 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);
|
||||
}
|
||||
|
||||
swp-section-action: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);
|
||||
}
|
||||
|
|
@ -3,7 +3,8 @@
|
|||
*
|
||||
* Employees-specific styling only.
|
||||
* Reuses: swp-stat-card (stats.css), swp-stats-row (stats.css), swp-tab-bar (tabs.css),
|
||||
* swp-btn (cash.css), swp-status-badge (cash.css), swp-row-toggle (cash.css),
|
||||
* swp-btn, swp-status-badge, swp-icon-btn, swp-card, swp-section-label (components.css),
|
||||
* swp-row-toggle (cash.css),
|
||||
* swp-sticky-header, swp-header-content (page.css),
|
||||
* swp-toggle-slider, swp-checkbox-list (controls.css)
|
||||
*
|
||||
|
|
@ -57,8 +58,8 @@ swp-users-progress-bar {
|
|||
swp-employee-table-card {
|
||||
display: block;
|
||||
background: var(--color-surface);
|
||||
border-radius: var(--radius-lg);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius-lg);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
|
@ -195,33 +196,7 @@ swp-table-actions {
|
|||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
swp-icon-btn:hover {
|
||||
background: var(--color-background-alt);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
swp-icon-btn.danger:hover {
|
||||
background: color-mix(in srgb, var(--color-red) 10%, transparent);
|
||||
color: var(--color-red);
|
||||
}
|
||||
|
||||
swp-icon-btn i {
|
||||
font-size: 18px;
|
||||
}
|
||||
/* Icon button styles in components.css */
|
||||
|
||||
/* ===========================================
|
||||
PERMISSIONS MATRIX
|
||||
|
|
@ -452,7 +427,7 @@ swp-edit-row {
|
|||
}
|
||||
|
||||
swp-edit-label {
|
||||
font-size: var(--font-size-sm);
|
||||
font-size: var(--font-size-md);
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
|
|
@ -477,16 +452,7 @@ swp-edit-value:focus {
|
|||
border-color: var(--color-teal);
|
||||
}
|
||||
|
||||
/* Section label in cards */
|
||||
swp-section-label {
|
||||
display: block;
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-text);
|
||||
margin-bottom: var(--spacing-6);
|
||||
padding-bottom: var(--spacing-4);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
/* swp-section-label is now in components.css */
|
||||
|
||||
/* ===========================================
|
||||
VIEW CONTAINERS (List/Detail swap)
|
||||
|
|
@ -532,12 +498,7 @@ swp-detail-grid > div {
|
|||
gap: var(--spacing-8);
|
||||
}
|
||||
|
||||
swp-detail-grid swp-card {
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: var(--card-padding);
|
||||
}
|
||||
/* swp-card base styles in components.css */
|
||||
|
||||
@media (max-width: 900px) {
|
||||
swp-detail-grid {
|
||||
|
|
|
|||
|
|
@ -78,54 +78,9 @@ swp-page-actions {
|
|||
}
|
||||
|
||||
/* ===========================================
|
||||
CARDS
|
||||
CARD CONTENT GRIDS (Page-specific)
|
||||
Base card styles in components.css
|
||||
=========================================== */
|
||||
swp-card {
|
||||
display: block;
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius-lg);
|
||||
padding: var(--card-padding);
|
||||
}
|
||||
|
||||
swp-card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: calc(-1 * var(--card-padding)) calc(-1 * var(--card-padding)) var(--spacing-5) calc(-1 * var(--card-padding));
|
||||
padding: var(--spacing-4) var(--card-padding);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
swp-card-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-2);
|
||||
font-size: var(--font-size-base);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
swp-card-title i {
|
||||
font-size: var(--font-size-xl);
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
swp-card-action {
|
||||
font-size: var(--font-size-md);
|
||||
color: var(--color-teal);
|
||||
cursor: pointer;
|
||||
transition: opacity var(--transition-fast);
|
||||
}
|
||||
|
||||
swp-card-action:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
swp-card-content {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Card content with grid lists - auto-detect via :has() */
|
||||
swp-card-content:has(> swp-booking-list),
|
||||
swp-card-content:has(> swp-notification-list),
|
||||
|
|
|
|||
|
|
@ -1,38 +0,0 @@
|
|||
/**
|
||||
* Quick Stats CSS
|
||||
*
|
||||
* Styling for quick stats components in sidebar
|
||||
*/
|
||||
|
||||
/* ===========================================
|
||||
QUICK STATS CONTAINER
|
||||
=========================================== */
|
||||
swp-quick-stats {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: var(--card-gap);
|
||||
}
|
||||
|
||||
/* ===========================================
|
||||
QUICK STAT ITEM
|
||||
=========================================== */
|
||||
swp-quick-stat {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-2);
|
||||
padding: var(--card-padding);
|
||||
background: var(--color-background-alt);
|
||||
border-radius: var(--radius-md);
|
||||
}
|
||||
|
||||
swp-quick-stat swp-stat-value {
|
||||
font-size: var(--font-size-xl);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
font-family: var(--font-mono);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
swp-quick-stat swp-stat-label {
|
||||
font-size: var(--font-size-xs);
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
|
@ -208,6 +208,36 @@ swp-stat-item swp-stat-label {
|
|||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* ===========================================
|
||||
QUICK STATS (Sidebar Variant)
|
||||
=========================================== */
|
||||
swp-quick-stats {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: var(--card-gap);
|
||||
}
|
||||
|
||||
swp-quick-stat {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-2);
|
||||
padding: var(--card-padding);
|
||||
background: var(--color-background-alt);
|
||||
border-radius: var(--radius-md);
|
||||
}
|
||||
|
||||
swp-quick-stat swp-stat-value {
|
||||
font-size: var(--font-size-xl);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
font-family: var(--font-mono);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
swp-quick-stat swp-stat-label {
|
||||
font-size: var(--font-size-xs);
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
/* ===========================================
|
||||
RESPONSIVE
|
||||
=========================================== */
|
||||
|
|
|
|||
118
PlanTempus.Application/wwwroot/css/utilities.css
Normal file
118
PlanTempus.Application/wwwroot/css/utilities.css
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/**
|
||||
* Utilities - Common utility classes
|
||||
*
|
||||
* Reusable utility classes for common patterns.
|
||||
* Use sparingly - prefer semantic component styles.
|
||||
*/
|
||||
|
||||
/* ===========================================
|
||||
FLEXBOX UTILITIES
|
||||
=========================================== */
|
||||
.flex-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.flex-between {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.flex-start {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.flex-end {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.flex-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.flex-1 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.flex-shrink-0 {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* ===========================================
|
||||
TEXT UTILITIES
|
||||
=========================================== */
|
||||
.text-truncate {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.text-secondary {
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.text-mono {
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
/* ===========================================
|
||||
SPACING UTILITIES
|
||||
=========================================== */
|
||||
.gap-2 { gap: var(--spacing-2); }
|
||||
.gap-3 { gap: var(--spacing-3); }
|
||||
.gap-4 { gap: var(--spacing-4); }
|
||||
.gap-6 { gap: var(--spacing-6); }
|
||||
.gap-8 { gap: var(--spacing-8); }
|
||||
|
||||
.mt-auto { margin-top: auto; }
|
||||
.mb-0 { margin-bottom: 0; }
|
||||
|
||||
/* ===========================================
|
||||
VISIBILITY UTILITIES
|
||||
=========================================== */
|
||||
.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* ===========================================
|
||||
WIDTH UTILITIES
|
||||
=========================================== */
|
||||
.w-full {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.min-w-0 {
|
||||
min-width: 0;
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
* Waitlist CSS
|
||||
*
|
||||
* Styling for waitlist mini card and drawer items
|
||||
*
|
||||
* Reuses: swp-btn, swp-avatar (components.css)
|
||||
*/
|
||||
|
||||
/* ===========================================
|
||||
|
|
@ -84,19 +86,7 @@ swp-waitlist-customer {
|
|||
gap: var(--spacing-6);
|
||||
}
|
||||
|
||||
swp-waitlist-customer swp-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: var(--radius-full);
|
||||
background: var(--color-teal);
|
||||
color: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: var(--font-size-base);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
/* Avatar base styles in components.css */
|
||||
|
||||
swp-waitlist-customer-info {
|
||||
flex: 1;
|
||||
|
|
@ -191,39 +181,9 @@ swp-waitlist-actions {
|
|||
border-top: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
/* Button base styles in components.css */
|
||||
swp-waitlist-actions swp-btn {
|
||||
flex: 1;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: var(--spacing-2);
|
||||
padding: var(--spacing-4) var(--spacing-6);
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-medium);
|
||||
font-family: var(--font-family);
|
||||
border-radius: var(--radius-md);
|
||||
cursor: pointer;
|
||||
transition: all var(--transition-fast);
|
||||
border: none;
|
||||
}
|
||||
|
||||
swp-waitlist-actions swp-btn.secondary {
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
swp-waitlist-actions swp-btn.secondary:hover {
|
||||
background: var(--color-background-hover);
|
||||
}
|
||||
|
||||
swp-waitlist-actions swp-btn.primary {
|
||||
background: var(--color-teal);
|
||||
color: white;
|
||||
}
|
||||
|
||||
swp-waitlist-actions swp-btn.primary:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* ===========================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue