This commit is contained in:
Janus C. H. Knudsen 2026-01-10 20:39:17 +01:00
parent 54b057886c
commit 7fc1ae0650
204 changed files with 4345 additions and 134 deletions

View file

@ -0,0 +1,50 @@
/**
* App Layout - Main Grid Structure
*
* Definerer den overordnede app-struktur med sidebar og main content
*/
/* ===========================================
MAIN APP GRID
=========================================== */
swp-app-layout {
display: grid;
grid-template-columns: var(--side-menu-width) 1fr;
grid-template-rows: var(--topbar-height) 1fr;
height: 100vh;
transition: grid-template-columns var(--transition-normal);
}
/* ===========================================
COLLAPSED MENU STATE
=========================================== */
swp-app-layout.menu-collapsed {
grid-template-columns: var(--side-menu-width-collapsed) 1fr;
}
/* ===========================================
MAIN CONTENT AREA
=========================================== */
swp-main-content {
display: block;
overflow-y: auto;
background: var(--color-background);
}
/* ===========================================
DRAWER OVERLAY
=========================================== */
swp-drawer-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
z-index: var(--z-overlay);
opacity: 0;
visibility: hidden;
transition: opacity var(--transition-normal), visibility var(--transition-normal);
}
swp-drawer-overlay.active {
opacity: 1;
visibility: visible;
}

View file

@ -0,0 +1,118 @@
/**
* Base Styles - Reset & Global Elements
*
* Normalization og grundlæggende styling
*/
/* ===========================================
FONT FACES
=========================================== */
@font-face {
font-family: 'Poppins';
src: url('../fonts/Poppins-Regular.woff') format('woff');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Poppins';
src: url('../fonts/Poppins-Medium.woff') format('woff');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Poppins';
src: url('../fonts/Poppins-SemiBold.woff') format('woff');
font-weight: 600;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Poppins';
src: url('../fonts/Poppins-Bold.woff') format('woff');
font-weight: 700;
font-style: normal;
font-display: swap;
}
/* ===========================================
RESET
=========================================== */
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
height: 100%;
}
/* ===========================================
BASE ELEMENTS
=========================================== */
body {
font-family: var(--font-family);
font-size: var(--font-size-base);
color: var(--color-text);
background: var(--color-background);
line-height: var(--line-height-normal);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* Links */
a {
color: var(--color-teal);
text-decoration: none;
transition: color var(--transition-fast);
}
a:hover {
text-decoration: underline;
}
/* Lists */
ul, ol {
list-style: none;
}
/* Images */
img {
max-width: 100%;
height: auto;
display: block;
}
/* Buttons */
button {
font-family: inherit;
cursor: pointer;
}
/* Inputs */
input,
textarea,
select {
font-family: inherit;
font-size: inherit;
}
/* Focus visible */
:focus-visible {
outline: 2px solid var(--color-teal);
outline-offset: 2px;
}
/* Selection */
::selection {
background: var(--color-teal-light);
color: var(--color-text);
}

View file

@ -0,0 +1,163 @@
/**
* SWP Design System - CSS Variables
*
* Dette er den centrale definition af alle design tokens.
* Alle farver, fonts og layout-variabler defineres her.
*/
/* ===========================================
COLOR PALETTE - Light Mode (Default)
=========================================== */
:root {
/* Surfaces */
--color-surface: #fff;
--color-background: #f5f5f5;
--color-background-hover: #f0f0f0;
--color-background-alt: #fafafa;
/* Borders */
--color-border: #e0e0e0;
--color-border-light: #f0f0f0;
/* Text */
--color-text: #333;
--color-text-secondary: #666;
--color-text-muted: #999;
/* Brand Colors */
--color-teal: #00897b;
--color-teal-light: color-mix(in srgb, var(--color-teal) 10%, transparent);
/* Semantic Colors */
--color-blue: #1976d2;
--color-green: #43a047;
--color-amber: #f59e0b;
--color-red: #e53935;
--color-purple: #8b5cf6;
}
/* ===========================================
COLOR PALETTE - Dark Mode (System)
=========================================== */
@media (prefers-color-scheme: dark) {
:root:not(.light-mode) {
--color-surface: #1e1e1e;
--color-background: #121212;
--color-background-hover: #2a2a2a;
--color-background-alt: #1a1a1a;
--color-border: #333;
--color-border-light: #2a2a2a;
--color-text: #e0e0e0;
--color-text-secondary: #999;
--color-text-muted: #666;
--color-teal: #26a69a;
--color-blue: #42a5f5;
--color-green: #66bb6a;
--color-amber: #ffb74d;
--color-red: #ef5350;
--color-purple: #a78bfa;
}
}
/* ===========================================
COLOR PALETTE - Dark Mode (Manual)
=========================================== */
:root.dark-mode {
--color-surface: #1e1e1e;
--color-background: #121212;
--color-background-hover: #2a2a2a;
--color-background-alt: #1a1a1a;
--color-border: #333;
--color-border-light: #2a2a2a;
--color-text: #e0e0e0;
--color-text-secondary: #999;
--color-text-muted: #666;
--color-teal: #26a69a;
--color-blue: #42a5f5;
--color-green: #66bb6a;
--color-amber: #ffb74d;
--color-red: #ef5350;
--color-purple: #a78bfa;
}
/* ===========================================
TYPOGRAPHY
=========================================== */
:root {
--font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
--font-mono: 'JetBrains Mono', monospace;
/* Font Sizes */
--font-size-xs: 11px;
--font-size-sm: 12px;
--font-size-base: 14px;
--font-size-md: 13px;
--font-size-lg: 16px;
--font-size-xl: 22px;
/* Line Heights */
--line-height-tight: 1.25;
--line-height-normal: 1.5;
--line-height-relaxed: 1.75;
}
/* ===========================================
SPACING
=========================================== */
:root {
--spacing-1: 4px;
--spacing-2: 8px;
--spacing-3: 12px;
--spacing-4: 16px;
--spacing-5: 20px;
--spacing-6: 24px;
--spacing-8: 32px;
}
/* ===========================================
LAYOUT
=========================================== */
:root {
--side-menu-width: 240px;
--side-menu-width-collapsed: 64px;
--topbar-height: 56px;
--page-max-width: 1400px;
--border-radius: 6px;
--border-radius-lg: 8px;
}
/* ===========================================
TRANSITIONS
=========================================== */
:root {
--transition-fast: 150ms ease;
--transition-normal: 200ms ease;
--transition-slow: 300ms ease;
}
/* ===========================================
Z-INDEX LAYERS
=========================================== */
:root {
--z-dropdown: 100;
--z-sticky: 200;
--z-overlay: 900;
--z-drawer: 1000;
--z-modal: 1100;
--z-tooltip: 1200;
}
/* ===========================================
SHADOWS
=========================================== */
:root {
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 2px 8px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.15);
}

View file

@ -0,0 +1,258 @@
/**
* Drawers - Slide-in Panels
*
* Profile drawer, notifications drawer, etc.
*/
/* ===========================================
BASE DRAWER
=========================================== */
swp-profile-drawer,
swp-notification-drawer,
swp-todo-drawer {
position: fixed;
top: 0;
right: 0;
width: 320px;
height: 100vh;
background: var(--color-surface);
border-left: 1px solid var(--color-border);
box-shadow: var(--shadow-lg);
z-index: var(--z-drawer);
display: flex;
flex-direction: column;
transform: translateX(100%);
transition: transform var(--transition-normal);
}
swp-profile-drawer.active,
swp-notification-drawer.active,
swp-todo-drawer.active {
transform: translateX(0);
}
/* ===========================================
DRAWER HEADER
=========================================== */
swp-drawer-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--spacing-4) var(--spacing-5);
border-bottom: 1px solid var(--color-border);
flex-shrink: 0;
}
swp-drawer-title {
font-size: var(--font-size-lg);
font-weight: 600;
color: var(--color-text);
}
swp-drawer-close {
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border: none;
background: transparent;
border-radius: var(--border-radius);
cursor: pointer;
color: var(--color-text-secondary);
transition: all var(--transition-fast);
}
swp-drawer-close:hover {
background: var(--color-background-hover);
color: var(--color-text);
}
swp-drawer-close i {
font-size: 20px;
}
/* ===========================================
DRAWER CONTENT
=========================================== */
swp-drawer-content {
flex: 1;
overflow-y: auto;
padding: var(--spacing-5);
}
swp-drawer-divider {
height: 1px;
background: var(--color-border);
margin: var(--spacing-4) 0;
}
/* ===========================================
PROFILE SECTION
=========================================== */
swp-profile-section {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
padding: var(--spacing-4) 0;
}
swp-profile-avatar-large {
width: 64px;
height: 64px;
border-radius: 50%;
background: var(--color-teal);
color: white;
font-size: 24px;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: var(--spacing-3);
}
swp-profile-name-large {
font-size: var(--font-size-lg);
font-weight: 600;
color: var(--color-text);
margin-bottom: var(--spacing-1);
}
swp-profile-email {
font-size: var(--font-size-sm);
color: var(--color-text-secondary);
}
/* ===========================================
DRAWER MENU
=========================================== */
swp-drawer-menu {
display: flex;
flex-direction: column;
gap: var(--spacing-1);
}
swp-drawer-menu-item {
display: flex;
align-items: center;
gap: var(--spacing-3);
padding: var(--spacing-3) var(--spacing-3);
border-radius: var(--border-radius);
cursor: pointer;
transition: background var(--transition-fast);
color: var(--color-text);
}
swp-drawer-menu-item:hover {
background: var(--color-background-hover);
}
swp-drawer-menu-item i {
font-size: 20px;
color: var(--color-text-secondary);
}
/* ===========================================
THEME TOGGLE
=========================================== */
swp-theme-toggle {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--spacing-3);
border-radius: var(--border-radius);
background: var(--color-background);
}
swp-theme-label {
display: flex;
align-items: center;
gap: var(--spacing-3);
color: var(--color-text);
}
swp-theme-label i {
font-size: 20px;
color: var(--color-text-secondary);
}
swp-toggle-switch {
position: relative;
width: 44px;
height: 24px;
}
swp-toggle-switch input {
opacity: 0;
width: 0;
height: 0;
}
swp-toggle-slider {
position: absolute;
cursor: pointer;
inset: 0;
background: var(--color-border);
border-radius: 12px;
transition: background var(--transition-fast);
}
swp-toggle-slider::before {
content: '';
position: absolute;
width: 18px;
height: 18px;
left: 3px;
bottom: 3px;
background: white;
border-radius: 50%;
transition: transform var(--transition-fast);
}
swp-toggle-switch input:checked + swp-toggle-slider {
background: var(--color-teal);
}
swp-toggle-switch input:checked + swp-toggle-slider::before {
transform: translateX(20px);
}
/* ===========================================
DRAWER FOOTER
=========================================== */
swp-drawer-footer {
padding: var(--spacing-4) var(--spacing-5);
border-top: 1px solid var(--color-border);
flex-shrink: 0;
}
swp-drawer-action {
display: flex;
align-items: center;
justify-content: center;
gap: var(--spacing-2);
width: 100%;
padding: var(--spacing-3);
font-size: var(--font-size-base);
font-family: var(--font-family);
color: var(--color-text-secondary);
background: transparent;
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
cursor: pointer;
transition: all var(--transition-fast);
}
swp-drawer-action:hover {
background: var(--color-background-hover);
}
swp-drawer-action.logout:hover {
color: var(--color-red);
border-color: var(--color-red);
}
swp-drawer-action i {
font-size: 18px;
}

View file

@ -0,0 +1,204 @@
/**
* Page Layout - Content Area Structure
*
* Page container, headers, cards og grid layouts
*/
/* ===========================================
PAGE CONTAINER
=========================================== */
swp-page-container {
display: block;
max-width: var(--page-max-width);
margin: 0 auto;
padding: var(--spacing-6);
}
/* ===========================================
PAGE HEADER
=========================================== */
swp-page-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
margin-bottom: var(--spacing-6);
}
swp-page-title h1 {
font-size: 24px;
font-weight: 600;
color: var(--color-text);
margin-bottom: var(--spacing-1);
}
swp-page-title p {
font-size: var(--font-size-base);
color: var(--color-text-secondary);
}
swp-page-actions {
display: flex;
gap: var(--spacing-2);
}
/* ===========================================
CARDS
=========================================== */
swp-card {
display: block;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--border-radius-lg);
margin-bottom: var(--spacing-5);
}
swp-card-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--spacing-4) var(--spacing-5);
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: 600;
color: var(--color-text);
}
swp-card-title i {
font-size: 20px;
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 {
padding: var(--spacing-5);
}
/* ===========================================
DASHBOARD GRID
=========================================== */
swp-dashboard-grid {
display: grid;
grid-template-columns: 1fr 350px;
gap: var(--spacing-5);
}
swp-main-column {
display: flex;
flex-direction: column;
}
swp-side-column {
display: flex;
flex-direction: column;
}
/* ===========================================
AI INSIGHT
=========================================== */
swp-ai-insight {
display: block;
padding: var(--spacing-4) var(--spacing-5);
background: linear-gradient(135deg,
color-mix(in srgb, var(--color-purple) 8%, transparent),
color-mix(in srgb, var(--color-teal) 8%, transparent)
);
border-radius: var(--border-radius);
}
swp-ai-header {
display: flex;
align-items: center;
gap: var(--spacing-2);
margin-bottom: var(--spacing-2);
font-size: var(--font-size-sm);
font-weight: 500;
color: var(--color-purple);
}
swp-ai-header i {
font-size: 16px;
}
swp-ai-text {
font-size: var(--font-size-base);
color: var(--color-text);
line-height: var(--line-height-relaxed);
}
/* ===========================================
QUICK ACTIONS
=========================================== */
swp-quick-actions {
display: flex;
flex-direction: column;
gap: var(--spacing-2);
}
swp-quick-action-btn {
display: flex;
align-items: center;
gap: var(--spacing-2);
padding: var(--spacing-3);
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);
cursor: pointer;
transition: all var(--transition-fast);
}
swp-quick-action-btn:hover {
background: var(--color-background-hover);
border-color: var(--color-teal);
color: var(--color-teal);
}
swp-quick-action-btn i {
font-size: 18px;
}
/* ===========================================
RESPONSIVE
=========================================== */
@media (max-width: 1200px) {
swp-dashboard-grid {
grid-template-columns: 1fr;
}
swp-side-column {
order: -1;
}
}
@media (max-width: 768px) {
swp-page-container {
padding: var(--spacing-4);
}
swp-page-header {
flex-direction: column;
gap: var(--spacing-4);
}
swp-page-actions {
width: 100%;
}
}

View file

@ -0,0 +1,246 @@
/**
* Sidebar - Side Menu Component
*
* Navigation sidebar med collapse-funktionalitet
*/
/* ===========================================
SIDE MENU CONTAINER
=========================================== */
swp-side-menu {
grid-row: 1 / -1;
display: flex;
flex-direction: column;
background: var(--color-surface);
border-right: 1px solid var(--color-border);
overflow-y: auto;
overflow-x: hidden;
}
/* ===========================================
HEADER
=========================================== */
swp-side-menu-header {
display: flex;
align-items: center;
gap: 10px;
height: var(--topbar-height);
padding: 0 var(--spacing-4);
border-bottom: 1px solid var(--color-border);
flex-shrink: 0;
}
swp-side-menu-header > i {
font-size: 26px;
color: var(--color-teal);
}
swp-side-menu-logo {
font-size: var(--font-size-lg);
font-weight: 600;
color: var(--color-text);
}
/* Toggle Button */
swp-menu-toggle {
margin-left: auto;
width: 28px;
height: 28px;
display: flex;
align-items: center;
justify-content: center;
border: none;
background: transparent;
border-radius: var(--border-radius);
cursor: pointer;
color: var(--color-text-secondary);
transition: all var(--transition-fast);
}
swp-menu-toggle:hover {
background: var(--color-background-hover);
color: var(--color-text);
}
swp-menu-toggle i {
font-size: 18px;
color: inherit;
transition: transform var(--transition-normal);
}
/* ===========================================
NAVIGATION
=========================================== */
swp-side-menu-nav {
flex: 1;
padding: var(--spacing-3) 0;
overflow-y: auto;
}
swp-side-menu-group {
display: block;
margin-bottom: var(--spacing-2);
}
swp-side-menu-label {
display: block;
padding: var(--spacing-2) var(--spacing-4) 6px;
font-size: var(--font-size-xs);
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--color-text-secondary);
}
/* ===========================================
MENU ITEMS
=========================================== */
swp-side-menu-item,
a[is="swp-side-menu-item"] {
display: flex;
align-items: center;
gap: var(--spacing-3);
padding: 10px var(--spacing-4);
color: var(--color-text);
cursor: pointer;
transition: all var(--transition-fast);
border-left: 3px solid transparent;
text-decoration: none;
}
swp-side-menu-item:hover,
a[is="swp-side-menu-item"]:hover {
background: var(--color-background-hover);
text-decoration: none;
}
swp-side-menu-item[data-active="true"],
a[is="swp-side-menu-item"][data-active="true"] {
background: var(--color-teal-light);
border-left-color: var(--color-teal);
color: var(--color-teal);
font-weight: 500;
}
swp-side-menu-item i,
a[is="swp-side-menu-item"] i {
font-size: 20px;
flex-shrink: 0;
}
/* ===========================================
FOOTER
=========================================== */
swp-side-menu-footer {
display: flex;
flex-direction: column;
gap: var(--spacing-2);
padding: var(--spacing-3) var(--spacing-4);
border-top: 1px solid var(--color-border);
margin-top: auto;
flex-shrink: 0;
}
swp-side-menu-action {
display: flex;
align-items: center;
justify-content: center;
gap: var(--spacing-2);
padding: 10px;
font-size: var(--font-size-md);
color: var(--color-text-secondary);
background: transparent;
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
cursor: pointer;
transition: all var(--transition-fast);
font-family: var(--font-family);
}
swp-side-menu-action:hover {
background: var(--color-background-hover);
}
swp-side-menu-action.lock:hover {
color: var(--color-amber);
border-color: var(--color-amber);
}
swp-side-menu-action.logout:hover {
color: var(--color-red);
border-color: var(--color-red);
}
swp-side-menu-action i {
font-size: 18px;
}
/* ===========================================
COLLAPSED STATE
=========================================== */
swp-app-layout.menu-collapsed swp-side-menu {
overflow: visible;
}
swp-app-layout.menu-collapsed swp-side-menu-logo,
swp-app-layout.menu-collapsed swp-side-menu-label,
swp-app-layout.menu-collapsed swp-side-menu-item span,
swp-app-layout.menu-collapsed swp-side-menu-action span,
swp-app-layout.menu-collapsed a[is="swp-side-menu-item"] span {
display: none;
}
swp-app-layout.menu-collapsed swp-side-menu-header {
justify-content: center;
padding: 0;
}
swp-app-layout.menu-collapsed swp-menu-toggle {
margin-left: 0;
}
swp-app-layout.menu-collapsed swp-menu-toggle i {
transform: rotate(180deg);
}
swp-app-layout.menu-collapsed swp-side-menu-item,
swp-app-layout.menu-collapsed a[is="swp-side-menu-item"] {
justify-content: center;
padding: var(--spacing-3);
border-left: none;
}
swp-app-layout.menu-collapsed swp-side-menu-item[data-active="true"],
swp-app-layout.menu-collapsed a[is="swp-side-menu-item"][data-active="true"] {
border-left: none;
border-radius: var(--border-radius-lg);
margin: 0 var(--spacing-2);
}
swp-app-layout.menu-collapsed swp-side-menu-action {
justify-content: center;
padding: var(--spacing-3);
}
swp-app-layout.menu-collapsed swp-side-menu-footer {
padding: var(--spacing-3) var(--spacing-2);
}
/* ===========================================
TOOLTIP (Collapsed State)
=========================================== */
.swp-menu-tooltip {
position: fixed;
margin: 0;
padding: 6px var(--spacing-3);
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
font-size: var(--font-size-md);
font-family: var(--font-family);
color: var(--color-text);
white-space: nowrap;
box-shadow: var(--shadow-md);
pointer-events: none;
z-index: var(--z-tooltip);
}

View file

@ -0,0 +1,258 @@
/**
* Stats - Statistics Components
*
* Stat bars, cards, values og trends
*/
/* ===========================================
STATS CONTAINER (Grid/Bar/Row)
=========================================== */
swp-stats-bar,
swp-stats-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: var(--spacing-4);
margin-bottom: var(--spacing-5);
}
swp-stats-row {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: var(--spacing-4);
margin-bottom: var(--spacing-5);
}
/* ===========================================
STAT CARD
=========================================== */
swp-stat-card {
display: flex;
flex-direction: column;
background: var(--color-surface);
border-radius: var(--border-radius-lg);
padding: var(--spacing-4) var(--spacing-5);
border: 1px solid var(--color-border);
}
swp-stat-box {
display: flex;
flex-direction: column;
gap: var(--spacing-1);
padding: var(--spacing-4);
background: var(--color-surface);
border-radius: var(--border-radius);
border: 1px solid var(--color-border);
}
/* ===========================================
STAT VALUE
=========================================== */
swp-stat-value {
display: block;
font-size: 22px;
font-weight: 600;
font-family: var(--font-mono);
color: var(--color-text);
line-height: var(--line-height-tight);
}
/* Larger variant for emphasis */
swp-stat-card swp-stat-value,
swp-stat-box swp-stat-value {
font-size: 22px;
font-weight: 600;
font-family: var(--font-mono);
color: var(--color-text);
}
/* ===========================================
STAT LABEL
=========================================== */
swp-stat-label {
display: block;
font-size: var(--font-size-sm);
color: var(--color-text-secondary);
margin-top: var(--spacing-1);
}
swp-stat-box swp-stat-label {
font-size: 11px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--color-text-secondary);
}
/* ===========================================
STAT SUBTITLE
=========================================== */
swp-stat-subtitle {
display: block;
font-size: 11px;
color: var(--color-text-muted);
margin-top: var(--spacing-1);
}
/* ===========================================
STAT TREND / CHANGE
=========================================== */
swp-stat-trend,
swp-stat-change {
display: inline-flex;
align-items: center;
gap: var(--spacing-1);
font-size: var(--font-size-xs);
margin-top: var(--spacing-2);
}
swp-stat-trend i,
swp-stat-change i {
font-size: 14px;
}
/* Trend Up (positive) */
swp-stat-trend.up,
swp-stat-change.positive {
color: var(--color-green);
}
/* Trend Down (negative) */
swp-stat-trend.down,
swp-stat-change.negative {
color: var(--color-red);
}
/* Neutral trend */
swp-stat-trend.neutral {
color: var(--color-text-secondary);
}
/* ===========================================
COLOR MODIFIERS
=========================================== */
/* Highlight (Primary/Teal) */
swp-stat-card.highlight swp-stat-value,
swp-stat-box.highlight swp-stat-value,
swp-stat-card.teal swp-stat-value {
color: var(--color-teal);
}
/* Success (Green) */
swp-stat-card.success swp-stat-value {
color: var(--color-green);
}
/* Warning (Amber) */
swp-stat-card.warning swp-stat-value,
swp-stat-card.amber swp-stat-value {
color: var(--color-amber);
}
/* Danger (Red) */
swp-stat-card.danger swp-stat-value,
swp-stat-card.negative swp-stat-value,
swp-stat-card.red swp-stat-value {
color: var(--color-red);
}
/* Purple */
swp-stat-card.purple swp-stat-value {
color: var(--color-purple);
}
/* ===========================================
HIGHLIGHT CARD (Filled Background)
=========================================== */
swp-stat-card.highlight.filled {
background: linear-gradient(135deg, var(--color-teal) 0%, #00695c 100%);
color: white;
border-color: transparent;
}
swp-stat-card.highlight.filled swp-stat-value {
color: white;
}
swp-stat-card.highlight.filled swp-stat-label {
color: rgba(255, 255, 255, 0.8);
}
swp-stat-card.highlight.filled swp-stat-change {
color: rgba(255, 255, 255, 0.9);
}
/* ===========================================
QUICK STATS (Compact Variant)
=========================================== */
swp-quick-stats {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: var(--spacing-3);
}
swp-quick-stat {
display: flex;
flex-direction: column;
text-align: center;
padding: var(--spacing-3);
background: var(--color-background);
border-radius: var(--border-radius);
}
swp-quick-stat swp-stat-value {
font-size: 18px;
}
swp-quick-stat swp-stat-label {
font-size: 11px;
margin-top: var(--spacing-1);
}
/* ===========================================
STAT ITEM (Inline Variant)
=========================================== */
swp-stat-item {
display: flex;
flex-direction: column;
gap: 2px;
padding: var(--spacing-2) var(--spacing-3);
background: var(--color-background);
border-radius: var(--border-radius);
}
swp-stat-item swp-stat-value {
font-size: 16px;
font-weight: 600;
}
swp-stat-item swp-stat-value.mono {
font-family: var(--font-mono);
}
swp-stat-item swp-stat-label {
font-size: 11px;
margin-top: 0;
}
/* ===========================================
RESPONSIVE
=========================================== */
@media (max-width: 1200px) {
swp-stats-bar,
swp-stats-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 768px) {
swp-stats-bar,
swp-stats-grid,
swp-stats-row {
grid-template-columns: 1fr;
}
swp-quick-stats {
grid-template-columns: repeat(2, 1fr);
}
}

View file

@ -0,0 +1,180 @@
/**
* Topbar - App Header Bar
*
* Search, notifications og profil-menu
*/
/* ===========================================
TOPBAR CONTAINER
=========================================== */
swp-app-topbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 var(--spacing-5);
background: var(--color-surface);
border-bottom: 1px solid var(--color-border);
position: sticky;
top: 0;
z-index: var(--z-sticky);
}
/* ===========================================
SEARCH
=========================================== */
swp-topbar-search {
display: flex;
align-items: center;
gap: 10px;
padding: var(--spacing-2) var(--spacing-3);
background: var(--color-background);
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
width: 320px;
transition: border-color var(--transition-fast);
}
swp-topbar-search:focus-within {
border-color: var(--color-teal);
}
swp-topbar-search i {
font-size: 18px;
color: var(--color-text-secondary);
flex-shrink: 0;
}
swp-topbar-search input {
flex: 1;
border: none;
outline: none;
background: transparent;
font-size: var(--font-size-md);
font-family: var(--font-family);
color: var(--color-text);
}
swp-topbar-search input::placeholder {
color: var(--color-text-secondary);
}
swp-topbar-search kbd {
font-size: var(--font-size-xs);
font-family: var(--font-mono);
padding: 2px 6px;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: 4px;
color: var(--color-text-secondary);
}
/* ===========================================
ACTIONS
=========================================== */
swp-topbar-actions {
display: flex;
align-items: center;
gap: var(--spacing-2);
}
/* Action Buttons */
swp-topbar-btn {
display: flex;
align-items: center;
justify-content: center;
width: 38px;
height: 38px;
border: none;
background: transparent;
border-radius: var(--border-radius);
cursor: pointer;
transition: background var(--transition-fast);
position: relative;
color: var(--color-text-secondary);
}
swp-topbar-btn:hover {
background: var(--color-background-hover);
}
swp-topbar-btn i {
font-size: 22px;
}
/* Notification Badge */
swp-notification-badge {
position: absolute;
top: 6px;
right: 6px;
min-width: 16px;
height: 16px;
padding: 0 4px;
font-size: 10px;
font-weight: 600;
background: var(--color-red);
color: white;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
}
/* Divider */
swp-topbar-divider {
width: 1px;
height: 24px;
background: var(--color-border);
margin: 0 var(--spacing-2);
}
/* ===========================================
PROFILE TRIGGER
=========================================== */
swp-topbar-profile {
display: flex;
align-items: center;
gap: 10px;
padding: 6px var(--spacing-3) 6px 6px;
background: transparent;
border: 1px solid transparent;
border-radius: var(--border-radius);
cursor: pointer;
transition: all var(--transition-fast);
}
swp-topbar-profile:hover {
background: var(--color-background-hover);
border-color: var(--color-border);
}
swp-profile-avatar {
width: 32px;
height: 32px;
border-radius: 50%;
background: var(--color-teal);
color: white;
font-size: var(--font-size-sm);
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
}
swp-profile-info {
display: flex;
flex-direction: column;
align-items: flex-start;
}
swp-profile-name {
font-size: var(--font-size-md);
font-weight: 500;
color: var(--color-text);
line-height: var(--line-height-tight);
}
swp-profile-role {
font-size: var(--font-size-xs);
color: var(--color-text-secondary);
line-height: var(--line-height-tight);
}