/* Contractor Manager Pro - Main Stylesheet */

/* === CSS Reset & Base Styles === */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/*
 * === THEME TOKENS ===
 *
 * Every colour in the app resolves through one of these tokens. The dashboards
 * render with inline styles, so a `dark:` utility class was never an option -
 * instead the JS was swept so that each hardcoded colour became the semantic
 * token below, and the theme is switched by flipping the values here.
 *
 * <html data-theme="light|dark"> is written by public/js/utils/theme.js (and by
 * a small inline copy in index.html that runs before first paint). The user's
 * chosen MODE - system, light or dark - lives in data-theme-mode.
 *
 * 🔴 If you add a colour anywhere, add it as a token here with BOTH a light and
 * a dark value. Never put a raw hex in a dashboard style string again.
 */
:root {
    color-scheme: light;

    /* Brand solids. These deliberately hold the SAME value in both themes:
     * they are badge/button backgrounds that carry white text, and they still
     * read acceptably as text on a dark page. */
    --primary-color: #2563eb;
    --secondary-color: #64748b;
    --success-color: #10b981;
    --warning-color: #f59e0b;
    --danger-color: #ef4444;
    --info-color: #3b82f6;
    --purple-color: #6f42c1;
    --neutral-color: #6c757d;

    /* Brand colours used as TEXT on a page/card background. A solid that works
     * behind white text is usually too dark to read on a dark surface, so these
     * lighten in dark mode while the solids above do not. */
    --primary-text: #2563eb;
    --success-text: #15803d;
    --warning-text: #b45309;
    --danger-text: #dc2626;
    --info-text: #1565c0;
    --purple-text: #7b1fa2;

    /* Surfaces, from the top of the stack downwards. */
    --surface: #ffffff;          /* cards, modals, headers, table rows */
    --surface-alt: #f9fafb;      /* zebra striping, nested panels */
    --surface-sunken: #f8f9fa;   /* inset areas, table headers */
    --surface-muted: #f5f5f5;    /* muted chips, inactive states */
    --surface-hover: #e5e5e5;    /* row and control hover */
    --page-bg: #f8fafc;          /* the page behind everything */

    /* Legacy aliases kept because older code still references them. */
    --bg-primary: var(--surface);
    --bg-secondary: var(--surface-sunken);
    --bg-color: var(--surface-sunken);

    /* Borders */
    --border-color: #e2e8f0;
    --border-strong: #cbd5e1;
    --border-subtle: #eeeeee;

    /* Text */
    --text-primary: #1e293b;
    --text-secondary: #64748b;
    --text-muted: #94a3b8;
    --text-on-solid: #ffffff;

    /* Tinted alert / badge blocks: a soft background with matching text and
     * border. In dark mode the background becomes a deep shade of the same hue
     * and the text becomes a light one, so the pairing stays legible. */
    --tint-info-bg: #e3f2fd;
    --tint-info-fg: #1565c0;
    --tint-info-border: #90caf9;

    --tint-warn-bg: #fff3cd;
    --tint-warn-fg: #856404;
    --tint-warn-border: #ffe69c;

    --tint-danger-bg: #f8d7da;
    --tint-danger-fg: #721c24;
    --tint-danger-border: #f5c6cb;

    --tint-success-bg: #d4edda;
    --tint-success-fg: #155724;
    --tint-success-border: #c3e6cb;

    --tint-purple-bg: #f3e5f5;
    --tint-purple-fg: #7b1fa2;
    --tint-purple-border: #e1bee7;

    --tint-neutral-bg: #f8f9fa;
    --tint-neutral-fg: #41464b;
    --tint-neutral-border: #e2e3e5;

    /* Compliance Status Colors */
    --status-compliant: var(--success-color);
    --status-warning: var(--warning-color);
    --status-non-compliant: var(--danger-color);

    /* Spacing */
    --spacing-xs: 0.25rem;
    --spacing-sm: 0.5rem;
    --spacing-md: 1rem;
    --spacing-lg: 1.5rem;
    --spacing-xl: 2rem;

    /* Typography */
    --font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    --font-size-sm: 0.875rem;
    --font-size-base: 1rem;
    --font-size-lg: 1.125rem;
    --font-size-xl: 1.25rem;
    --font-size-2xl: 1.5rem;

    /* Shadows. Dark mode needs deeper shadows because a translucent black
     * shadow all but disappears against a dark surface. */
    --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
    --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
    --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);

    /* The plate that sits behind a single-version logo in dark mode. */
    --logo-plate-bg: transparent;
    --logo-plate-padding: 0;
    --logo-plate-radius: 0;
}

:root[data-theme="dark"] {
    color-scheme: dark;

    --primary-text: #93b8fc;
    --success-text: #6ee7a8;
    --warning-text: #f5c168;
    --danger-text: #f8a5a5;
    --info-text: #8ec5f5;
    --purple-text: #d3a9ee;

    --surface: #1e293b;
    --surface-alt: #233045;
    --surface-sunken: #172033;
    --surface-muted: #273449;
    --surface-hover: #35455f;
    --page-bg: #0f172a;

    --border-color: #334155;
    --border-strong: #475569;
    --border-subtle: #2a3852;

    --text-primary: #e2e8f0;
    --text-secondary: #94a3b8;
    --text-muted: #7d8ca3;

    --tint-info-bg: #16304d;
    --tint-info-fg: #8ec5f5;
    --tint-info-border: #2f5f8f;

    --tint-warn-bg: #3b2f14;
    --tint-warn-fg: #f0c96e;
    --tint-warn-border: #6d5622;

    --tint-danger-bg: #43201f;
    --tint-danger-fg: #f4a6a6;
    --tint-danger-border: #7d3538;

    --tint-success-bg: #16331e;
    --tint-success-fg: #7fdca0;
    --tint-success-border: #2e6240;

    --tint-purple-bg: #2c2040;
    --tint-purple-fg: #d3a9ee;
    --tint-purple-border: #4f3c6b;

    --tint-neutral-bg: #202d42;
    --tint-neutral-fg: #cbd5e1;
    --tint-neutral-border: #37455d;

    --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.4);
    --shadow-md: 0 4px 10px -1px rgb(0 0 0 / 0.5);
    --shadow-lg: 0 12px 28px -6px rgb(0 0 0 / 0.6);

    --logo-plate-bg: #ffffff;
    --logo-plate-padding: 6px 10px;
    --logo-plate-radius: 6px;
}

/*
 * No-JS / pre-boot fallback: if data-theme has not been written for any reason,
 * still honour the operating system preference rather than forcing light.
 * theme.js normally sets the attribute before first paint, so this rarely runs.
 */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme]) {
        color-scheme: dark;

        --primary-text: #93b8fc;
        --success-text: #6ee7a8;
        --warning-text: #f5c168;
        --danger-text: #f8a5a5;
        --info-text: #8ec5f5;
        --purple-text: #d3a9ee;

        --surface: #1e293b;
        --surface-alt: #233045;
        --surface-sunken: #172033;
        --surface-muted: #273449;
        --surface-hover: #35455f;
        --page-bg: #0f172a;

        --border-color: #334155;
        --border-strong: #475569;
        --border-subtle: #2a3852;

        --text-primary: #e2e8f0;
        --text-secondary: #94a3b8;
        --text-muted: #7d8ca3;

        --tint-info-bg: #16304d;
        --tint-info-fg: #8ec5f5;
        --tint-info-border: #2f5f8f;

        --tint-warn-bg: #3b2f14;
        --tint-warn-fg: #f0c96e;
        --tint-warn-border: #6d5622;

        --tint-danger-bg: #43201f;
        --tint-danger-fg: #f4a6a6;
        --tint-danger-border: #7d3538;

        --tint-success-bg: #16331e;
        --tint-success-fg: #7fdca0;
        --tint-success-border: #2e6240;

        --tint-purple-bg: #2c2040;
        --tint-purple-fg: #d3a9ee;
        --tint-purple-border: #4f3c6b;

        --tint-neutral-bg: #202d42;
        --tint-neutral-fg: #cbd5e1;
        --tint-neutral-border: #37455d;

        --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.4);
        --shadow-md: 0 4px 10px -1px rgb(0 0 0 / 0.5);
        --shadow-lg: 0 12px 28px -6px rgb(0 0 0 / 0.6);

        --logo-plate-bg: #ffffff;
        --logo-plate-padding: 6px 10px;
        --logo-plate-radius: 6px;
    }
}

body {
    font-family: var(--font-family);
    font-size: var(--font-size-base);
    color: var(--text-primary);
    background-color: var(--page-bg);
    line-height: 1.6;
}

/* Form controls do not inherit the document font, and without an explicit
 * background they ignore the theme in some browsers. Both are set here so no
 * control ever falls back to a serif face or a white-on-white field. */
button,
input,
select,
textarea {
    font-family: inherit;
    font-size: inherit;
}

input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
select,
textarea {
    background-color: var(--surface);
    color: var(--text-primary);
    border-color: var(--border-color);
}

input::placeholder,
textarea::placeholder {
    color: var(--text-muted);
    opacity: 1;
}

/* Native pickers (date, time) render their indicator dark-on-dark otherwise. */
:root[data-theme="dark"] input::-webkit-calendar-picker-indicator {
    filter: invert(1) brightness(1.6);
}

hr {
    border: none;
    border-top: 1px solid var(--border-color);
}

a {
    color: var(--primary-text);
}

/* === Loading State === */
/*
 * The loading element is reused for the initial app boot AND for the in-flight
 * spinner shown during long ops (cert uploads etc.). Two states:
 *
 *   1. Boot mode (default class .loading-container only): full-viewport centered
 *      "Contractor Manager Pro / Loading..." screen used while app.js initialises.
 *   2. In-flight mode (.loading-container.loading-inflight): a small corner toast
 *      with a spinning circle and message. pointer-events: none so any modal
 *      that opens during the operation (e.g. the supersede prompt) is still
 *      visible and interactive — the toast doesn't block clicks underneath.
 *
 * Utils.showLoading() adds the .loading-inflight class; hideLoading() removes
 * it. The boot screen is the natural state on first paint.
 */
.loading-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    text-align: center;
}

.loading-container h1 {
    font-size: var(--font-size-2xl);
    margin-bottom: var(--spacing-md);
    color: var(--primary-text);
}

.loading-container p {
    font-size: 16px;
    font-weight: 500;
    color: var(--text-primary);
    margin: 0;
}

/* In-flight spinner: small fixed corner toast that does not block input.
 * Semi-transparent with a backdrop blur so the screen behind stays visible —
 * a fully opaque toast made it feel like the page was being covered. */
.loading-container.loading-inflight {
    position: fixed;
    bottom: 24px;
    right: 24px;
    min-height: 0;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 10px;
    padding: 10px 14px;
    background: color-mix(in srgb, var(--surface) 78%, transparent);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    box-shadow: var(--shadow-lg);
    z-index: 100000;
    max-width: 320px;
    pointer-events: none; /* clicks pass through to whatever's underneath */
    text-align: left;
}

.loading-container.loading-inflight p {
    font-size: 14px;
    line-height: 1.3;
}

.loading-container.loading-inflight::before {
    content: "";
    flex-shrink: 0;
    width: 22px;
    height: 22px;
    margin: 0;
    border: 3px solid var(--border-color);
    border-top-color: var(--primary-color);
    border-radius: 50%;
    animation: cmpro-spin 0.9s linear infinite;
}

@keyframes cmpro-spin {
    to { transform: rotate(360deg); }
}

/* === Utility Classes === */
.hidden {
    display: none !important;
}

.text-success {
    color: var(--success-text);
}

.text-warning {
    color: var(--warning-text);
}

.text-danger {
    color: var(--danger-text);
}

.bg-success {
    background-color: var(--success-color);
}

.bg-warning {
    background-color: var(--warning-color);
}

.bg-danger {
    background-color: var(--danger-color);
}

/* === Container & Layout === */
.container {
    max-width: 1280px;
    margin: 0 auto;
    padding: 0 var(--spacing-md);
}

/* === Responsive Design === */
@media (max-width: 768px) {
    :root {
        --font-size-base: 0.875rem;
        --font-size-lg: 1rem;
        --font-size-xl: 1.125rem;
        --font-size-2xl: 1.25rem;
    }
}

/* === Component Styles (to be expanded) === */

/* Buttons.
 *
 * A bare .btn used to have no background and no border, so it read as plain
 * text - invisible as a control, and unreadable once the header went dark. It
 * is now a proper secondary/outline button. Buttons that set their own
 * background inline (the coloured action buttons) are unaffected, because an
 * inline style beats a class rule. */
.btn {
    display: inline-block;
    padding: var(--spacing-sm) var(--spacing-lg);
    border: 1px solid var(--border-strong);
    border-radius: 0.375rem;
    background-color: var(--surface);
    color: var(--text-primary);
    font-size: var(--font-size-base);
    font-weight: 500;
    cursor: pointer;
    transition: background-color 0.2s, border-color 0.2s, opacity 0.2s;
}

.btn:hover {
    background-color: var(--surface-hover);
}

.btn-primary {
    background-color: var(--primary-color);
    border-color: var(--primary-color);
    color: var(--text-on-solid);
}

.btn-primary:hover {
    background-color: var(--primary-color);
    opacity: 0.9;
}

/* Cards */
.card {
    background-color: var(--surface);
    border-radius: 0.5rem;
    box-shadow: var(--shadow-md);
    padding: var(--spacing-lg);
    color: var(--text-primary);
}

/* Dropdown Menu */
.dropdown {
    position: relative;
    display: inline-block;
}

.dropdown-button {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: var(--spacing-sm) var(--spacing-lg);
    background-color: var(--surface);
    color: var(--text-primary);
    border: 1px solid var(--border-color);
    border-radius: 0.375rem;
    font-size: var(--font-size-base);
    font-weight: 500;
    cursor: pointer;
    transition: all 0.2s;
}

.dropdown-button:hover {
    background-color: var(--surface-hover);
}

.dropdown-content {
    display: none;
    position: absolute;
    right: 0;
    top: 100%;
    margin-top: 0.5rem;
    min-width: 280px;
    background-color: var(--surface);
    border: 1px solid var(--border-color);
    border-radius: 0.5rem;
    box-shadow: var(--shadow-lg);
    z-index: 1000;
    max-height: 400px;
    overflow-y: auto;
}

.dropdown-content.show {
    display: block;
}

.dropdown-item {
    padding: 12px 16px;
    cursor: pointer;
    transition: background-color 0.2s;
    border-bottom: 1px solid var(--border-color);
    color: var(--text-primary);
}

.dropdown-item:last-child {
    border-bottom: none;
}

.dropdown-item:hover {
    background-color: var(--surface-hover);
}

.dropdown-item-title {
    font-weight: 500;
    margin-bottom: 4px;
    color: var(--text-primary);
}

.dropdown-item-subtitle {
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
}

.dropdown-divider {
    height: 1px;
    background-color: var(--border-color);
    margin: 0.5rem 0;
}

/* === Theme selector ===
 *
 * A three-way segmented control: Default (follow the system) / Light / Dark.
 * Rendered by CMTheme.renderSelector() into the right-hand side of every
 * dashboard header, and floated top-right on the login and signup screens.
 * The labels collapse to icons on narrow screens so the header does not wrap.
 */
.theme-seg {
    display: inline-flex;
    align-items: stretch;
    gap: 2px;
    padding: 2px;
    background-color: var(--surface-sunken);
    border: 1px solid var(--border-color);
    border-radius: 8px;
}

.theme-seg-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 10px;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: var(--text-secondary);
    font-size: 13px;
    font-weight: 500;
    line-height: 1;
    cursor: pointer;
    transition: background-color 0.15s, color 0.15s;
}

.theme-seg-btn:hover {
    background-color: var(--surface-hover);
    color: var(--text-primary);
}

.theme-seg-btn.is-active {
    background-color: var(--surface);
    color: var(--primary-text);
    box-shadow: var(--shadow-sm);
}

.theme-seg-btn:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 1px;
}

.theme-seg-icon {
    width: 15px;
    height: 15px;
    flex-shrink: 0;
}

.theme-seg-compact .theme-seg-label {
    display: none;
}

.theme-seg-compact .theme-seg-btn {
    padding: 6px 8px;
}

/* Below the point where a header would start wrapping, drop to icons only. */
@media (max-width: 900px) {
    .theme-seg .theme-seg-label {
        display: none;
    }

    .theme-seg .theme-seg-btn {
        padding: 6px 8px;
    }
}

/* Floating selector for the screens that have no header (login, signup). */
.theme-seg-floating {
    position: fixed;
    top: 16px;
    right: 16px;
    z-index: 900;
}

/* === Organisation logo ===
 *
 * Organisations may upload a normal logo and a dark-background ("white") logo.
 * Most have only the first, which is usually dark artwork on a transparent
 * background and therefore invisible against a dark header. So:
 *
 *   - both versions uploaded  -> show whichever suits the active theme
 *   - only the normal version -> keep it, but sit it on a white plate in dark
 *                                mode so it stays legible
 *
 * The swap is done in CSS rather than JS so it survives a theme change without
 * anything having to re-render.
 */
.brand-logo {
    display: inline-flex;
    align-items: center;
}

.brand-logo img {
    display: block;
}

/* Two classes so these out-specify `.brand-logo img` above - otherwise both
 * versions of the logo render at once, one on top of the other. */
.brand-logo .brand-logo-dark {
    display: none;
}

:root[data-theme="dark"] .brand-logo .brand-logo-light {
    display: none;
}

:root[data-theme="dark"] .brand-logo .brand-logo-dark {
    display: block;
}

.brand-logo-plated {
    background-color: var(--logo-plate-bg);
    padding: var(--logo-plate-padding);
    border-radius: var(--logo-plate-radius);
    transition: background-color 0.2s, padding 0.2s;
}

/* More styles to be added as components are developed */
