Calendar/wwwroot/poc-indstillinger.html
Janus C. H. Knudsen fac7754d7a Refactors design system documentation and layout
Updates design system documentation with comprehensive component overview
Enhances UI layout across multiple pages with consistent styling and new components
Adds support for charts, pagination, and responsive design elements

Improves overall system documentation and visual consistency
2026-01-07 22:12:25 +01:00

4404 lines
143 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="da">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Indstillinger - KARINA KNUDSEN®</title>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@phosphor-icons/web@2.1.2/src/regular/style.css" />
<style>
/* ==========================================
FONT FACE (Poppins)
========================================== */
@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;
}
/* ==========================================
CSS VARIABLES (Design System)
========================================== */
:root {
--color-surface: #fff;
--color-background: #f5f5f5;
--color-background-hover: #f0f0f0;
--color-background-alt: #fafafa;
--color-border: #e0e0e0;
--color-text: #333;
--color-text-secondary: #666;
--color-teal: #00897b;
--color-blue: #1976d2;
--color-red: #e53935;
--color-amber: #f59e0b;
--color-purple: #8b5cf6;
--color-green: #43a047;
--font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
--font-mono: 'JetBrains Mono', monospace;
}
@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-text: #e0e0e0;
--color-text-secondary: #999;
--color-teal: #26a69a;
--color-blue: #42a5f5;
--color-red: #ef5350;
--color-amber: #ffb74d;
--color-purple: #a78bfa;
--color-green: #66bb6a;
}
}
:root.dark-mode {
--color-surface: #1e1e1e;
--color-background: #121212;
--color-background-hover: #2a2a2a;
--color-background-alt: #1a1a1a;
--color-border: #333;
--color-text: #e0e0e0;
--color-text-secondary: #999;
--color-teal: #26a69a;
--color-blue: #42a5f5;
--color-red: #ef5350;
--color-amber: #ffb74d;
--color-purple: #a78bfa;
--color-green: #66bb6a;
}
/* ==========================================
RESET & BASE
========================================== */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: var(--font-family);
font-size: 14px;
color: var(--color-text);
background: var(--color-background);
line-height: 1.5;
}
/* ==========================================
TOPBAR
========================================== */
swp-topbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 24px;
background: var(--color-surface);
border-bottom: 1px solid var(--color-border);
position: sticky;
top: 0;
z-index: 100;
}
swp-topbar-left {
display: flex;
align-items: center;
gap: 16px;
}
swp-topbar-title {
font-size: 16px;
font-weight: 600;
color: var(--color-text);
}
swp-topbar-actions {
display: flex;
align-items: center;
gap: 12px;
}
/* ==========================================
TAB BAR
========================================== */
swp-tab-bar {
display: flex;
gap: 0;
background: var(--color-surface);
border-bottom: 1px solid var(--color-border);
padding: 0 24px;
position: sticky;
top: 49px;
z-index: 80;
}
swp-tab {
display: flex;
align-items: center;
gap: 8px;
padding: 14px 24px;
font-size: 14px;
font-weight: 500;
color: var(--color-text-secondary);
cursor: pointer;
border-bottom: 2px solid transparent;
margin-bottom: -1px;
transition: all 150ms ease;
}
swp-tab i {
font-size: 18px;
}
swp-tab:hover {
color: var(--color-text);
background: var(--color-background-alt);
}
swp-tab.active {
color: var(--color-teal);
border-bottom-color: var(--color-teal);
}
/* ==========================================
TAB CONTENT
========================================== */
swp-tab-content {
display: none;
padding: 24px;
max-width: 900px;
margin: 0 auto;
}
swp-tab-content.active {
display: block;
}
/* ==========================================
CARDS & SECTIONS
========================================== */
swp-card {
display: block;
background: var(--color-surface);
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
margin-bottom: 20px;
}
swp-card-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
border-bottom: 1px solid var(--color-border);
}
swp-card-title {
display: flex;
align-items: center;
gap: 10px;
font-size: 15px;
font-weight: 600;
color: var(--color-text);
}
swp-card-title i {
font-size: 20px;
color: var(--color-teal);
}
swp-card-content {
display: block;
padding: 20px;
}
/* ==========================================
EDIT SECTION (from poc-employee.html)
========================================== */
swp-edit-section {
display: flex;
flex-direction: column;
gap: 12px;
}
swp-edit-row {
display: grid;
grid-template-columns: 140px 1fr;
align-items: center;
gap: 12px;
}
swp-edit-row.wide-label {
grid-template-columns: 180px 1fr;
}
swp-edit-label {
font-size: 13px;
color: var(--color-text-secondary);
}
swp-edit-label .optional {
font-weight: 400;
color: var(--color-text-secondary);
opacity: 0.7;
}
swp-edit-value {
font-size: 14px;
padding: 8px 12px;
border-radius: 4px;
background: var(--color-background-alt);
border: 1px solid transparent;
transition: all 150ms ease;
cursor: text;
}
swp-edit-value:hover {
background: var(--color-background);
}
swp-edit-value:focus {
outline: none;
background: var(--color-surface);
border-color: var(--color-teal);
}
swp-edit-value.mono {
font-family: var(--font-mono);
}
/* Edit Select */
swp-edit-select {
display: block;
}
swp-edit-select select {
width: 100%;
font-size: 14px;
font-family: inherit;
padding: 8px 12px;
border-radius: 4px;
background: var(--color-background-alt);
border: 1px solid transparent;
cursor: pointer;
transition: all 150ms ease;
color: var(--color-text);
}
swp-edit-select select:hover {
background: var(--color-background);
}
swp-edit-select select:focus {
outline: none;
background: var(--color-surface);
border-color: var(--color-teal);
}
/* Textarea */
swp-edit-textarea {
display: block;
width: 100%;
padding: 10px 12px;
font-size: 14px;
font-family: var(--font-family);
color: var(--color-text);
background: var(--color-background-alt);
border: 1px solid transparent;
border-radius: 4px;
resize: vertical;
min-height: 80px;
transition: all 150ms ease;
}
swp-edit-textarea:hover {
background: var(--color-background);
}
swp-edit-textarea:focus {
outline: none;
background: var(--color-surface);
border-color: var(--color-teal);
}
/* ==========================================
TOGGLE SLIDER (Ja/Nej - from poc-employee.html)
========================================== */
swp-toggle-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 0;
border-bottom: 1px solid var(--color-border);
}
swp-toggle-row:last-child {
border-bottom: none;
}
swp-toggle-info {
display: flex;
flex-direction: column;
gap: 2px;
}
swp-toggle-label {
font-size: 14px;
font-weight: 500;
color: var(--color-text);
}
swp-toggle-desc {
font-size: 12px;
color: var(--color-text-secondary);
}
swp-toggle-slider {
display: inline-flex;
width: fit-content;
background: var(--color-background);
border-radius: 6px;
border: 1px solid var(--color-border);
overflow: hidden;
position: relative;
}
swp-toggle-slider::before {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: calc(50% - 4px);
height: calc(100% - 4px);
background: color-mix(in srgb, var(--color-green) 18%, white);
border-radius: 4px;
transition: transform 200ms ease, background 200ms ease;
}
swp-toggle-slider[data-value="no"]::before {
transform: translateX(100%);
background: color-mix(in srgb, var(--color-red) 18%, white);
}
swp-toggle-option {
position: relative;
z-index: 1;
padding: 5px 16px;
font-size: 12px;
font-weight: 500;
color: var(--color-text-secondary);
cursor: pointer;
transition: color 150ms ease;
user-select: none;
}
swp-toggle-slider[data-value="yes"] swp-toggle-option:first-child {
color: var(--color-green);
font-weight: 600;
}
swp-toggle-slider[data-value="no"] swp-toggle-option:last-child {
color: var(--color-red);
font-weight: 600;
}
/* ==========================================
HOURS TABLE
========================================== */
swp-hours-table {
display: flex;
flex-direction: column;
}
swp-hours-row {
display: grid;
grid-template-columns: 100px 80px 1fr;
gap: 16px;
align-items: center;
padding: 12px 0;
border-bottom: 1px solid var(--color-border);
}
swp-hours-row:last-child {
border-bottom: none;
}
swp-hours-day {
font-size: 14px;
font-weight: 500;
color: var(--color-text);
}
swp-hours-time {
display: flex;
align-items: center;
gap: 8px;
}
swp-hours-time span {
font-size: 13px;
color: var(--color-text-secondary);
}
swp-hours-time input[type="time"] {
width: 100px;
padding: 6px 10px;
font-size: 13px;
font-family: var(--font-mono);
background: var(--color-background-alt);
border: 1px solid transparent;
border-radius: 4px;
color: var(--color-text);
transition: all 150ms ease;
}
swp-hours-time input[type="time"]:hover {
background: var(--color-background);
}
swp-hours-time input[type="time"]:focus {
outline: none;
background: var(--color-surface);
border-color: var(--color-teal);
}
swp-hours-closed {
font-size: 13px;
color: var(--color-text-secondary);
font-style: italic;
}
/* ==========================================
URL FIELD
========================================== */
swp-url-field {
display: flex;
align-items: stretch;
background: var(--color-background-alt);
border: 1px solid var(--color-border);
border-radius: 6px;
overflow: hidden;
}
swp-url-field input {
flex: 1;
padding: 10px 14px;
font-size: 14px;
font-family: var(--font-mono);
color: var(--color-text);
background: transparent;
border: none;
outline: none;
}
swp-url-copy {
display: flex;
align-items: center;
justify-content: center;
padding: 0 14px;
background: var(--color-surface);
border-left: 1px solid var(--color-border);
cursor: pointer;
color: var(--color-text-secondary);
transition: all 150ms ease;
}
swp-url-copy:hover {
background: var(--color-background-hover);
color: var(--color-teal);
}
swp-url-copy i {
font-size: 18px;
}
/* ==========================================
INFO BOX
========================================== */
swp-info-box {
display: flex;
align-items: flex-start;
gap: 12px;
padding: 14px 16px;
background: color-mix(in srgb, var(--color-blue) 8%, transparent);
border: 1px solid color-mix(in srgb, var(--color-blue) 20%, transparent);
border-radius: 6px;
margin-bottom: 20px;
}
swp-info-box i {
font-size: 20px;
color: var(--color-blue);
flex-shrink: 0;
}
swp-info-box p {
font-size: 13px;
color: var(--color-text);
margin: 0;
}
/* ==========================================
BUTTONS
========================================== */
swp-btn {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 10px 18px;
font-size: 13px;
font-weight: 500;
font-family: var(--font-family);
border-radius: 6px;
cursor: pointer;
transition: all 150ms ease;
border: none;
}
swp-btn i {
font-size: 18px;
}
swp-btn.primary {
background: var(--color-teal);
color: white;
}
swp-btn.primary:hover {
background: #00796b;
}
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);
}
/* ==========================================
NOTIFICATION ITEMS
========================================== */
swp-notification-list {
display: flex;
flex-direction: column;
gap: 0;
}
swp-notification-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 0;
border-bottom: 1px solid var(--color-border);
}
swp-notification-item:last-child {
border-bottom: none;
}
swp-notification-main {
display: flex;
align-items: center;
gap: 16px;
flex: 1;
}
swp-notification-info {
display: flex;
flex-direction: column;
gap: 2px;
flex: 1;
}
swp-notification-title {
display: flex;
align-items: center;
gap: 10px;
font-size: 14px;
font-weight: 500;
color: var(--color-text);
}
swp-notification-price {
font-size: 12px;
color: var(--color-text-secondary);
font-weight: 400;
}
swp-notification-price.free {
color: var(--color-green);
}
swp-notification-price.premium {
color: var(--color-purple);
}
swp-notification-desc {
font-size: 12px;
color: var(--color-text-secondary);
}
swp-notification-actions {
display: flex;
align-items: center;
gap: 12px;
}
swp-edit-link {
font-size: 13px;
color: var(--color-teal);
cursor: pointer;
transition: color 150ms ease;
}
swp-edit-link:hover {
color: #00796b;
text-decoration: underline;
}
swp-section-intro {
font-size: 13px;
color: var(--color-text-secondary);
margin-bottom: 16px;
}
swp-time-setting {
display: flex;
align-items: center;
gap: 12px;
padding: 16px 0;
border-bottom: 1px solid var(--color-border);
}
swp-time-setting:last-child {
border-bottom: none;
}
swp-time-setting-label {
font-size: 14px;
color: var(--color-text);
min-width: 200px;
}
swp-time-range {
display: flex;
align-items: center;
gap: 10px;
}
swp-time-range span {
font-size: 13px;
color: var(--color-text-secondary);
}
swp-time-range input[type="time"] {
width: 100px;
padding: 6px 10px;
font-size: 13px;
font-family: var(--font-mono);
background: var(--color-background-alt);
border: 1px solid transparent;
border-radius: 4px;
color: var(--color-text);
}
swp-time-range input[type="time"]:focus {
outline: none;
background: var(--color-surface);
border-color: var(--color-teal);
}
/* Section divider */
swp-section-divider {
display: block;
height: 1px;
background: var(--color-border);
margin: 20px 0;
}
/* ==========================================
CLOSED DAYS LIST
========================================== */
swp-closed-days-list {
display: flex;
flex-direction: column;
gap: 0;
}
swp-closed-day-item {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 0;
border-bottom: 1px solid var(--color-border);
}
swp-closed-day-item:last-child {
border-bottom: none;
}
swp-closed-day-info {
display: flex;
flex-direction: column;
gap: 2px;
flex: 1;
}
swp-closed-day-date {
font-size: 13px;
font-weight: 500;
color: var(--color-text);
}
swp-closed-day-name {
font-size: 12px;
color: var(--color-text-secondary);
}
swp-closed-day-badge {
display: inline-flex;
align-items: center;
padding: 4px 10px;
font-size: 11px;
font-weight: 500;
border-radius: 4px;
flex-shrink: 0;
}
swp-closed-day-badge.holiday {
background: color-mix(in srgb, var(--color-purple) 15%, transparent);
color: var(--color-purple);
}
swp-closed-day-badge.custom {
background: color-mix(in srgb, var(--color-amber) 15%, transparent);
color: var(--color-amber);
}
swp-closed-day-item swp-icon-btn {
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border: none;
background: transparent;
border-radius: 6px;
cursor: pointer;
color: var(--color-text-secondary);
transition: all 150ms ease;
flex-shrink: 0;
}
swp-closed-day-item swp-icon-btn i {
font-size: 16px;
}
swp-closed-day-item swp-icon-btn.edit:hover {
background: color-mix(in srgb, var(--color-teal) 15%, transparent);
color: var(--color-teal);
}
swp-closed-day-item swp-icon-btn.delete:hover {
background: color-mix(in srgb, var(--color-red) 15%, transparent);
color: var(--color-red);
}
/* ==========================================
TWO COLUMN GRID
========================================== */
swp-two-column-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
align-items: start;
}
@media (max-width: 900px) {
swp-two-column-grid {
grid-template-columns: 1fr;
}
}
/* Card note */
swp-card-note {
display: block;
font-size: 12px;
color: var(--color-text-secondary);
margin-top: 16px;
padding-top: 12px;
border-top: 1px solid var(--color-border);
}
/* ==========================================
DRAWER
========================================== */
swp-drawer-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.4);
z-index: 200;
opacity: 0;
visibility: hidden;
transition: opacity 200ms ease, visibility 200ms ease;
}
swp-drawer-overlay.open {
opacity: 1;
visibility: visible;
}
swp-drawer {
position: fixed;
top: 0;
right: 0;
bottom: 0;
width: 480px;
max-width: 100%;
background: var(--color-surface);
box-shadow: -4px 0 20px rgba(0, 0, 0, 0.15);
z-index: 201;
display: flex;
flex-direction: column;
transform: translateX(100%);
transition: transform 250ms ease, width 250ms ease;
}
swp-drawer.open {
transform: translateX(0);
}
swp-drawer.wide {
width: calc(100% - 420px);
min-width: 600px;
}
@media (max-width: 1100px) {
swp-drawer.wide {
width: 100%;
min-width: unset;
}
}
swp-drawer-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
border-bottom: 1px solid var(--color-border);
flex-shrink: 0;
}
swp-drawer-title {
display: flex;
flex-direction: column;
gap: 2px;
}
swp-drawer-title h3 {
font-size: 16px;
font-weight: 600;
color: var(--color-text);
margin: 0;
}
swp-drawer-title span {
font-size: 12px;
color: var(--color-text-secondary);
}
swp-drawer-close {
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
border: none;
background: transparent;
border-radius: 6px;
cursor: pointer;
color: var(--color-text-secondary);
transition: all 150ms ease;
}
swp-drawer-close:hover {
background: var(--color-background-hover);
color: var(--color-text);
}
swp-drawer-close i {
font-size: 22px;
}
swp-drawer-body {
flex: 1;
overflow-y: auto;
padding: 20px;
}
swp-drawer-footer {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 12px;
padding: 16px 20px;
border-top: 1px solid var(--color-border);
background: var(--color-background-alt);
flex-shrink: 0;
}
/* Message editor */
swp-message-section {
display: block;
margin-bottom: 24px;
}
swp-message-section:last-child {
margin-bottom: 0;
}
swp-message-section-title {
display: block;
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--color-text-secondary);
margin-bottom: 12px;
}
swp-message-editor {
display: block;
width: 100%;
min-height: 120px;
padding: 14px;
font-size: 14px;
font-family: var(--font-family);
line-height: 1.6;
color: var(--color-text);
background: var(--color-background-alt);
border: 1px solid var(--color-border);
border-radius: 6px;
resize: vertical;
transition: all 150ms ease;
}
swp-message-editor:focus {
outline: none;
background: var(--color-surface);
border-color: var(--color-teal);
}
/* Variables */
swp-variables-grid {
display: flex;
flex-wrap: wrap;
gap: 8px;
position: relative;
}
/* Onboarding popover */
#variablesHint[popover] {
margin: 0;
border: none;
padding: 0;
background: transparent;
overflow: visible;
inset: unset;
}
#variablesHint[popover]:popover-open {
display: block;
}
swp-onboarding-hint {
display: flex;
align-items: center;
gap: 8px;
background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #a855f7 100%);
color: white;
padding: 12px 16px;
border-radius: 10px;
font-size: 13px;
font-weight: 500;
line-height: 1.4;
white-space: nowrap;
box-shadow: 0 4px 20px rgba(99, 102, 241, 0.4);
}
swp-onboarding-hint i.ph-lightbulb {
font-size: 18px;
}
swp-onboarding-hint::after {
content: '';
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
border: 8px solid transparent;
border-top-color: #8b5cf6;
}
swp-onboarding-hint swp-hint-close {
display: inline-flex;
align-items: center;
justify-content: center;
width: 18px;
height: 18px;
margin-left: 4px;
background: rgba(255, 255, 255, 0.2);
border-radius: 50%;
cursor: pointer;
font-size: 12px;
transition: background 150ms ease;
}
swp-onboarding-hint swp-hint-close:hover {
background: rgba(255, 255, 255, 0.3);
}
swp-variable-tag {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 6px 10px;
font-size: 12px;
font-family: var(--font-mono);
background: var(--color-background);
border: 1px solid var(--color-border);
border-radius: 4px;
cursor: pointer;
transition: all 150ms ease;
color: var(--color-text-secondary);
}
swp-variable-tag:hover {
border-color: var(--color-teal);
color: var(--color-teal);
cursor: pointer;
}
swp-message-preview .highlight.active {
background: color-mix(in srgb, var(--color-teal) 35%, transparent);
box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-teal) 20%, transparent);
}
swp-variable-tag i {
font-size: 14px;
}
/* Preview */
swp-message-preview {
display: block;
padding: 16px;
background: var(--color-background);
border: 1px solid var(--color-border);
border-radius: 6px;
font-size: 14px;
line-height: 1.6;
color: var(--color-text);
}
swp-message-preview .highlight {
padding: 1px 4px;
border-radius: 3px;
transition: all 150ms ease;
}
swp-preview-meta {
display: flex;
align-items: center;
gap: 16px;
margin-top: 12px;
padding-top: 12px;
border-top: 1px solid var(--color-border);
font-size: 12px;
color: var(--color-text-secondary);
}
swp-preview-meta span {
display: flex;
align-items: center;
gap: 6px;
}
swp-preview-meta i {
font-size: 14px;
}
/* ==========================================
EMAIL TEMPLATE EDITOR
========================================== */
swp-email-editor-layout {
display: grid;
grid-template-columns: 280px 1fr;
gap: 24px;
height: 100%;
}
@media (max-width: 900px) {
swp-email-editor-layout {
grid-template-columns: 1fr;
}
}
swp-email-sidebar {
display: flex;
flex-direction: column;
gap: 20px;
}
swp-email-preview-container {
flex: 1;
background: var(--color-border);
border-radius: 8px;
padding: 24px;
overflow-y: auto;
display: flex;
justify-content: center;
align-items: flex-start;
}
/* Email preview - uses fixed light colors since emails are light-themed */
swp-email-preview {
width: 100%;
max-width: 520px;
background: #ffffff;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
overflow: hidden;
color: #333;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
swp-email-header {
display: flex;
flex-direction: column;
align-items: center;
padding: 28px 24px;
background: linear-gradient(135deg, #00897b 0%, #00695c 100%);
color: #ffffff;
text-align: center;
}
swp-email-logo {
width: 56px;
height: 56px;
background: #ffffff;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 14px;
font-size: 24px;
color: #00897b;
font-weight: 700;
}
swp-email-header h2 {
font-size: 18px;
font-weight: 600;
margin: 0 0 4px 0;
color: #ffffff;
}
swp-email-header p {
font-size: 12px;
opacity: 0.85;
margin: 0;
color: #ffffff;
}
swp-email-body {
display: block;
padding: 28px 32px;
background: #ffffff;
}
swp-email-greeting {
font-size: 15px;
font-weight: 500;
margin-bottom: 12px;
display: block;
color: #333333;
}
swp-email-text {
font-size: 14px;
line-height: 1.6;
color: #555555;
display: block;
margin-bottom: 20px;
}
swp-email-appointment-card {
display: block;
background: #f5f5f5;
border-radius: 0;
padding: 16px 20px;
margin-bottom: 24px;
border-left: 4px solid #00897b;
}
swp-email-appointment-row {
display: flex;
align-items: center;
gap: 12px;
padding: 6px 0;
}
swp-email-appointment-row:first-child {
padding-top: 0;
}
swp-email-appointment-row:last-child {
padding-bottom: 0;
}
swp-email-appointment-row i {
font-size: 18px;
color: #00897b;
width: 20px;
flex-shrink: 0;
}
swp-email-appointment-row span {
font-size: 14px;
color: #333333;
}
swp-email-appointment-row strong {
font-weight: 600;
}
swp-email-button {
display: inline-block;
padding: 12px 24px;
background: #00897b;
color: #ffffff;
font-size: 14px;
font-weight: 600;
text-decoration: none;
border-radius: 6px;
text-align: center;
}
swp-email-button-container {
text-align: center;
margin: 20px 0 8px 0;
display: block;
}
swp-email-footer {
display: block;
padding: 20px 32px;
background: #f5f5f5;
text-align: center;
border-top: none;
}
swp-email-footer-logo {
font-size: 14px;
font-weight: 600;
color: #333333;
margin-bottom: 8px;
display: block;
}
swp-email-footer p {
font-size: 12px;
color: #888888;
margin: 4px 0;
line-height: 1.5;
}
swp-email-footer a {
color: #00897b;
text-decoration: none;
}
/* Email sidebar - uses swp-edit-* pattern */
swp-email-sidebar swp-edit-row {
grid-template-columns: 1fr;
gap: 6px;
}
swp-email-sidebar swp-edit-label {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
}
/* Color picker */
swp-color-picker-row {
display: flex;
align-items: center;
gap: 10px;
}
swp-color-picker-row input[type="color"] {
width: 40px;
height: 40px;
border: none;
border-radius: 6px;
cursor: pointer;
padding: 0;
background: none;
}
swp-color-picker-row input[type="color"]::-webkit-color-swatch-wrapper {
padding: 0;
}
swp-color-picker-row input[type="color"]::-webkit-color-swatch {
border: 2px solid var(--color-border);
border-radius: 6px;
}
swp-color-picker-row span {
font-size: 13px;
font-family: var(--font-mono);
color: var(--color-text-secondary);
}
/* Highlight in email preview - only on hover */
swp-email-preview .editable {
padding: 1px 3px;
border-radius: 2px;
transition: all 150ms ease;
}
swp-email-preview .editable.active {
background: rgba(0, 137, 123, 0.35);
box-shadow: 0 0 0 2px rgba(0, 137, 123, 0.2);
}
/* ==========================================
MODULES TAB STYLES
========================================== */
swp-modules-section {
display: block;
margin-bottom: 32px;
}
swp-modules-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 16px;
}
swp-modules-title {
display: flex;
align-items: center;
gap: 10px;
font-size: 15px;
font-weight: 600;
color: var(--color-text);
}
swp-modules-title i {
font-size: 20px;
color: var(--color-teal);
}
swp-modules-badge {
display: inline-flex;
align-items: center;
padding: 4px 10px;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
border-radius: 20px;
background: color-mix(in srgb, var(--color-purple) 15%, transparent);
color: var(--color-purple);
}
swp-modules-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
}
@media (max-width: 768px) {
swp-modules-grid {
grid-template-columns: 1fr;
}
}
swp-module-card {
display: block;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: 10px;
overflow: hidden;
transition: all 150ms ease;
}
swp-module-card.full-width {
grid-column: 1 / -1;
}
swp-module-card:hover {
border-color: var(--color-teal);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
swp-module-header {
display: flex;
align-items: center;
gap: 16px;
padding: 20px;
}
swp-module-icon {
width: 48px;
height: 48px;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
swp-module-icon i {
font-size: 24px;
}
swp-module-icon.teal {
background: color-mix(in srgb, var(--color-teal) 15%, transparent);
color: var(--color-teal);
}
swp-module-icon.purple {
background: color-mix(in srgb, var(--color-purple) 15%, transparent);
color: var(--color-purple);
}
swp-module-icon.blue {
background: color-mix(in srgb, var(--color-blue) 15%, transparent);
color: var(--color-blue);
}
swp-module-icon.amber {
background: color-mix(in srgb, var(--color-amber) 15%, transparent);
color: var(--color-amber);
}
swp-module-icon.green {
background: color-mix(in srgb, var(--color-green) 15%, transparent);
color: var(--color-green);
}
swp-module-info {
flex: 1;
min-width: 0;
}
swp-module-title {
display: block;
font-size: 15px;
font-weight: 600;
color: var(--color-text);
margin-bottom: 4px;
}
swp-module-desc {
display: block;
font-size: 13px;
color: var(--color-text-secondary);
line-height: 1.4;
}
swp-module-toggle {
flex-shrink: 0;
}
swp-module-footer {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 20px;
background: var(--color-background-alt);
border-top: 1px solid var(--color-border);
}
swp-module-tags {
display: flex;
align-items: center;
gap: 8px;
}
swp-module-tag {
display: inline-flex;
align-items: center;
padding: 4px 10px;
font-size: 12px;
font-weight: 500;
border-radius: 4px;
background: var(--color-background);
color: var(--color-text-secondary);
}
swp-module-tag.included {
background: color-mix(in srgb, var(--color-green) 15%, transparent);
color: var(--color-green);
}
swp-module-tag.price {
background: color-mix(in srgb, var(--color-blue) 15%, transparent);
color: var(--color-blue);
}
swp-module-tag.new {
background: color-mix(in srgb, var(--color-purple) 15%, transparent);
color: var(--color-purple);
}
swp-module-tag.coming {
background: color-mix(in srgb, var(--color-amber) 15%, transparent);
color: var(--color-amber);
}
/* Featured module card */
swp-module-card.featured {
border: 2px solid var(--color-green);
background: linear-gradient(135deg, color-mix(in srgb, var(--color-green) 3%, var(--color-surface)) 0%, var(--color-surface) 100%);
}
swp-module-card.featured:hover {
border-color: var(--color-green);
box-shadow: 0 4px 16px rgba(67, 160, 71, 0.15);
}
swp-module-features {
display: flex;
flex-wrap: wrap;
gap: 8px 16px;
padding: 0 20px 16px;
}
swp-module-feature {
display: flex;
align-items: center;
gap: 6px;
font-size: 13px;
color: var(--color-text-secondary);
}
swp-module-feature i {
font-size: 16px;
color: var(--color-green);
}
swp-module-stats {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 12px;
padding: 16px 20px;
background: color-mix(in srgb, var(--color-green) 6%, transparent);
border-top: 1px solid color-mix(in srgb, var(--color-green) 20%, transparent);
border-bottom: 1px solid color-mix(in srgb, var(--color-green) 20%, transparent);
}
swp-module-stat {
text-align: center;
}
swp-module-stat-value {
display: block;
font-size: 20px;
font-weight: 700;
font-family: var(--font-mono);
color: var(--color-green);
}
swp-module-stat-label {
display: block;
font-size: 11px;
color: var(--color-text-secondary);
margin-top: 2px;
}
/* Purple featured variant */
swp-module-card.featured.purple {
border-color: var(--color-purple);
background: linear-gradient(135deg, color-mix(in srgb, var(--color-purple) 3%, var(--color-surface)) 0%, var(--color-surface) 100%);
}
swp-module-card.featured.purple:hover {
border-color: var(--color-purple);
box-shadow: 0 4px 16px rgba(139, 92, 246, 0.15);
}
swp-module-feature.purple i {
color: var(--color-purple);
}
swp-module-stats.purple {
background: color-mix(in srgb, var(--color-purple) 6%, transparent);
border-top-color: color-mix(in srgb, var(--color-purple) 20%, transparent);
border-bottom-color: color-mix(in srgb, var(--color-purple) 20%, transparent);
}
swp-module-stats.purple swp-module-stat-value {
color: var(--color-purple);
}
swp-btn.primary.purple {
background: var(--color-purple);
}
swp-btn.primary.purple:hover {
background: color-mix(in srgb, var(--color-purple) 85%, black);
}
/* ==========================================
TRACKING TAB
========================================== */
swp-tab-content[data-tab="tracking"] {
display: none;
}
swp-tab-content[data-tab="tracking"].active {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
}
.tracking-card {
margin-bottom: 0;
}
.tracking-card.full-width,
.code-preview-card {
grid-column: 1 / -1;
}
.tracking-card swp-card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.tracking-card[data-tracker] swp-card-content {
transition: opacity 200ms ease, max-height 300ms ease;
}
.tracking-card[data-tracker].disabled swp-card-content {
opacity: 0.5;
pointer-events: none;
}
swp-tracking-hint {
display: flex;
align-items: center;
gap: 8px;
margin-top: 12px;
padding: 10px 12px;
background: color-mix(in srgb, var(--color-blue) 8%, transparent);
border-radius: 6px;
font-size: 12px;
color: var(--color-text-secondary);
}
swp-tracking-hint i {
font-size: 16px;
color: var(--color-blue);
}
swp-tracking-hint.privacy {
background: color-mix(in srgb, var(--color-green) 8%, transparent);
}
swp-tracking-hint.privacy i {
color: var(--color-green);
}
swp-script-section {
display: flex;
flex-direction: column;
gap: 8px;
margin-bottom: 16px;
}
swp-script-section:last-child {
margin-bottom: 0;
}
swp-script-label {
display: flex;
align-items: center;
gap: 8px;
font-size: 13px;
font-weight: 500;
color: var(--color-text);
}
swp-script-label i {
font-size: 16px;
color: var(--color-text-secondary);
}
.script-textarea {
width: 100%;
min-height: 100px;
padding: 12px;
font-family: var(--font-mono);
font-size: 12px;
line-height: 1.5;
color: var(--color-text);
background: var(--color-background);
border: 1px solid var(--color-border);
border-radius: 6px;
resize: vertical;
}
.script-textarea::placeholder {
color: var(--color-text-secondary);
}
.script-textarea:focus {
outline: none;
border-color: var(--color-teal);
}
.code-preview-card {
margin-top: 24px;
border: 2px dashed var(--color-teal);
background: color-mix(in srgb, var(--color-teal) 3%, var(--color-surface));
}
.code-preview-card swp-card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.code-preview-card swp-card-title {
color: var(--color-teal);
}
swp-code-info {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 12px;
font-size: 12px;
color: var(--color-text-secondary);
}
swp-code-info i {
font-size: 16px;
color: var(--color-teal);
}
.code-preview {
margin: 0;
padding: 16px;
background: var(--color-background);
border: 1px solid var(--color-border);
border-radius: 6px;
overflow-x: auto;
max-height: 400px;
overflow-y: auto;
}
.code-preview code {
font-family: var(--font-mono);
font-size: 11px;
line-height: 1.6;
color: var(--color-text);
white-space: pre;
}
.code-preview .comment {
color: var(--color-green);
}
.code-preview .tag {
color: var(--color-blue);
}
.code-preview .attr {
color: var(--color-purple);
}
.code-preview .string {
color: var(--color-teal);
}
</style>
</head>
<body>
<!-- Topbar -->
<swp-topbar>
<swp-topbar-left>
<swp-topbar-title>Indstillinger</swp-topbar-title>
</swp-topbar-left>
<swp-topbar-actions>
<swp-btn class="primary" id="saveBtn">
<i class="ph ph-check"></i>
Gem alle ændringer
</swp-btn>
</swp-topbar-actions>
</swp-topbar>
<!-- Tab Bar -->
<swp-tab-bar>
<swp-tab class="active" data-tab="general">
<i class="ph ph-buildings"></i>
Virksomhed
</swp-tab>
<swp-tab data-tab="hours">
<i class="ph ph-clock"></i>
Åbningstider
</swp-tab>
<swp-tab data-tab="calendar">
<i class="ph ph-calendar"></i>
Kalender
</swp-tab>
<swp-tab data-tab="booking">
<i class="ph ph-globe"></i>
Online Booking
</swp-tab>
<swp-tab data-tab="billing">
<i class="ph ph-receipt"></i>
Faktura & Kvittering
</swp-tab>
<swp-tab data-tab="reminders">
<i class="ph ph-bell"></i>
Påmindelser
</swp-tab>
<swp-tab data-tab="payments">
<i class="ph ph-credit-card"></i>
Betalinger
</swp-tab>
<swp-tab data-tab="modules">
<i class="ph ph-puzzle-piece"></i>
Moduler
</swp-tab>
<swp-tab data-tab="tracking">
<i class="ph ph-chart-line-up"></i>
Tracking
</swp-tab>
</swp-tab-bar>
<!-- ==========================================
TAB: VIRKSOMHED
========================================== -->
<swp-tab-content class="active" data-tab="general">
<swp-card>
<swp-card-header>
<swp-card-title>
<i class="ph ph-identification-card"></i>
Grundlæggende oplysninger
</swp-card-title>
</swp-card-header>
<swp-card-content>
<swp-edit-section>
<swp-edit-row>
<swp-edit-label>Virksomhedsnavn</swp-edit-label>
<swp-edit-value contenteditable="true">KARINA KNUDSEN®</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>CVR-nummer</swp-edit-label>
<swp-edit-value contenteditable="true" class="mono">12345678</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Adresse</swp-edit-label>
<swp-edit-value contenteditable="true">Hovedgaden 123</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Postnummer</swp-edit-label>
<swp-edit-value contenteditable="true" class="mono">2100</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>By</swp-edit-label>
<swp-edit-value contenteditable="true">København Ø</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Telefon</swp-edit-label>
<swp-edit-value contenteditable="true" class="mono">70 20 30 40</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Email</swp-edit-label>
<swp-edit-value contenteditable="true">info@salonbeauty.dk</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Website <span class="optional">(valgfri)</span></swp-edit-label>
<swp-edit-value contenteditable="true">https://salonbeauty.dk</swp-edit-value>
</swp-edit-row>
</swp-edit-section>
</swp-card-content>
</swp-card>
</swp-tab-content>
<!-- ==========================================
TAB: ÅBNINGSTIDER
========================================== -->
<swp-tab-content data-tab="hours">
<swp-card>
<swp-card-header>
<swp-card-title>
<i class="ph ph-clock"></i>
Åbningstider
</swp-card-title>
</swp-card-header>
<swp-card-content>
<swp-hours-table>
<swp-hours-row>
<swp-hours-day>Mandag</swp-hours-day>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
<swp-hours-time>
<input type="time" value="09:00">
<span>til</span>
<input type="time" value="18:00">
</swp-hours-time>
</swp-hours-row>
<swp-hours-row>
<swp-hours-day>Tirsdag</swp-hours-day>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
<swp-hours-time>
<input type="time" value="09:00">
<span>til</span>
<input type="time" value="18:00">
</swp-hours-time>
</swp-hours-row>
<swp-hours-row>
<swp-hours-day>Onsdag</swp-hours-day>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
<swp-hours-time>
<input type="time" value="09:00">
<span>til</span>
<input type="time" value="18:00">
</swp-hours-time>
</swp-hours-row>
<swp-hours-row>
<swp-hours-day>Torsdag</swp-hours-day>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
<swp-hours-time>
<input type="time" value="09:00">
<span>til</span>
<input type="time" value="20:00">
</swp-hours-time>
</swp-hours-row>
<swp-hours-row>
<swp-hours-day>Fredag</swp-hours-day>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
<swp-hours-time>
<input type="time" value="09:00">
<span>til</span>
<input type="time" value="17:00">
</swp-hours-time>
</swp-hours-row>
<swp-hours-row>
<swp-hours-day>Lørdag</swp-hours-day>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
<swp-hours-time>
<input type="time" value="10:00">
<span>til</span>
<input type="time" value="14:00">
</swp-hours-time>
</swp-hours-row>
<swp-hours-row>
<swp-hours-day>Søndag</swp-hours-day>
<swp-toggle-slider data-value="no">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
<swp-hours-closed>Lukket</swp-hours-closed>
</swp-hours-row>
</swp-hours-table>
</swp-card-content>
</swp-card>
</swp-tab-content>
<!-- ==========================================
TAB: KALENDER
========================================== -->
<swp-tab-content data-tab="calendar">
<swp-card>
<swp-card-header>
<swp-card-title>
<i class="ph ph-calendar-blank"></i>
Kalenderindstillinger
</swp-card-title>
</swp-card-header>
<swp-card-content>
<swp-edit-section>
<swp-edit-row>
<swp-edit-label>Standard visning</swp-edit-label>
<swp-edit-select>
<select>
<option value="day">Dag</option>
<option value="week" selected>Uge</option>
<option value="month">Måned</option>
</select>
</swp-edit-select>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Første dag i ugen</swp-edit-label>
<swp-edit-select>
<select>
<option value="monday" selected>Mandag</option>
<option value="sunday">Søndag</option>
</select>
</swp-edit-select>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Tidsinterval</swp-edit-label>
<swp-edit-select>
<select>
<option value="15" selected>15 minutter</option>
<option value="30">30 minutter</option>
<option value="60">60 minutter</option>
</select>
</swp-edit-select>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Vis weekender</swp-edit-label>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Arbejdstid fra</swp-edit-label>
<swp-edit-select>
<select>
<option value="06:00">06:00</option>
<option value="07:00">07:00</option>
<option value="08:00" selected>08:00</option>
<option value="09:00">09:00</option>
<option value="10:00">10:00</option>
</select>
</swp-edit-select>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Arbejdstid til</swp-edit-label>
<swp-edit-select>
<select>
<option value="17:00">17:00</option>
<option value="18:00">18:00</option>
<option value="19:00">19:00</option>
<option value="20:00" selected>20:00</option>
<option value="21:00">21:00</option>
<option value="22:00">22:00</option>
</select>
</swp-edit-select>
</swp-edit-row>
</swp-edit-section>
</swp-card-content>
</swp-card>
<swp-card>
<swp-card-header>
<swp-card-title>
<i class="ph ph-calendar-x"></i>
Helligdage & lukkedage
</swp-card-title>
<swp-btn class="small secondary" id="addClosedDayBtn">
<i class="ph ph-plus"></i>
Tilføj lukkedag
</swp-btn>
</swp-card-header>
<swp-card-content>
<swp-toggle-row>
<swp-toggle-info>
<swp-toggle-label>Luk automatisk på helligdage</swp-toggle-label>
<swp-toggle-desc>Salonen lukkes automatisk på danske helligdage</swp-toggle-desc>
</swp-toggle-info>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-toggle-row>
<swp-section-divider></swp-section-divider>
<swp-closed-days-list>
<swp-closed-day-item>
<swp-closed-day-info>
<swp-closed-day-date>5. april 2026</swp-closed-day-date>
<swp-closed-day-name>Påskedag</swp-closed-day-name>
</swp-closed-day-info>
<swp-closed-day-badge class="holiday">Helligdag</swp-closed-day-badge>
<swp-icon-btn class="edit" title="Rediger åbningstid">
<i class="ph ph-pencil-simple"></i>
</swp-icon-btn>
</swp-closed-day-item>
<swp-closed-day-item>
<swp-closed-day-info>
<swp-closed-day-date>1. maj 2026</swp-closed-day-date>
<swp-closed-day-name>Store bededag</swp-closed-day-name>
</swp-closed-day-info>
<swp-closed-day-badge class="holiday">Helligdag</swp-closed-day-badge>
<swp-icon-btn class="edit" title="Rediger åbningstid">
<i class="ph ph-pencil-simple"></i>
</swp-icon-btn>
</swp-closed-day-item>
<swp-closed-day-item>
<swp-closed-day-info>
<swp-closed-day-date>14. maj 2026</swp-closed-day-date>
<swp-closed-day-name>Kristi Himmelfart</swp-closed-day-name>
</swp-closed-day-info>
<swp-closed-day-badge class="holiday">Helligdag</swp-closed-day-badge>
<swp-icon-btn class="edit" title="Rediger åbningstid">
<i class="ph ph-pencil-simple"></i>
</swp-icon-btn>
</swp-closed-day-item>
<swp-closed-day-item>
<swp-closed-day-info>
<swp-closed-day-date>24. maj 2026</swp-closed-day-date>
<swp-closed-day-name>Pinsedag</swp-closed-day-name>
</swp-closed-day-info>
<swp-closed-day-badge class="holiday">Helligdag</swp-closed-day-badge>
<swp-icon-btn class="edit" title="Rediger åbningstid">
<i class="ph ph-pencil-simple"></i>
</swp-icon-btn>
</swp-closed-day-item>
<swp-closed-day-item>
<swp-closed-day-info>
<swp-closed-day-date>25. maj 2026</swp-closed-day-date>
<swp-closed-day-name>2. pinsedag</swp-closed-day-name>
</swp-closed-day-info>
<swp-closed-day-badge class="holiday">Helligdag</swp-closed-day-badge>
<swp-icon-btn class="edit" title="Rediger åbningstid">
<i class="ph ph-pencil-simple"></i>
</swp-icon-btn>
</swp-closed-day-item>
<swp-closed-day-item>
<swp-closed-day-info>
<swp-closed-day-date>5. juni 2026</swp-closed-day-date>
<swp-closed-day-name>Grundlovsdag</swp-closed-day-name>
</swp-closed-day-info>
<swp-closed-day-badge class="holiday">Helligdag</swp-closed-day-badge>
<swp-icon-btn class="edit" title="Rediger åbningstid">
<i class="ph ph-pencil-simple"></i>
</swp-icon-btn>
</swp-closed-day-item>
<swp-closed-day-item>
<swp-closed-day-info>
<swp-closed-day-date>24. december 2026</swp-closed-day-date>
<swp-closed-day-name>Juleaften</swp-closed-day-name>
</swp-closed-day-info>
<swp-closed-day-badge class="holiday">Helligdag</swp-closed-day-badge>
<swp-icon-btn class="edit" title="Rediger åbningstid">
<i class="ph ph-pencil-simple"></i>
</swp-icon-btn>
</swp-closed-day-item>
<swp-closed-day-item>
<swp-closed-day-info>
<swp-closed-day-date>25. december 2026</swp-closed-day-date>
<swp-closed-day-name>1. juledag</swp-closed-day-name>
</swp-closed-day-info>
<swp-closed-day-badge class="holiday">Helligdag</swp-closed-day-badge>
<swp-icon-btn class="edit" title="Rediger åbningstid">
<i class="ph ph-pencil-simple"></i>
</swp-icon-btn>
</swp-closed-day-item>
<swp-closed-day-item>
<swp-closed-day-info>
<swp-closed-day-date>26. december 2026</swp-closed-day-date>
<swp-closed-day-name>2. juledag</swp-closed-day-name>
</swp-closed-day-info>
<swp-closed-day-badge class="holiday">Helligdag</swp-closed-day-badge>
<swp-icon-btn class="edit" title="Rediger åbningstid">
<i class="ph ph-pencil-simple"></i>
</swp-icon-btn>
</swp-closed-day-item>
<swp-closed-day-item>
<swp-closed-day-info>
<swp-closed-day-date>1. januar 2027</swp-closed-day-date>
<swp-closed-day-name>Nytårsdag</swp-closed-day-name>
</swp-closed-day-info>
<swp-closed-day-badge class="holiday">Helligdag</swp-closed-day-badge>
<swp-icon-btn class="edit" title="Rediger åbningstid">
<i class="ph ph-pencil-simple"></i>
</swp-icon-btn>
</swp-closed-day-item>
<swp-closed-day-item>
<swp-closed-day-info>
<swp-closed-day-date>14. - 28. juli 2026</swp-closed-day-date>
<swp-closed-day-name>Sommerferie</swp-closed-day-name>
</swp-closed-day-info>
<swp-closed-day-badge class="custom">Lukkedag</swp-closed-day-badge>
<swp-icon-btn class="delete" title="Fjern">
<i class="ph ph-trash"></i>
</swp-icon-btn>
</swp-closed-day-item>
<swp-closed-day-item>
<swp-closed-day-info>
<swp-closed-day-date>24. - 26. december 2026</swp-closed-day-date>
<swp-closed-day-name>Julelukning</swp-closed-day-name>
</swp-closed-day-info>
<swp-closed-day-badge class="custom">Lukkedag</swp-closed-day-badge>
<swp-icon-btn class="delete" title="Fjern">
<i class="ph ph-trash"></i>
</swp-icon-btn>
</swp-closed-day-item>
</swp-closed-days-list>
</swp-card-content>
</swp-card>
</swp-tab-content>
<!-- ==========================================
TAB: ONLINE BOOKING
========================================== -->
<swp-tab-content data-tab="booking">
<swp-info-box>
<i class="ph ph-info"></i>
<p>Din booking-side er tilgængelig for kunder. Del linket på din hjemmeside, sociale medier eller i din email-signatur.</p>
</swp-info-box>
<swp-card>
<swp-card-header>
<swp-card-title>
<i class="ph ph-link"></i>
Booking URL
</swp-card-title>
</swp-card-header>
<swp-card-content>
<swp-url-field>
<input type="text" value="https://book.plantempus.dk/salonbeauty" readonly>
<swp-url-copy title="Kopier link">
<i class="ph ph-copy"></i>
</swp-url-copy>
</swp-url-field>
</swp-card-content>
</swp-card>
<swp-card>
<swp-card-header>
<swp-card-title>
<i class="ph ph-sliders"></i>
Booking-indstillinger
</swp-card-title>
</swp-card-header>
<swp-card-content>
<swp-toggle-row>
<swp-toggle-info>
<swp-toggle-label>Aktivér online booking</swp-toggle-label>
<swp-toggle-desc>Tillad kunder at booke tider online</swp-toggle-desc>
</swp-toggle-info>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-toggle-row>
<swp-toggle-row>
<swp-toggle-info>
<swp-toggle-label>Tillad online aflysning</swp-toggle-label>
<swp-toggle-desc>Kunder kan selv aflyse deres booking</swp-toggle-desc>
</swp-toggle-info>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-toggle-row>
<swp-section-divider></swp-section-divider>
<swp-edit-section>
<swp-edit-row class="wide-label">
<swp-edit-label>Book frem i tiden</swp-edit-label>
<swp-edit-select>
<select>
<option value="7">7 dage</option>
<option value="14">14 dage</option>
<option value="30" selected>30 dage</option>
<option value="60">60 dage</option>
<option value="90">90 dage</option>
</select>
</swp-edit-select>
</swp-edit-row>
<swp-edit-row class="wide-label">
<swp-edit-label>Minimum tid før booking</swp-edit-label>
<swp-edit-select>
<select>
<option value="0">Ingen begrænsning</option>
<option value="1">1 time</option>
<option value="2" selected>2 timer</option>
<option value="4">4 timer</option>
<option value="24">24 timer</option>
</select>
</swp-edit-select>
</swp-edit-row>
<swp-edit-row class="wide-label">
<swp-edit-label>Aflysningsfrist</swp-edit-label>
<swp-edit-select>
<select>
<option value="0">Ingen frist</option>
<option value="2">2 timer før</option>
<option value="4">4 timer før</option>
<option value="24" selected>24 timer før</option>
<option value="48">48 timer før</option>
</select>
</swp-edit-select>
</swp-edit-row>
</swp-edit-section>
</swp-card-content>
</swp-card>
</swp-tab-content>
<!-- ==========================================
TAB: FAKTURA & KVITTERING (kombineret)
========================================== -->
<swp-tab-content data-tab="billing">
<swp-info-box>
<i class="ph ph-info"></i>
<p><strong>Kvittering</strong> printes efter betaling i butikken. <strong>Faktura</strong> sendes til kunder der betaler senere.</p>
</swp-info-box>
<swp-card>
<swp-card-header>
<swp-card-title>
<i class="ph ph-identification-badge"></i>
Virksomhedsoplysninger
</swp-card-title>
</swp-card-header>
<swp-card-content>
<swp-edit-section>
<swp-edit-row>
<swp-edit-label>Firmanavn (juridisk)</swp-edit-label>
<swp-edit-value contenteditable="true">KARINA KNUDSEN® ApS</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>CVR-nummer</swp-edit-label>
<swp-edit-value contenteditable="true" class="mono">12345678</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Adresse</swp-edit-label>
<swp-edit-value contenteditable="true">Amager Strandvej 22f, 2300 København S</swp-edit-value>
</swp-edit-row>
</swp-edit-section>
</swp-card-content>
</swp-card>
<swp-card>
<swp-card-header>
<swp-card-title>
<i class="ph ph-bank"></i>
Bankoplysninger (kun faktura)
</swp-card-title>
</swp-card-header>
<swp-card-content>
<swp-edit-section>
<swp-edit-row>
<swp-edit-label>Registreringsnr.</swp-edit-label>
<swp-edit-value contenteditable="true" class="mono">1234</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Kontonummer</swp-edit-label>
<swp-edit-value contenteditable="true" class="mono">12345678</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>IBAN <span class="optional">(valgfri)</span></swp-edit-label>
<swp-edit-value contenteditable="true" class="mono" style="color: var(--color-text-secondary);">DK00 0000 0000 0000 00</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>MobilePay <span class="optional">(valgfri)</span></swp-edit-label>
<swp-edit-value contenteditable="true" class="mono">12345678</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Betalingsbetingelser</swp-edit-label>
<swp-edit-select>
<select>
<option value="0">Kontant</option>
<option value="8" selected>Netto 8 dage</option>
<option value="14">Netto 14 dage</option>
<option value="30">Netto 30 dage</option>
</select>
</swp-edit-select>
</swp-edit-row>
</swp-edit-section>
</swp-card-content>
</swp-card>
<swp-card>
<swp-card-header>
<swp-card-title>
<i class="ph ph-eye"></i>
Vis på print
</swp-card-title>
</swp-card-header>
<swp-card-content>
<swp-toggle-row>
<swp-toggle-label>Vis CVR-nummer</swp-toggle-label>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-toggle-row>
<swp-toggle-row>
<swp-toggle-label>Vis telefonnummer</swp-toggle-label>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-toggle-row>
<swp-toggle-row>
<swp-toggle-label>Vis website</swp-toggle-label>
<swp-toggle-slider data-value="no">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-toggle-row>
<swp-toggle-row>
<swp-toggle-label>Vis logo</swp-toggle-label>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-toggle-row>
</swp-card-content>
</swp-card>
<swp-card>
<swp-card-header>
<swp-card-title>
<i class="ph ph-text-align-left"></i>
Tekster
</swp-card-title>
</swp-card-header>
<swp-card-content>
<swp-edit-section>
<swp-edit-row>
<swp-edit-label>Header-tekst</swp-edit-label>
<swp-edit-value contenteditable="true">Tak for dit besøg!</swp-edit-value>
</swp-edit-row>
</swp-edit-section>
<div style="margin-top: 16px;">
<swp-edit-label style="display: block; margin-bottom: 8px;">Footer-tekst</swp-edit-label>
<swp-edit-textarea contenteditable="true">Åbningstider: Man-Fre 9-18, Lør 10-14
Vi glæder os til at se dig igen!</swp-edit-textarea>
</div>
<div style="margin-top: 16px;">
<swp-edit-label style="display: block; margin-bottom: 8px;">Faktura-tekst</swp-edit-label>
<swp-edit-textarea contenteditable="true">Ved betaling bedes fakturanummer angivet.
Tak for din handel!</swp-edit-textarea>
</div>
</swp-card-content>
</swp-card>
</swp-tab-content>
<!-- ==========================================
TAB: PÅMINDELSER
========================================== -->
<swp-tab-content data-tab="reminders">
<swp-two-column-grid>
<!-- EMAIL COLUMN -->
<swp-card>
<swp-card-header>
<swp-card-title>
<i class="ph ph-envelope"></i>
Email
</swp-card-title>
</swp-card-header>
<swp-card-content>
<swp-notification-list>
<swp-notification-item>
<swp-notification-main>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
<swp-notification-info>
<swp-notification-title>Bekræftelse</swp-notification-title>
<swp-notification-desc>Sendes når en aftale er booket</swp-notification-desc>
</swp-notification-info>
</swp-notification-main>
<swp-edit-link>Rediger</swp-edit-link>
</swp-notification-item>
<swp-notification-item>
<swp-notification-main>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
<swp-notification-info>
<swp-notification-title>Påmindelse</swp-notification-title>
<swp-notification-desc>Sendes inden aftalen</swp-notification-desc>
</swp-notification-info>
</swp-notification-main>
<swp-edit-link>Rediger</swp-edit-link>
</swp-notification-item>
<swp-notification-item>
<swp-notification-main>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
<swp-notification-info>
<swp-notification-title>Aflysning</swp-notification-title>
<swp-notification-desc>Sendes når en aftale er aflyst</swp-notification-desc>
</swp-notification-info>
</swp-notification-main>
<swp-edit-link>Rediger</swp-edit-link>
</swp-notification-item>
<swp-notification-item>
<swp-notification-main>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
<swp-notification-info>
<swp-notification-title>Flytning</swp-notification-title>
<swp-notification-desc>Sendes når en aftale er flyttet</swp-notification-desc>
</swp-notification-info>
</swp-notification-main>
<swp-edit-link>Rediger</swp-edit-link>
</swp-notification-item>
</swp-notification-list>
<swp-card-note>Email-påmindelser er gratis.</swp-card-note>
</swp-card-content>
</swp-card>
<!-- SMS COLUMN -->
<swp-card>
<swp-card-header>
<swp-card-title>
<i class="ph ph-chat-text"></i>
SMS
</swp-card-title>
</swp-card-header>
<swp-card-content>
<swp-notification-list>
<swp-notification-item>
<swp-notification-main>
<swp-toggle-slider data-value="no">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
<swp-notification-info>
<swp-notification-title>
Bekræftelse online
<swp-notification-price>(0,30 kr.)</swp-notification-price>
</swp-notification-title>
<swp-notification-desc>Sendes ved online booking</swp-notification-desc>
</swp-notification-info>
</swp-notification-main>
<swp-edit-link>Rediger</swp-edit-link>
</swp-notification-item>
<swp-notification-item>
<swp-notification-main>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
<swp-notification-info>
<swp-notification-title>
Bekræftelse manuelt
<swp-notification-price>(0,30 kr.)</swp-notification-price>
</swp-notification-title>
<swp-notification-desc>Ved oprettelse i kalender</swp-notification-desc>
</swp-notification-info>
</swp-notification-main>
<swp-edit-link>Rediger</swp-edit-link>
</swp-notification-item>
<swp-notification-item>
<swp-notification-main>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
<swp-notification-info>
<swp-notification-title>
Påmindelse
<swp-notification-price class="premium">(Premium)</swp-notification-price>
</swp-notification-title>
<swp-notification-desc>Sendes inden aftalen</swp-notification-desc>
</swp-notification-info>
</swp-notification-main>
<swp-edit-link>Rediger</swp-edit-link>
</swp-notification-item>
</swp-notification-list>
<swp-section-divider></swp-section-divider>
<swp-edit-section>
<swp-edit-row>
<swp-edit-label>Påmindelse sendes</swp-edit-label>
<swp-edit-select>
<select>
<option value="2">2 timer før</option>
<option value="4">4 timer før</option>
<option value="12">12 timer før</option>
<option value="24" selected>24 timer før</option>
<option value="48">48 timer før</option>
</select>
</swp-edit-select>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Sendes mellem</swp-edit-label>
<swp-time-range>
<input type="time" value="08:00">
<span></span>
<input type="time" value="21:00">
</swp-time-range>
</swp-edit-row>
</swp-edit-section>
</swp-card-content>
</swp-card>
</swp-two-column-grid>
</swp-tab-content>
<!-- ==========================================
TAB: BETALINGER
========================================== -->
<swp-tab-content data-tab="payments">
<swp-card>
<swp-card-header>
<swp-card-title>
<i class="ph ph-wallet"></i>
Betalingsmetoder i butik
</swp-card-title>
</swp-card-header>
<swp-card-content>
<swp-section-intro>Vælg hvilke betalingsmetoder dine kunder kan bruge ved checkout i butikken.</swp-section-intro>
<swp-toggle-row>
<swp-toggle-info>
<swp-toggle-label>Kontant</swp-toggle-label>
<swp-toggle-desc>Modtag kontant betaling</swp-toggle-desc>
</swp-toggle-info>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-toggle-row>
<swp-toggle-row>
<swp-toggle-info>
<swp-toggle-label>Dankort / Visa / Mastercard</swp-toggle-label>
<swp-toggle-desc>Betalingskort via terminal</swp-toggle-desc>
</swp-toggle-info>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-toggle-row>
<swp-toggle-row>
<swp-toggle-info>
<swp-toggle-label>MobilePay</swp-toggle-label>
<swp-toggle-desc>Betaling via MobilePay</swp-toggle-desc>
</swp-toggle-info>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-toggle-row>
<swp-toggle-row>
<swp-toggle-info>
<swp-toggle-label>Gavekort</swp-toggle-label>
<swp-toggle-desc>Indløs gavekort som betaling</swp-toggle-desc>
</swp-toggle-info>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-toggle-row>
<swp-toggle-row>
<swp-toggle-info>
<swp-toggle-label>Faktura</swp-toggle-label>
<swp-toggle-desc>Send faktura til kunden</swp-toggle-desc>
</swp-toggle-info>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-toggle-row>
</swp-card-content>
</swp-card>
<swp-card>
<swp-card-header>
<swp-card-title>
<i class="ph ph-globe"></i>
Online betaling
</swp-card-title>
</swp-card-header>
<swp-card-content>
<swp-toggle-row>
<swp-toggle-info>
<swp-toggle-label>Modtag betaling ved online booking</swp-toggle-label>
<swp-toggle-desc>Kunder betaler når de booker online</swp-toggle-desc>
</swp-toggle-info>
<swp-toggle-slider data-value="no" id="onlinePaymentToggle">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-toggle-row>
<div id="onlinePaymentSettings" style="display: none;">
<swp-section-divider></swp-section-divider>
<swp-info-box>
<i class="ph ph-info"></i>
<p>Online betalinger håndteres via Stripe. Beløbet overføres automatisk til din bankkonto efter den valgte periode.</p>
</swp-info-box>
<swp-edit-section>
<swp-edit-row class="wide-label">
<swp-edit-label>Registreringsnummer</swp-edit-label>
<swp-edit-value contenteditable="true" class="mono">1234</swp-edit-value>
</swp-edit-row>
<swp-edit-row class="wide-label">
<swp-edit-label>Kontonummer</swp-edit-label>
<swp-edit-value contenteditable="true" class="mono">12345678</swp-edit-value>
</swp-edit-row>
<swp-edit-row class="wide-label">
<swp-edit-label>Udbetaling</swp-edit-label>
<swp-edit-select>
<select>
<option value="7" selected>Hver uge</option>
<option value="14">Hver 2. uge</option>
<option value="28">Hver 4. uge</option>
</select>
</swp-edit-select>
</swp-edit-row>
</swp-edit-section>
</div>
</swp-card-content>
</swp-card>
<swp-card>
<swp-card-header>
<swp-card-title>
<i class="ph ph-percent"></i>
Gebyr & tillæg
</swp-card-title>
</swp-card-header>
<swp-card-content>
<swp-toggle-row>
<swp-toggle-info>
<swp-toggle-label>Vis kortgebyr til kunden</swp-toggle-label>
<swp-toggle-desc>Vis kortgebyr som separat linje på kvittering</swp-toggle-desc>
</swp-toggle-info>
<swp-toggle-slider data-value="no">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-toggle-row>
</swp-card-content>
</swp-card>
</swp-tab-content>
<!-- ==========================================
TAB: MODULER
========================================== -->
<swp-tab-content data-tab="modules">
<!-- Løn & Økonomi sektion -->
<swp-modules-section>
<swp-modules-header>
<swp-modules-title>
<i class="ph ph-wallet"></i>
Løn & Økonomi
</swp-modules-title>
</swp-modules-header>
<swp-modules-grid>
<!-- Lønberegning -->
<swp-module-card>
<swp-module-header>
<swp-module-icon class="teal">
<i class="ph ph-calculator"></i>
</swp-module-icon>
<swp-module-info>
<swp-module-title>Lønberegning</swp-module-title>
<swp-module-desc>Beregn løn, overtid, provision og ferie automatisk. Grundmodul for løneksport til eksterne systemer.</swp-module-desc>
</swp-module-info>
<swp-module-toggle>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Til</swp-toggle-option>
<swp-toggle-option>Fra</swp-toggle-option>
</swp-toggle-slider>
</swp-module-toggle>
</swp-module-header>
<swp-module-footer>
<swp-module-tags>
<swp-module-tag class="included">Inkluderet</swp-module-tag>
</swp-module-tags>
<swp-btn class="small secondary">Indstillinger</swp-btn>
</swp-module-footer>
</swp-module-card>
<!-- Intect -->
<swp-module-card>
<swp-module-header>
<swp-module-icon class="blue">
<i class="ph ph-export"></i>
</swp-module-icon>
<swp-module-info>
<swp-module-title>Intect</swp-module-title>
<swp-module-desc>Eksporter direkte til Intect lønsystem i StandardMapping-format.</swp-module-desc>
</swp-module-info>
<swp-module-toggle>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Til</swp-toggle-option>
<swp-toggle-option>Fra</swp-toggle-option>
</swp-toggle-slider>
</swp-module-toggle>
</swp-module-header>
<swp-module-footer>
<swp-module-tags>
<swp-module-tag class="included">Inkluderet</swp-module-tag>
</swp-module-tags>
<swp-btn class="small secondary">Indstillinger</swp-btn>
</swp-module-footer>
</swp-module-card>
<!-- Proløn -->
<swp-module-card>
<swp-module-header>
<swp-module-icon class="blue">
<i class="ph ph-export"></i>
</swp-module-icon>
<swp-module-info>
<swp-module-title>Proløn</swp-module-title>
<swp-module-desc>Eksporter direkte til Proløn lønsystem.</swp-module-desc>
</swp-module-info>
<swp-module-toggle>
<swp-toggle-slider data-value="no">
<swp-toggle-option>Til</swp-toggle-option>
<swp-toggle-option>Fra</swp-toggle-option>
</swp-toggle-slider>
</swp-module-toggle>
</swp-module-header>
<swp-module-footer>
<swp-module-tags>
<swp-module-tag class="coming">Kommer</swp-module-tag>
</swp-module-tags>
</swp-module-footer>
</swp-module-card>
<!-- Danløn -->
<swp-module-card>
<swp-module-header>
<swp-module-icon class="blue">
<i class="ph ph-export"></i>
</swp-module-icon>
<swp-module-info>
<swp-module-title>Danløn</swp-module-title>
<swp-module-desc>Eksporter direkte til Danløn lønsystem.</swp-module-desc>
</swp-module-info>
<swp-module-toggle>
<swp-toggle-slider data-value="no">
<swp-toggle-option>Til</swp-toggle-option>
<swp-toggle-option>Fra</swp-toggle-option>
</swp-toggle-slider>
</swp-module-toggle>
</swp-module-header>
<swp-module-footer>
<swp-module-tags>
<swp-module-tag class="coming">Kommer</swp-module-tag>
</swp-module-tags>
</swp-module-footer>
</swp-module-card>
<!-- Salary.dk -->
<swp-module-card>
<swp-module-header>
<swp-module-icon class="blue">
<i class="ph ph-export"></i>
</swp-module-icon>
<swp-module-info>
<swp-module-title>Salary.dk</swp-module-title>
<swp-module-desc>Eksporter direkte til Salary.dk lønsystem.</swp-module-desc>
</swp-module-info>
<swp-module-toggle>
<swp-toggle-slider data-value="no">
<swp-toggle-option>Til</swp-toggle-option>
<swp-toggle-option>Fra</swp-toggle-option>
</swp-toggle-slider>
</swp-module-toggle>
</swp-module-header>
<swp-module-footer>
<swp-module-tags>
<swp-module-tag class="coming">Kommer</swp-module-tag>
</swp-module-tags>
</swp-module-footer>
</swp-module-card>
<!-- Zenegy -->
<swp-module-card>
<swp-module-header>
<swp-module-icon class="teal">
<i class="ph ph-export"></i>
</swp-module-icon>
<swp-module-info>
<swp-module-title>Zenegy</swp-module-title>
<swp-module-desc>Eksporter direkte til Zenegy lønsystem. Automatisk overførsel af timer og provision.</swp-module-desc>
</swp-module-info>
<swp-module-toggle>
<swp-toggle-slider data-value="no">
<swp-toggle-option>Til</swp-toggle-option>
<swp-toggle-option>Fra</swp-toggle-option>
</swp-toggle-slider>
</swp-module-toggle>
</swp-module-header>
<swp-module-footer>
<swp-module-tags>
<swp-module-tag class="coming">Kommer</swp-module-tag>
</swp-module-tags>
</swp-module-footer>
</swp-module-card>
</swp-modules-grid>
</swp-modules-section>
<!-- AI & Analyse sektion -->
<swp-modules-section>
<swp-modules-header>
<swp-modules-title>
<i class="ph ph-brain"></i>
AI & Analyse
</swp-modules-title>
<swp-modules-badge>Nyt</swp-modules-badge>
</swp-modules-header>
<swp-modules-grid>
<!-- AI Dashboard -->
<swp-module-card>
<swp-module-header>
<swp-module-icon class="purple">
<i class="ph ph-sparkle"></i>
</swp-module-icon>
<swp-module-info>
<swp-module-title>AI Dashboard</swp-module-title>
<swp-module-desc>Din personlige AI-assistent på dashboardet. Få daglige indsigter, anbefalinger og svar på spørgsmål om din forretning.</swp-module-desc>
</swp-module-info>
<swp-module-toggle>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Til</swp-toggle-option>
<swp-toggle-option>Fra</swp-toggle-option>
</swp-toggle-slider>
</swp-module-toggle>
</swp-module-header>
<swp-module-footer>
<swp-module-tags>
<swp-module-tag class="included">Inkluderet</swp-module-tag>
</swp-module-tags>
<swp-btn class="small secondary">Indstillinger</swp-btn>
</swp-module-footer>
</swp-module-card>
<!-- AI Virksomhedsanalyse -->
<swp-module-card>
<swp-module-header>
<swp-module-icon class="purple">
<i class="ph ph-chart-line-up"></i>
</swp-module-icon>
<swp-module-info>
<swp-module-title>AI Virksomhedsanalyse</swp-module-title>
<swp-module-desc>Dybdegående AI-analyse af timer vs. omsætning, belægningsgrad og identificer mønstre og vækstmuligheder.</swp-module-desc>
</swp-module-info>
<swp-module-toggle>
<swp-toggle-slider data-value="no">
<swp-toggle-option>Til</swp-toggle-option>
<swp-toggle-option>Fra</swp-toggle-option>
</swp-toggle-slider>
</swp-module-toggle>
</swp-module-header>
<swp-module-footer>
<swp-module-tags>
<swp-module-tag class="price">+49 kr/md</swp-module-tag>
<swp-module-tag class="new">Beta</swp-module-tag>
</swp-module-tags>
<swp-btn class="small secondary">Læs mere</swp-btn>
</swp-module-footer>
</swp-module-card>
<!-- AI Produktsalg -->
<swp-module-card class="featured purple">
<swp-module-header>
<swp-module-icon class="purple">
<i class="ph ph-shopping-bag"></i>
</swp-module-icon>
<swp-module-info>
<swp-module-title>AI Produktsalg</swp-module-title>
<swp-module-desc>Øg dit produktsalg med intelligente anbefalinger. AI'en lærer dine kunders præferencer og foreslår de rigtige produkter på det rigtige tidspunkt.</swp-module-desc>
</swp-module-info>
<swp-module-toggle>
<swp-toggle-slider data-value="no">
<swp-toggle-option>Til</swp-toggle-option>
<swp-toggle-option>Fra</swp-toggle-option>
</swp-toggle-slider>
</swp-module-toggle>
</swp-module-header>
<swp-module-features>
<swp-module-feature class="purple">
<i class="ph ph-check-circle"></i>
<span>Personlige produktanbefalinger</span>
</swp-module-feature>
<swp-module-feature class="purple">
<i class="ph ph-check-circle"></i>
<span>Automatisk mersalg ved kassen</span>
</swp-module-feature>
<swp-module-feature class="purple">
<i class="ph ph-check-circle"></i>
<span>Kundeprofilanalyse</span>
</swp-module-feature>
<swp-module-feature class="purple">
<i class="ph ph-check-circle"></i>
<span>Sæson- og trendbaserede forslag</span>
</swp-module-feature>
</swp-module-features>
<swp-module-stats class="purple">
<swp-module-stat>
<swp-module-stat-value>+23%</swp-module-stat-value>
<swp-module-stat-label>Mersalg pr. kunde</swp-module-stat-label>
</swp-module-stat>
<swp-module-stat>
<swp-module-stat-value>4.2x</swp-module-stat-value>
<swp-module-stat-label>Højere konvertering</swp-module-stat-label>
</swp-module-stat>
<swp-module-stat>
<swp-module-stat-value>89%</swp-module-stat-value>
<swp-module-stat-label>Relevante forslag</swp-module-stat-label>
</swp-module-stat>
</swp-module-stats>
<swp-module-footer>
<swp-module-tags>
<swp-module-tag class="price">+49 kr/md</swp-module-tag>
<swp-module-tag class="new">Beta</swp-module-tag>
</swp-module-tags>
<swp-btn class="small primary purple">Prøv gratis i 14 dage</swp-btn>
</swp-module-footer>
</swp-module-card>
<!-- AI Kalenderoptimering -->
<swp-module-card class="featured">
<swp-module-header>
<swp-module-icon class="green">
<i class="ph ph-sparkle"></i>
</swp-module-icon>
<swp-module-info>
<swp-module-title>AI Kalenderoptimering</swp-module-title>
<swp-module-desc>Maksimer din kalenderudnyttelse og reducer tabt omsætning. AI'en foreslår optimale tider til kunder og identificerer huller der kan fyldes.</swp-module-desc>
</swp-module-info>
<swp-module-toggle>
<swp-toggle-slider data-value="no">
<swp-toggle-option>Til</swp-toggle-option>
<swp-toggle-option>Fra</swp-toggle-option>
</swp-toggle-slider>
</swp-module-toggle>
</swp-module-header>
<swp-module-features>
<swp-module-feature>
<i class="ph ph-check-circle"></i>
<span>Smart tidsforslag ved booking</span>
</swp-module-feature>
<swp-module-feature>
<i class="ph ph-check-circle"></i>
<span>Automatisk hul-identifikation</span>
</swp-module-feature>
<swp-module-feature>
<i class="ph ph-check-circle"></i>
<span>SMS-tilbud til flytning af tider</span>
</swp-module-feature>
<swp-module-feature>
<i class="ph ph-check-circle"></i>
<span>Dashboard med optimeringsscore</span>
</swp-module-feature>
</swp-module-features>
<swp-module-stats>
<swp-module-stat>
<swp-module-stat-value>52x</swp-module-stat-value>
<swp-module-stat-label>ROI i gennemsnit</swp-module-stat-label>
</swp-module-stat>
<swp-module-stat>
<swp-module-stat-value>15%</swp-module-stat-value>
<swp-module-stat-label>Færre tomme slots</swp-module-stat-label>
</swp-module-stat>
<swp-module-stat>
<swp-module-stat-value>312k</swp-module-stat-value>
<swp-module-stat-label>Ekstra oms./år*</swp-module-stat-label>
</swp-module-stat>
</swp-module-stats>
<swp-module-footer>
<swp-module-tags>
<swp-module-tag class="price">+99 kr/md</swp-module-tag>
<swp-module-tag class="new">Ny</swp-module-tag>
</swp-module-tags>
<swp-btn class="small primary">Prøv gratis i 14 dage</swp-btn>
</swp-module-footer>
</swp-module-card>
</swp-modules-grid>
</swp-modules-section>
<!-- Tillægsmoduler sektion -->
<swp-modules-section>
<swp-modules-header>
<swp-modules-title>
<i class="ph ph-plus-circle"></i>
Tillægsmoduler
</swp-modules-title>
</swp-modules-header>
<swp-modules-grid>
<!-- Online Booking -->
<swp-module-card>
<swp-module-header>
<swp-module-icon class="teal">
<i class="ph ph-globe"></i>
</swp-module-icon>
<swp-module-info>
<swp-module-title>Online Booking</swp-module-title>
<swp-module-desc>Lad kunder booke tider online via din egen bookingside. Integreres med kalender og påmindelser.</swp-module-desc>
</swp-module-info>
<swp-module-toggle>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Til</swp-toggle-option>
<swp-toggle-option>Fra</swp-toggle-option>
</swp-toggle-slider>
</swp-module-toggle>
</swp-module-header>
<swp-module-footer>
<swp-module-tags>
<swp-module-tag class="included">Inkluderet</swp-module-tag>
</swp-module-tags>
<swp-btn class="small secondary">Indstillinger</swp-btn>
</swp-module-footer>
</swp-module-card>
<!-- Gavekort -->
<swp-module-card>
<swp-module-header>
<swp-module-icon class="amber">
<i class="ph ph-gift"></i>
</swp-module-icon>
<swp-module-info>
<swp-module-title>Gavekort</swp-module-title>
<swp-module-desc>Sælg og administrer digitale gavekort. Kunderne kan købe online eller i butikken, og indløse ved betaling.</swp-module-desc>
</swp-module-info>
<swp-module-toggle>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Til</swp-toggle-option>
<swp-toggle-option>Fra</swp-toggle-option>
</swp-toggle-slider>
</swp-module-toggle>
</swp-module-header>
<swp-module-footer>
<swp-module-tags>
<swp-module-tag class="included">Inkluderet</swp-module-tag>
</swp-module-tags>
<swp-btn class="small secondary">Indstillinger</swp-btn>
</swp-module-footer>
</swp-module-card>
<!-- Kasseafstemning -->
<swp-module-card>
<swp-module-header>
<swp-module-icon class="blue">
<i class="ph ph-calculator"></i>
</swp-module-icon>
<swp-module-info>
<swp-module-title>Kasseafstemning</swp-module-title>
<swp-module-desc>Daglig kasseopgørelse og afstemning. Hold styr på kontanter, kort og andre betalingsmetoder.</swp-module-desc>
</swp-module-info>
<swp-module-toggle>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Til</swp-toggle-option>
<swp-toggle-option>Fra</swp-toggle-option>
</swp-toggle-slider>
</swp-module-toggle>
</swp-module-header>
<swp-module-footer>
<swp-module-tags>
<swp-module-tag class="included">Inkluderet</swp-module-tag>
</swp-module-tags>
<swp-btn class="small secondary">Indstillinger</swp-btn>
</swp-module-footer>
</swp-module-card>
<!-- Leverandører -->
<swp-module-card>
<swp-module-header>
<swp-module-icon class="green">
<i class="ph ph-truck"></i>
</swp-module-icon>
<swp-module-info>
<swp-module-title>Leverandører</swp-module-title>
<swp-module-desc>Bestil varer direkte fra dine leverandører. Hold styr på ordrer, leveringer og lagerbeholdning.</swp-module-desc>
</swp-module-info>
<swp-module-toggle>
<swp-toggle-slider data-value="no">
<swp-toggle-option>Til</swp-toggle-option>
<swp-toggle-option>Fra</swp-toggle-option>
</swp-toggle-slider>
</swp-module-toggle>
</swp-module-header>
<swp-module-footer>
<swp-module-tags>
<swp-module-tag class="included">Inkluderet</swp-module-tag>
</swp-module-tags>
<swp-btn class="small secondary">Indstillinger</swp-btn>
</swp-module-footer>
</swp-module-card>
<!-- Stregkodescanner -->
<swp-module-card>
<swp-module-header>
<swp-module-icon class="purple">
<i class="ph ph-barcode"></i>
</swp-module-icon>
<swp-module-info>
<swp-module-title>Stregkodescanner</swp-module-title>
<swp-module-desc>Scan EAN-koder og få AI-genererede produktbeskrivelser automatisk. Opret nye produkter på sekunder.</swp-module-desc>
</swp-module-info>
<swp-module-toggle>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Til</swp-toggle-option>
<swp-toggle-option>Fra</swp-toggle-option>
</swp-toggle-slider>
</swp-module-toggle>
</swp-module-header>
<swp-module-footer>
<swp-module-tags>
<swp-module-tag class="included">Inkluderet</swp-module-tag>
<swp-module-tag class="new">AI</swp-module-tag>
</swp-module-tags>
<swp-btn class="small secondary">Indstillinger</swp-btn>
</swp-module-footer>
</swp-module-card>
<!-- Website Builder -->
<swp-module-card>
<swp-module-header>
<swp-module-icon class="teal">
<i class="ph ph-layout"></i>
</swp-module-icon>
<swp-module-info>
<swp-module-title>Website Builder</swp-module-title>
<swp-module-desc>Byg din salons hjemmeside med drag-and-drop blokke. Vælg mellem færdige designs, tilpas farver og fonte, og integrer din booking.</swp-module-desc>
</swp-module-info>
<swp-module-toggle>
<swp-toggle-slider data-value="no">
<swp-toggle-option>Til</swp-toggle-option>
<swp-toggle-option>Fra</swp-toggle-option>
</swp-toggle-slider>
</swp-module-toggle>
</swp-module-header>
<swp-module-footer>
<swp-module-tags>
<swp-module-tag class="price">+149 kr/md</swp-module-tag>
<swp-module-tag class="new">Ny</swp-module-tag>
</swp-module-tags>
<swp-btn class="small secondary" onclick="window.open('poc-website-builder.html', '_blank')">Åbn Builder</swp-btn>
</swp-module-footer>
</swp-module-card>
<!-- HR & Dokumenter -->
<swp-module-card class="full-width">
<swp-module-header>
<swp-module-icon class="purple">
<i class="ph ph-folder-user"></i>
</swp-module-icon>
<swp-module-info>
<swp-module-title>HR & Dokumenter</swp-module-title>
<swp-module-desc>Komplet medarbejderstyring: Kontrakter, certificeringer, kurser, ferie-saldo, sygefravær og barsel. Upload dokumenter og få påmindelser om udløbsdatoer.</swp-module-desc>
</swp-module-info>
<swp-module-toggle>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Til</swp-toggle-option>
<swp-toggle-option>Fra</swp-toggle-option>
</swp-toggle-slider>
</swp-module-toggle>
</swp-module-header>
<swp-module-footer>
<swp-module-tags>
<swp-module-tag class="included">Inkluderet</swp-module-tag>
</swp-module-tags>
<swp-btn class="small secondary">Indstillinger</swp-btn>
</swp-module-footer>
</swp-module-card>
</swp-modules-grid>
</swp-modules-section>
<!-- Integrationer sektion -->
<swp-modules-section>
<swp-modules-header>
<swp-modules-title>
<i class="ph ph-plugs-connected"></i>
Integrationer
</swp-modules-title>
</swp-modules-header>
<swp-modules-grid>
<!-- Sygeforsikring "danmark" -->
<swp-module-card class="featured">
<swp-module-header>
<swp-module-icon class="green">
<i class="ph ph-heart-half"></i>
</swp-module-icon>
<swp-module-info>
<swp-module-title>Sygeforsikring "danmark"</swp-module-title>
<swp-module-desc>Gør det nemt for dine kunder at få tilskud. Send automatisk kvitteringer til "danmark" så kunderne får deres penge tilbage uden selv at løfte en finger.</swp-module-desc>
</swp-module-info>
<swp-module-toggle>
<swp-toggle-slider data-value="no">
<swp-toggle-option>Til</swp-toggle-option>
<swp-toggle-option>Fra</swp-toggle-option>
</swp-toggle-slider>
</swp-module-toggle>
</swp-module-header>
<swp-module-features>
<swp-module-feature>
<i class="ph ph-check-circle"></i>
<span>Automatisk indsendelse af kvitteringer</span>
</swp-module-feature>
<swp-module-feature>
<i class="ph ph-check-circle"></i>
<span>Direkte integration via API</span>
</swp-module-feature>
<swp-module-feature>
<i class="ph ph-check-circle"></i>
<span>Kunden får tilskud uden besvær</span>
</swp-module-feature>
<swp-module-feature>
<i class="ph ph-check-circle"></i>
<span>Øget kundetilfredshed</span>
</swp-module-feature>
</swp-module-features>
<swp-module-stats>
<swp-module-stat>
<swp-module-stat-value>2.1M</swp-module-stat-value>
<swp-module-stat-label>Medlemmer i DK</swp-module-stat-label>
</swp-module-stat>
<swp-module-stat>
<swp-module-stat-value>100%</swp-module-stat-value>
<swp-module-stat-label>Automatiseret</swp-module-stat-label>
</swp-module-stat>
<swp-module-stat>
<swp-module-stat-value>0 kr</swp-module-stat-value>
<swp-module-stat-label>Ekstra gebyr</swp-module-stat-label>
</swp-module-stat>
</swp-module-stats>
<swp-module-footer>
<swp-module-tags>
<swp-module-tag class="included">Inkluderet</swp-module-tag>
</swp-module-tags>
<swp-btn class="small primary">Opsæt integration</swp-btn>
</swp-module-footer>
</swp-module-card>
<!-- Kalenderintegration -->
<swp-module-card>
<swp-module-header>
<swp-module-icon class="blue">
<i class="ph ph-calendar-check"></i>
</swp-module-icon>
<swp-module-info>
<swp-module-title>Kalenderintegration</swp-module-title>
<swp-module-desc>Få dine bookinger synkroniseret til din private kalender automatisk. Se alle aftaler samlet ét sted - også når du er offline.</swp-module-desc>
</swp-module-info>
<swp-module-toggle>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Til</swp-toggle-option>
<swp-toggle-option>Fra</swp-toggle-option>
</swp-toggle-slider>
</swp-module-toggle>
</swp-module-header>
<swp-module-features>
<swp-module-feature>
<i class="ph ph-check-circle"></i>
<span>Google Kalender</span>
</swp-module-feature>
<swp-module-feature>
<i class="ph ph-check-circle"></i>
<span>Apple iCloud Kalender</span>
</swp-module-feature>
<swp-module-feature>
<i class="ph ph-check-circle"></i>
<span>Microsoft Outlook</span>
</swp-module-feature>
<swp-module-feature>
<i class="ph ph-check-circle"></i>
<span>Tovejs-synkronisering</span>
</swp-module-feature>
</swp-module-features>
<swp-module-footer>
<swp-module-tags>
<swp-module-tag class="included">Inkluderet</swp-module-tag>
</swp-module-tags>
<swp-btn class="small secondary">Indstillinger</swp-btn>
</swp-module-footer>
</swp-module-card>
</swp-modules-grid>
</swp-modules-section>
</swp-tab-content>
<!-- ==========================================
TAB: TRACKING
========================================== -->
<swp-tab-content data-tab="tracking">
<!-- Meta Pixel -->
<swp-card class="tracking-card" data-tracker="meta">
<swp-card-header>
<swp-card-title>
<i class="ph ph-meta-logo"></i>
Meta Pixel (Facebook)
</swp-card-title>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-card-header>
<swp-card-content>
<swp-edit-section>
<swp-edit-row>
<swp-edit-label>Pixel ID</swp-edit-label>
<swp-edit-value contenteditable="true" class="mono" id="metaPixelId" oninput="updateTrackingPreview()">123456789012345</swp-edit-value>
</swp-edit-row>
</swp-edit-section>
<swp-tracking-hint>
<i class="ph ph-info"></i>
Bruges til Facebook og Instagram annoncering og remarketing
</swp-tracking-hint>
</swp-card-content>
</swp-card>
<!-- Google Analytics -->
<swp-card class="tracking-card" data-tracker="ga4">
<swp-card-header>
<swp-card-title>
<i class="ph ph-chart-line"></i>
Google Analytics (GA4)
</swp-card-title>
<swp-toggle-slider data-value="yes">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-card-header>
<swp-card-content>
<swp-edit-section>
<swp-edit-row>
<swp-edit-label>Measurement ID</swp-edit-label>
<swp-edit-value contenteditable="true" class="mono" id="ga4Id" oninput="updateTrackingPreview()">G-ABC123XYZ</swp-edit-value>
</swp-edit-row>
</swp-edit-section>
<swp-tracking-hint>
<i class="ph ph-info"></i>
Google Analytics 4 til website trafik og brugeradfærd
</swp-tracking-hint>
</swp-card-content>
</swp-card>
<!-- Google Tag Manager -->
<swp-card class="tracking-card" data-tracker="gtm">
<swp-card-header>
<swp-card-title>
<i class="ph ph-code"></i>
Google Tag Manager
</swp-card-title>
<swp-toggle-slider data-value="no">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-card-header>
<swp-card-content>
<swp-edit-section>
<swp-edit-row>
<swp-edit-label>Container ID</swp-edit-label>
<swp-edit-value contenteditable="true" class="mono" id="gtmId" oninput="updateTrackingPreview()">GTM-XXXXXXX</swp-edit-value>
</swp-edit-row>
</swp-edit-section>
<swp-tracking-hint>
<i class="ph ph-info"></i>
Central styring af alle tracking-tags
</swp-tracking-hint>
</swp-card-content>
</swp-card>
<!-- Plausible -->
<swp-card class="tracking-card" data-tracker="plausible">
<swp-card-header>
<swp-card-title>
<i class="ph ph-leaf"></i>
Plausible Analytics
</swp-card-title>
<swp-toggle-slider data-value="no">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-card-header>
<swp-card-content>
<swp-edit-section>
<swp-edit-row>
<swp-edit-label>Domæne</swp-edit-label>
<swp-edit-value contenteditable="true" class="mono" id="plausibleDomain" oninput="updateTrackingPreview()">minside.dk</swp-edit-value>
</swp-edit-row>
</swp-edit-section>
<swp-tracking-hint class="privacy">
<i class="ph ph-shield-check"></i>
Privacy-venlig analytics uden cookies - GDPR compliant
</swp-tracking-hint>
</swp-card-content>
</swp-card>
<!-- Fathom -->
<swp-card class="tracking-card" data-tracker="fathom">
<swp-card-header>
<swp-card-title>
<i class="ph ph-eye"></i>
Fathom Analytics
</swp-card-title>
<swp-toggle-slider data-value="no">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-card-header>
<swp-card-content>
<swp-edit-section>
<swp-edit-row>
<swp-edit-label>Site ID</swp-edit-label>
<swp-edit-value contenteditable="true" class="mono" id="fathomSiteId" oninput="updateTrackingPreview()">ABCDEFGH</swp-edit-value>
</swp-edit-row>
</swp-edit-section>
<swp-tracking-hint class="privacy">
<i class="ph ph-shield-check"></i>
Privacy-venlig analytics uden cookies - GDPR compliant
</swp-tracking-hint>
</swp-card-content>
</swp-card>
<!-- Matomo -->
<swp-card class="tracking-card" data-tracker="matomo">
<swp-card-header>
<swp-card-title>
<i class="ph ph-database"></i>
Matomo
</swp-card-title>
<swp-toggle-slider data-value="no">
<swp-toggle-option>Ja</swp-toggle-option>
<swp-toggle-option>Nej</swp-toggle-option>
</swp-toggle-slider>
</swp-card-header>
<swp-card-content>
<swp-edit-section>
<swp-edit-row>
<swp-edit-label>Server URL</swp-edit-label>
<swp-edit-value contenteditable="true" class="mono" id="matomoUrl" oninput="updateTrackingPreview()">https://matomo.minside.dk</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Site ID</swp-edit-label>
<swp-edit-value contenteditable="true" class="mono" id="matomoSiteId" oninput="updateTrackingPreview()">1</swp-edit-value>
</swp-edit-row>
</swp-edit-section>
<swp-tracking-hint class="privacy">
<i class="ph ph-shield-check"></i>
Self-hosted analytics - fuld kontrol over dine data
</swp-tracking-hint>
</swp-card-content>
</swp-card>
<!-- Custom Scripts -->
<swp-card class="tracking-card full-width">
<swp-card-header>
<swp-card-title>
<i class="ph ph-code-block"></i>
Brugerdefinerede Scripts
</swp-card-title>
</swp-card-header>
<swp-card-content>
<swp-script-section>
<swp-script-label>
<i class="ph ph-file-code"></i>
Scripts i &lt;head&gt;
</swp-script-label>
<textarea class="script-textarea" id="customHeadScripts" placeholder="<!-- Indsæt custom tracking kode her -->" oninput="updateTrackingPreview()"></textarea>
</swp-script-section>
<swp-script-section>
<swp-script-label>
<i class="ph ph-file-code"></i>
Scripts før &lt;/body&gt;
</swp-script-label>
<textarea class="script-textarea" id="customBodyScripts" placeholder="<!-- Indsæt custom kode her -->"></textarea>
</swp-script-section>
</swp-card-content>
</swp-card>
<!-- Generated Code Preview -->
<swp-card class="code-preview-card">
<swp-card-header>
<swp-card-title>
<i class="ph ph-terminal"></i>
Genereret Kode
</swp-card-title>
</swp-card-header>
<swp-card-content>
<swp-code-info>
<i class="ph ph-info"></i>
Denne kode indsættes automatisk i &lt;head&gt; på din online booking side
</swp-code-info>
<pre class="code-preview" id="trackingCodePreview"><code><!-- Ingen aktive tracking-koder --></code></pre>
</swp-card-content>
</swp-card>
</swp-tab-content>
<!-- ==========================================
DRAWER: REDIGER BESKED
========================================== -->
<swp-drawer-overlay id="drawerOverlay"></swp-drawer-overlay>
<swp-drawer id="messageDrawer">
<swp-drawer-header>
<swp-drawer-title>
<h3 id="drawerTitle">Bekræftelse</h3>
<span id="drawerSubtitle">SMS · Sendes ved booking</span>
</swp-drawer-title>
<swp-drawer-close id="drawerClose">
<i class="ph ph-x"></i>
</swp-drawer-close>
</swp-drawer-header>
<swp-drawer-body>
<swp-message-section>
<swp-message-section-title>Besked</swp-message-section-title>
<swp-message-editor contenteditable="true" id="messageEditor">Hej {kunde_navn}!
Din tid er bekræftet:
{behandling}
{dato} kl. {tid}
Hos {medarbejder}
{firma_navn}, {firma_adresse}
Vil du ændre din tid? {booking_link}</swp-message-editor>
</swp-message-section>
<swp-message-section>
<swp-message-section-title>Indsæt variabel</swp-message-section-title>
<swp-variables-grid id="smsVariablesGrid">
<swp-variable-tag data-var="{kunde_navn}"><i class="ph ph-user"></i> kunde_navn</swp-variable-tag>
<swp-variable-tag data-var="{behandling}"><i class="ph ph-scissors"></i> behandling</swp-variable-tag>
<swp-variable-tag data-var="{dato}"><i class="ph ph-calendar"></i> dato</swp-variable-tag>
<swp-variable-tag data-var="{tid}"><i class="ph ph-clock"></i> tid</swp-variable-tag>
<swp-variable-tag data-var="{medarbejder}"><i class="ph ph-user-circle"></i> medarbejder</swp-variable-tag>
<swp-variable-tag data-var="{firma_navn}"><i class="ph ph-buildings"></i> firma_navn</swp-variable-tag>
<swp-variable-tag data-var="{firma_adresse}"><i class="ph ph-map-pin"></i> firma_adresse</swp-variable-tag>
<swp-variable-tag data-var="{firma_tlf}"><i class="ph ph-phone"></i> firma_tlf</swp-variable-tag>
<swp-variable-tag data-var="{booking_link}"><i class="ph ph-link"></i> booking_link</swp-variable-tag>
</swp-variables-grid>
</swp-message-section>
<swp-message-section>
<swp-message-section-title>Forhåndsvisning</swp-message-section-title>
<swp-message-preview id="messagePreview">
Hej <span class="highlight" data-var="{kunde_navn}">Anna Jensen</span>!<br><br>
Din tid er bekræftet:<br>
<span class="highlight" data-var="{behandling}">Dameklip + Føn</span><br>
<span class="highlight" data-var="{dato}">Torsdag d. 2. januar</span> kl. <span class="highlight" data-var="{tid}">14:30</span><br><br>
Hos <span class="highlight" data-var="{medarbejder}">Maria</span><br>
<span class="highlight" data-var="{firma_navn}">KARINA KNUDSEN®</span>, <span class="highlight" data-var="{firma_adresse}">Hovedgaden 123</span><br><br>
Vil du ændre din tid? <span class="highlight" data-var="{booking_link}">book.plantempus.dk/x7k2</span>
</swp-message-preview>
<swp-preview-meta>
<span><i class="ph ph-chat-text"></i> 312 tegn</span>
<span><i class="ph ph-coin"></i> 2 SMS (0,98 kr.)</span>
</swp-preview-meta>
</swp-message-section>
</swp-drawer-body>
<swp-drawer-footer>
<swp-btn class="secondary" id="drawerCancel">Annuller</swp-btn>
<swp-btn class="primary" id="drawerSave">
<i class="ph ph-check"></i>
Gem besked
</swp-btn>
</swp-drawer-footer>
</swp-drawer>
<!-- ==========================================
DRAWER: EMAIL SKABELON (bred)
========================================== -->
<swp-drawer-overlay id="emailDrawerOverlay"></swp-drawer-overlay>
<swp-drawer class="wide" id="emailDrawer">
<swp-drawer-header>
<swp-drawer-title>
<h3 id="emailDrawerTitle">Bekræftelse</h3>
<span>Email · Sendes når en aftale er booket</span>
</swp-drawer-title>
<swp-drawer-close id="emailDrawerClose">
<i class="ph ph-x"></i>
</swp-drawer-close>
</swp-drawer-header>
<swp-drawer-body>
<swp-email-editor-layout>
<!-- Sidebar med felter -->
<swp-email-sidebar>
<swp-edit-section>
<swp-edit-row>
<swp-edit-label>Email emne</swp-edit-label>
<swp-edit-value contenteditable="true" id="emailSubject">Din tid hos KARINA KNUDSEN® er bekræftet</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Overskrift</swp-edit-label>
<swp-edit-value contenteditable="true" id="emailHeadline">Tid bekræftet!</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Velkomst</swp-edit-label>
<swp-edit-value contenteditable="true" id="emailGreeting">Hej {kunde_navn},</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Brødtekst</swp-edit-label>
<swp-edit-textarea contenteditable="true" id="emailBody">Vi glæder os til at se dig! Her er detaljerne for din aftale.</swp-edit-textarea>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Knap tekst</swp-edit-label>
<swp-edit-value contenteditable="true" id="emailButtonText">Se eller ændr din tid</swp-edit-value>
</swp-edit-row>
<swp-edit-row>
<swp-edit-label>Primær farve</swp-edit-label>
<swp-color-picker-row>
<input type="color" value="#00897b" id="emailColor">
<span id="emailColorValue">#00897b</span>
</swp-color-picker-row>
</swp-edit-row>
</swp-edit-section>
<swp-message-section>
<swp-message-section-title>Variabler</swp-message-section-title>
<swp-variables-grid>
<swp-variable-tag data-var="{kunde_navn}"><i class="ph ph-user"></i> kunde_navn</swp-variable-tag>
<swp-variable-tag data-var="{behandling}"><i class="ph ph-scissors"></i> behandling</swp-variable-tag>
<swp-variable-tag data-var="{dato}"><i class="ph ph-calendar"></i> dato</swp-variable-tag>
<swp-variable-tag data-var="{tid}"><i class="ph ph-clock"></i> tid</swp-variable-tag>
<swp-variable-tag data-var="{medarbejder}"><i class="ph ph-user-circle"></i> medarbejder</swp-variable-tag>
</swp-variables-grid>
</swp-message-section>
</swp-email-sidebar>
<!-- Live preview -->
<swp-email-preview-container>
<swp-email-preview>
<swp-email-header id="emailPreviewHeader">
<swp-email-logo>SB</swp-email-logo>
<h2 id="emailPreviewHeadline">Tid bekræftet!</h2>
<p>KARINA KNUDSEN®</p>
</swp-email-header>
<swp-email-body>
<swp-email-greeting id="emailPreviewGreeting">Hej <span class="editable" data-var="{kunde_navn}">Anna</span>,</swp-email-greeting>
<swp-email-text id="emailPreviewBody">Vi glæder os til at se dig! Her er detaljerne for din aftale.</swp-email-text>
<swp-email-appointment-card>
<swp-email-appointment-row>
<i class="ph ph-scissors"></i>
<span><strong class="editable" data-var="{behandling}">Dameklip + Føn</strong></span>
</swp-email-appointment-row>
<swp-email-appointment-row>
<i class="ph ph-calendar"></i>
<span><span class="editable" data-var="{dato}">Torsdag d. 2. januar 2025</span></span>
</swp-email-appointment-row>
<swp-email-appointment-row>
<i class="ph ph-clock"></i>
<span>Kl. <span class="editable" data-var="{tid}">14:30</span> <span class="editable" data-var="{tid}">15:15</span></span>
</swp-email-appointment-row>
<swp-email-appointment-row>
<i class="ph ph-user-circle"></i>
<span>Hos <strong class="editable" data-var="{medarbejder}">Maria</strong></span>
</swp-email-appointment-row>
<swp-email-appointment-row>
<i class="ph ph-map-pin"></i>
<span>Amager Strandvej 22f, 2300 København S</span>
</swp-email-appointment-row>
</swp-email-appointment-card>
<swp-email-button-container>
<swp-email-button id="emailPreviewButton">Se eller ændr din tid</swp-email-button>
</swp-email-button-container>
</swp-email-body>
<swp-email-footer>
<swp-email-footer-logo>KARINA KNUDSEN®</swp-email-footer-logo>
<p>Amager Strandvej 22f, 2300 København S</p>
<p>Tlf: 70 20 30 40 · <a href="#">info@salonbeauty.dk</a></p>
<p style="margin-top: 12px; font-size: 11px;">
<a href="#">Afmeld emails</a>
</p>
</swp-email-footer>
</swp-email-preview>
</swp-email-preview-container>
</swp-email-editor-layout>
</swp-drawer-body>
<swp-drawer-footer>
<swp-btn class="secondary" id="emailDrawerCancel">Annuller</swp-btn>
<swp-btn class="primary" id="emailDrawerSave">
<i class="ph ph-check"></i>
Gem skabelon
</swp-btn>
</swp-drawer-footer>
</swp-drawer>
<!-- Onboarding Popover -->
<div id="variablesHint" popover="manual">
<swp-onboarding-hint>
<i class="ph ph-lightbulb"></i>
<span>Klik for at indsætte, hold musen over for at se i preview</span>
<swp-hint-close><i class="ph ph-x"></i></swp-hint-close>
</swp-onboarding-hint>
</div>
<script>
// Tab switching
document.querySelectorAll('swp-tab').forEach(tab => {
tab.addEventListener('click', () => {
const tabName = tab.dataset.tab;
// Update active tab
document.querySelectorAll('swp-tab').forEach(t => t.classList.remove('active'));
tab.classList.add('active');
// Update active content
document.querySelectorAll('swp-tab-content').forEach(c => c.classList.remove('active'));
document.querySelector(`swp-tab-content[data-tab="${tabName}"]`).classList.add('active');
});
});
// Toggle slider functionality
document.querySelectorAll('swp-toggle-slider').forEach(slider => {
slider.querySelectorAll('swp-toggle-option').forEach((option, index) => {
option.addEventListener('click', () => {
slider.dataset.value = index === 0 ? 'yes' : 'no';
});
});
});
// Copy URL
document.querySelector('swp-url-copy')?.addEventListener('click', () => {
const input = document.querySelector('swp-url-field input');
navigator.clipboard.writeText(input.value);
alert('Link kopieret!');
});
// ==========================================
// SMS DRAWER
// ==========================================
const smsDrawer = document.getElementById('messageDrawer');
const smsOverlay = document.getElementById('drawerOverlay');
const smsTitle = document.getElementById('drawerTitle');
const smsSubtitle = document.getElementById('drawerSubtitle');
function openSmsDrawer(title, subtitle) {
smsTitle.textContent = title;
smsSubtitle.textContent = subtitle;
smsDrawer.classList.add('open');
smsOverlay.classList.add('open');
document.body.style.overflow = 'hidden';
// Show onboarding hint if not seen before
if (!localStorage.getItem('variablesHintSeen')) {
setTimeout(() => {
showVariablesHint();
}, 600);
}
}
function showVariablesHint() {
const hint = document.getElementById('variablesHint');
const anchor = document.getElementById('smsVariablesGrid');
if (!hint || !anchor) return;
const anchorRect = anchor.getBoundingClientRect();
hint.style.position = 'fixed';
hint.style.top = `${anchorRect.top - 60}px`;
hint.style.left = `${anchorRect.left - 80}px`;
hint.showPopover();
}
function hideVariablesHint() {
const hint = document.getElementById('variablesHint');
if (hint) {
hint.hidePopover();
localStorage.setItem('variablesHintSeen', 'true');
}
}
function closeSmsDrawer() {
smsDrawer.classList.remove('open');
smsOverlay.classList.remove('open');
document.body.style.overflow = '';
// Hide hint without marking as seen (will show again next time)
const hint = document.getElementById('variablesHint');
if (hint) {
try { hint.hidePopover(); } catch(e) {}
}
}
document.getElementById('drawerClose').addEventListener('click', closeSmsDrawer);
document.getElementById('drawerCancel').addEventListener('click', closeSmsDrawer);
smsOverlay.addEventListener('click', closeSmsDrawer);
document.getElementById('drawerSave').addEventListener('click', closeSmsDrawer);
// ==========================================
// EMAIL DRAWER
// ==========================================
const emailDrawer = document.getElementById('emailDrawer');
const emailOverlay = document.getElementById('emailDrawerOverlay');
const emailTitle = document.getElementById('emailDrawerTitle');
function openEmailDrawer(title) {
emailTitle.textContent = title;
emailDrawer.classList.add('open');
emailOverlay.classList.add('open');
document.body.style.overflow = 'hidden';
}
function closeEmailDrawer() {
emailDrawer.classList.remove('open');
emailOverlay.classList.remove('open');
document.body.style.overflow = '';
}
document.getElementById('emailDrawerClose').addEventListener('click', closeEmailDrawer);
document.getElementById('emailDrawerCancel').addEventListener('click', closeEmailDrawer);
emailOverlay.addEventListener('click', closeEmailDrawer);
document.getElementById('emailDrawerSave').addEventListener('click', closeEmailDrawer);
// ==========================================
// OPEN CORRECT DRAWER
// ==========================================
document.querySelectorAll('swp-edit-link').forEach(link => {
link.addEventListener('click', () => {
const item = link.closest('swp-notification-item');
const titleEl = item?.querySelector('swp-notification-title');
const title = titleEl?.childNodes[0]?.textContent.trim() || 'Besked';
const card = link.closest('swp-card');
const isEmail = card?.querySelector('swp-card-title')?.textContent.includes('Email');
const desc = item?.querySelector('swp-notification-desc')?.textContent || '';
if (isEmail) {
openEmailDrawer(title);
} else {
openSmsDrawer(title, `SMS · ${desc}`);
}
});
});
// ==========================================
// EMAIL LIVE PREVIEW
// ==========================================
const emailHeadline = document.getElementById('emailHeadline');
const emailBody = document.getElementById('emailBody');
const emailButtonText = document.getElementById('emailButtonText');
const emailColor = document.getElementById('emailColor');
const emailColorValue = document.getElementById('emailColorValue');
// Update headline (contenteditable)
emailHeadline?.addEventListener('input', () => {
document.getElementById('emailPreviewHeadline').textContent = emailHeadline.textContent;
});
// Update body text (contenteditable)
emailBody?.addEventListener('input', () => {
document.getElementById('emailPreviewBody').textContent = emailBody.textContent;
});
// Update button text (contenteditable)
emailButtonText?.addEventListener('input', () => {
document.getElementById('emailPreviewButton').textContent = emailButtonText.textContent;
});
// Update color
emailColor?.addEventListener('input', (e) => {
const color = e.target.value;
emailColorValue.textContent = color;
const header = document.getElementById('emailPreviewHeader');
header.style.background = `linear-gradient(135deg, ${color} 0%, ${adjustColor(color, -20)} 100%)`;
document.getElementById('emailPreviewButton').style.background = color;
document.querySelectorAll('swp-email-appointment-row i').forEach(icon => {
icon.style.color = color;
});
document.querySelector('swp-email-appointment-card').style.borderLeftColor = color;
// Update logo color
document.querySelector('swp-email-logo').style.color = color;
});
function adjustColor(hex, amount) {
const num = parseInt(hex.slice(1), 16);
const r = Math.max(0, Math.min(255, (num >> 16) + amount));
const g = Math.max(0, Math.min(255, ((num >> 8) & 0x00FF) + amount));
const b = Math.max(0, Math.min(255, (num & 0x0000FF) + amount));
return `#${(1 << 24 | r << 16 | g << 8 | b).toString(16).slice(1)}`;
}
// ==========================================
// INSERT VARIABLE (SMS)
// ==========================================
document.querySelectorAll('#messageDrawer swp-variable-tag').forEach(tag => {
tag.addEventListener('click', () => {
const varText = tag.dataset.var;
const editor = document.getElementById('messageEditor');
// Dismiss onboarding hint on first click
hideVariablesHint();
const selection = window.getSelection();
if (selection.rangeCount > 0) {
const range = selection.getRangeAt(0);
if (editor.contains(range.commonAncestorContainer)) {
range.deleteContents();
range.insertNode(document.createTextNode(varText));
range.collapse(false);
return;
}
}
editor.textContent += varText;
});
// Highlight preview on hover
tag.addEventListener('mouseenter', () => {
const varName = tag.dataset.var;
const preview = document.getElementById('messagePreview');
preview.querySelectorAll(`.highlight[data-var="${varName}"]`).forEach(span => {
span.classList.add('active');
});
});
tag.addEventListener('mouseleave', () => {
const preview = document.getElementById('messagePreview');
preview.querySelectorAll('.highlight.active').forEach(span => {
span.classList.remove('active');
});
});
});
// ==========================================
// HIGHLIGHT EMAIL PREVIEW ON HOVER
// ==========================================
document.querySelectorAll('#emailDrawer swp-variable-tag').forEach(tag => {
tag.addEventListener('mouseenter', () => {
const varName = tag.dataset.var;
const preview = document.querySelector('swp-email-preview');
preview.querySelectorAll(`.editable[data-var="${varName}"]`).forEach(span => {
span.classList.add('active');
});
});
tag.addEventListener('mouseleave', () => {
const preview = document.querySelector('swp-email-preview');
preview.querySelectorAll('.editable.active').forEach(span => {
span.classList.remove('active');
});
});
});
// ==========================================
// ONBOARDING HINT CLOSE
// ==========================================
document.querySelectorAll('swp-hint-close').forEach(closeBtn => {
closeBtn.addEventListener('click', () => {
hideVariablesHint();
});
});
// ==========================================
// ESCAPE KEY
// ==========================================
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
if (smsDrawer.classList.contains('open')) closeSmsDrawer();
if (emailDrawer.classList.contains('open')) closeEmailDrawer();
}
});
// ==========================================
// ONLINE PAYMENT TOGGLE
// ==========================================
const onlinePaymentToggle = document.getElementById('onlinePaymentToggle');
const onlinePaymentSettings = document.getElementById('onlinePaymentSettings');
function updateOnlinePaymentVisibility() {
if (onlinePaymentToggle && onlinePaymentSettings) {
const isEnabled = onlinePaymentToggle.dataset.value === 'yes';
onlinePaymentSettings.style.display = isEnabled ? 'block' : 'none';
}
}
if (onlinePaymentToggle) {
onlinePaymentToggle.querySelectorAll('swp-toggle-option').forEach((option, index) => {
option.addEventListener('click', () => {
onlinePaymentToggle.dataset.value = index === 0 ? 'yes' : 'no';
updateOnlinePaymentVisibility();
});
});
// Initial state
updateOnlinePaymentVisibility();
}
// ==========================================
// TRACKING TAB
// ==========================================
function initTrackingToggles() {
document.querySelectorAll('.tracking-card swp-toggle-slider').forEach(slider => {
slider.querySelectorAll('swp-toggle-option').forEach((option, index) => {
option.addEventListener('click', () => {
slider.dataset.value = index === 0 ? 'yes' : 'no';
const card = slider.closest('.tracking-card');
if (slider.dataset.value === 'no') {
card.classList.add('disabled');
} else {
card.classList.remove('disabled');
}
updateTrackingPreview();
});
});
});
}
function updateTrackingPreview() {
const preview = document.getElementById('trackingCodePreview');
if (!preview) return;
let code = '';
// Meta Pixel
const metaCard = document.querySelector('[data-tracker="meta"]');
if (metaCard && metaCard.querySelector('swp-toggle-slider').dataset.value === 'yes') {
const pixelId = document.getElementById('metaPixelId')?.textContent?.trim() || '';
if (pixelId) {
code += `<span class="comment">&lt;!-- Meta Pixel --&gt;</span>
<span class="tag">&lt;script&gt;</span>
!function(f,b,e,v,n,t,s)
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];
s.parentNode.insertBefore(t,s)}(window, document,'script',
'https://connect.facebook.net/en_US/fbevents.js');
fbq(<span class="string">'init'</span>, <span class="string">'${pixelId}'</span>);
fbq(<span class="string">'track'</span>, <span class="string">'PageView'</span>);
<span class="tag">&lt;/script&gt;</span>
`;
}
}
// Google Analytics
const ga4Card = document.querySelector('[data-tracker="ga4"]');
if (ga4Card && ga4Card.querySelector('swp-toggle-slider').dataset.value === 'yes') {
const measurementId = document.getElementById('ga4Id')?.textContent?.trim() || '';
if (measurementId) {
code += `<span class="comment">&lt;!-- Google Analytics (GA4) --&gt;</span>
<span class="tag">&lt;script</span> <span class="attr">async</span> <span class="attr">src</span>=<span class="string">"https://www.googletagmanager.com/gtag/js?id=${measurementId}"</span><span class="tag">&gt;&lt;/script&gt;</span>
<span class="tag">&lt;script&gt;</span>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag(<span class="string">'js'</span>, new Date());
gtag(<span class="string">'config'</span>, <span class="string">'${measurementId}'</span>);
<span class="tag">&lt;/script&gt;</span>
`;
}
}
// Google Tag Manager
const gtmCard = document.querySelector('[data-tracker="gtm"]');
if (gtmCard && gtmCard.querySelector('swp-toggle-slider').dataset.value === 'yes') {
const containerId = document.getElementById('gtmId')?.textContent?.trim() || '';
if (containerId) {
code += `<span class="comment">&lt;!-- Google Tag Manager --&gt;</span>
<span class="tag">&lt;script&gt;</span>
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer',<span class="string">'${containerId}'</span>);
<span class="tag">&lt;/script&gt;</span>
`;
}
}
// Plausible
const plausibleCard = document.querySelector('[data-tracker="plausible"]');
if (plausibleCard && plausibleCard.querySelector('swp-toggle-slider').dataset.value === 'yes') {
const domain = document.getElementById('plausibleDomain')?.textContent?.trim() || '';
if (domain) {
code += `<span class="comment">&lt;!-- Plausible Analytics --&gt;</span>
<span class="tag">&lt;script</span> <span class="attr">defer</span> <span class="attr">data-domain</span>=<span class="string">"${domain}"</span> <span class="attr">src</span>=<span class="string">"https://plausible.io/js/script.js"</span><span class="tag">&gt;&lt;/script&gt;</span>
`;
}
}
// Fathom
const fathomCard = document.querySelector('[data-tracker="fathom"]');
if (fathomCard && fathomCard.querySelector('swp-toggle-slider').dataset.value === 'yes') {
const siteId = document.getElementById('fathomSiteId')?.textContent?.trim() || '';
if (siteId) {
code += `<span class="comment">&lt;!-- Fathom Analytics --&gt;</span>
<span class="tag">&lt;script</span> <span class="attr">src</span>=<span class="string">"https://cdn.usefathom.com/script.js"</span> <span class="attr">data-site</span>=<span class="string">"${siteId}"</span> <span class="attr">defer</span><span class="tag">&gt;&lt;/script&gt;</span>
`;
}
}
// Matomo
const matomoCard = document.querySelector('[data-tracker="matomo"]');
if (matomoCard && matomoCard.querySelector('swp-toggle-slider').dataset.value === 'yes') {
const serverUrl = document.getElementById('matomoUrl')?.textContent?.trim() || '';
const siteId = document.getElementById('matomoSiteId')?.textContent?.trim() || '';
if (serverUrl && siteId) {
code += `<span class="comment">&lt;!-- Matomo Analytics --&gt;</span>
<span class="tag">&lt;script&gt;</span>
var _paq = window._paq = window._paq || [];
_paq.push([<span class="string">'trackPageView'</span>]);
_paq.push([<span class="string">'enableLinkTracking'</span>]);
(function() {
var u=<span class="string">"${serverUrl}/"</span>;
_paq.push([<span class="string">'setTrackerUrl'</span>, u+<span class="string">'matomo.php'</span>]);
_paq.push([<span class="string">'setSiteId'</span>, <span class="string">'${siteId}'</span>]);
var d=document, g=d.createElement(<span class="string">'script'</span>), s=d.getElementsByTagName(<span class="string">'script'</span>)[0];
g.async=true; g.src=u+<span class="string">'matomo.js'</span>; s.parentNode.insertBefore(g,s);
})();
<span class="tag">&lt;/script&gt;</span>
`;
}
}
// Custom Head Scripts
const customHead = document.getElementById('customHeadScripts')?.value?.trim() || '';
if (customHead) {
code += `<span class="comment">&lt;!-- Custom Scripts --&gt;</span>
${escapeHtml(customHead)}
`;
}
if (code) {
preview.querySelector('code').innerHTML = code.trim();
} else {
preview.querySelector('code').innerHTML = '<span class="comment">&lt;!-- Ingen aktive tracking-koder --&gt;</span>';
}
}
function escapeHtml(text) {
return text
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
}
function copyTrackingCode() {
const preview = document.getElementById('trackingCodePreview');
if (!preview) return;
// Get plain text version (strip HTML tags)
const code = preview.querySelector('code').innerHTML
.replace(/<span[^>]*>/g, '')
.replace(/<\/span>/g, '')
.replace(/&lt;/g, '<')
.replace(/&gt;/g, '>')
.replace(/&amp;/g, '&');
navigator.clipboard.writeText(code).then(() => {
const btn = document.querySelector('.code-preview-card swp-btn');
const originalText = btn.innerHTML;
btn.innerHTML = '<i class="ph ph-check"></i> Kopieret!';
btn.style.color = 'var(--color-green)';
setTimeout(() => {
btn.innerHTML = originalText;
btn.style.color = '';
}, 2000);
});
}
// Initialize tracking preview on page load
document.addEventListener('DOMContentLoaded', () => {
// Initialize tracking toggles
initTrackingToggles();
// Update preview
updateTrackingPreview();
// Set initial disabled state for cards
document.querySelectorAll('.tracking-card[data-tracker]').forEach(card => {
const toggle = card.querySelector('swp-toggle-slider');
if (toggle && toggle.dataset.value === 'no') {
card.classList.add('disabled');
}
});
});
</script>
</body>
</html>