/* ═══════════════════════════════════════════════════════════════════
   Axe CRM — Glass Morphism Design System
   Frosted glass surfaces, subtle gradients, bold data-viz accents.
   Base: Plus Jakarta Sans font, custom layout (no framework).
   ═══════════════════════════════════════════════════════════════════ */

/* ── Reset & Base ────────────────────────────────────────────────── */

*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

:root {
    --color-bg: rgba(255, 255, 255, 0.72);
    --color-bg-solid: #ffffff;
    --color-bg-subtle: rgba(247, 248, 252, 0.65);
    --color-bg-hover: rgba(0, 0, 0, 0.04);
    --color-bg-toolbar: rgba(255, 255, 255, 0.55);
    --color-text: #1a1a2e;
    --color-text-secondary: #5a607a;
    --color-text-muted: #8b90a8;
    --color-border: rgba(0, 0, 0, 0.08);
    --color-border-subtle: rgba(0, 0, 0, 0.04);

    /* McCandless accent palette — bold, vibrant data-viz colours */
    --color-coral: #ff6b6b;
    --color-teal: #18b5a4;
    --color-gold: #f0a500;
    --color-orange: #ff8c42;
    --color-blue: #4a90d9;
    --color-purple: #9b59b6;

    --color-primary: var(--color-teal);
    --color-primary-hover: #14a090;

    /* Glass properties */
    --glass-blur: 20px;
    --glass-bg: rgba(255, 255, 255, 0.55);
    --glass-bg-strong: rgba(255, 255, 255, 0.78);
    --glass-border: rgba(255, 255, 255, 0.35);

    --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04);
    --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.07), 0 1px 3px rgba(0, 0, 0, 0.04);
    --shadow-lg: 0 12px 40px rgba(0, 0, 0, 0.10), 0 4px 12px rgba(0, 0, 0, 0.05);
    --shadow-glow: 0 0 40px rgba(24, 181, 164, 0.12);

    --radius-sm: 8px;
    --radius-md: 12px;
    --radius-lg: 16px;

    --sidebar-width: 210px;

    --font-sans: 'Plus Jakarta Sans', system-ui, -apple-system, sans-serif;
}

html {
    font-size: 15px;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

body {
    font-family: var(--font-sans);
    color: var(--color-text);
    background: #eef0f6;
    background-image:
        radial-gradient(ellipse at 15% 10%, rgba(24, 181, 164, 0.10) 0%, transparent 50%),
        radial-gradient(ellipse at 85% 80%, rgba(74, 144, 217, 0.08) 0%, transparent 50%),
        radial-gradient(ellipse at 50% 50%, rgba(255, 107, 107, 0.04) 0%, transparent 60%);
    background-attachment: fixed;
    line-height: 1.6;
    min-height: 100vh;
}

h1, h2, h3, h4 {
    line-height: 1.3;
    font-weight: 600;
}

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

a:hover {
    text-decoration: underline;
}

/* ── Login Screen ────────────────────────────────────────────────── */

.gsection-login-logo img {
    max-width: 320px;
    height: auto;
}

.login-container {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
}

.login-card {
    background: var(--glass-bg-strong);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg), var(--shadow-glow);
    padding: 3rem;
    width: 100%;
    max-width: 400px;
    text-align: center;
}

.login-title {
    font-size: 2.4rem;
    font-weight: 700;
    letter-spacing: -0.03em;
    color: var(--color-text);
    margin-bottom: 0.25rem;
}

.login-subtitle {
    color: var(--color-text-secondary);
    margin-bottom: 2rem;
    font-size: 0.95rem;
}

/* ── App Layout ──────────────────────────────────────────────────── */

.app-layout {
    display: flex;
    min-height: 100vh;
}

/* ── Sidebar ─────────────────────────────────────────────────────── */

.sidebar {
    background: rgba(22, 25, 38, 0.88);
    backdrop-filter: blur(24px) saturate(1.4);
    -webkit-backdrop-filter: blur(24px) saturate(1.4);
    border-right: 1px solid rgba(255, 255, 255, 0.06);
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: var(--sidebar-width);
    z-index: 10;
}

.sidebar-brand {
    padding: 8px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
    display: flex;
    align-items: center;
    justify-content: center;
    background: #ffffff;
}

.brand-logo {
    display: block;
}

.sidebar-nav {
    list-style: none;
    padding: 0.5rem 0.5rem;
    flex: 1;
}

.sidebar-nav li {
    margin-bottom: 1px;
}

.sidebar-nav a {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.28rem 0.55rem;
    border-radius: var(--radius-sm);
    color: rgba(255, 255, 255, 0.55);
    font-weight: 500;
    font-size: 0.9rem;
    transition: background 0.2s, color 0.2s;
    text-decoration: none;
}

.sidebar-nav a:hover {
    background: rgba(255, 255, 255, 0.08);
    color: rgba(255, 255, 255, 0.9);
    text-decoration: none;
}

.sidebar-nav a.active {
    background: var(--color-primary);
    color: #ffffff;
    box-shadow: 0 2px 12px rgba(24, 181, 164, 0.35);
}

.nav-icon {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
}

/* Attention badge on a sidebar item (outstanding W1/W5 step) — pushed to the right edge, bright amber on the dark rail. */
.nav-warning {
    margin-left: auto;
    color: #fbbf24;
    font-size: 0.95rem;
    line-height: 1;
    flex-shrink: 0;
}

.sidebar-footer {
    padding: 0.5rem 0.5rem;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.sidebar-settings-link {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    padding: 0.28rem 0.55rem;
    border-radius: var(--radius-sm);
    color: rgba(255, 255, 255, 0.55);
    font-weight: 500;
    font-size: 0.9rem;
    font-family: inherit;
    transition: background 0.2s, color 0.2s;
    text-decoration: none;
    margin-bottom: 1px;
    background: none;
    border: none;
    cursor: pointer;
    text-align: left;
}

.sidebar-settings-link:hover {
    background: rgba(255, 255, 255, 0.08);
    color: rgba(255, 255, 255, 0.9);
    text-decoration: none;
}

.sidebar-settings-link.active {
    background: var(--color-primary);
    color: #ffffff;
    box-shadow: 0 2px 12px rgba(24, 181, 164, 0.35);
}

.sidebar-user {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.user-label {
    display: block;
    font-size: 0.8rem;
    color: rgba(255, 255, 255, 0.4);
    font-weight: 500;
    padding: 0 0.75rem;
}

.logout-button {
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.35rem;
    border-radius: 0.375rem;
    color: rgba(255, 255, 255, 0.35);
    flex-shrink: 0;
    transition: background 0.2s, color 0.2s;
}

.logout-button:hover {
    background: rgba(255, 255, 255, 0.08);
    color: rgba(255, 255, 255, 0.9);
}

/* ── Main Content ────────────────────────────────────────────────── */

.main-content {
    flex: 1;
    /* min-width:0 (overriding the flex default of auto) is load-bearing: without it this flex item refuses to
       shrink below its content's intrinsic width, so a list page with a very wide DataGrid balloons the whole
       content column past the viewport and the toolbar (headers/filters) scrolls off to the right across the
       fixed sidebar. With it, the column stays viewport-width and the grid scrolls inside its own .dg-container
       (overflow:hidden) / .dg-scroll-container (overflow:auto) instead. */
    min-width: 0;
    margin-left: var(--sidebar-width);
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.page-content {
    flex: 1;
    /* Same reasoning as .main-content — keep this column-flex child from being widened by an over-wide grid. */
    min-width: 0;
    padding: 2rem 2.5rem;
}

.page-header {
    margin-bottom: 1.75rem;
}

.page-header h1 {
    font-size: 1.6rem;
    font-weight: 700;
    letter-spacing: -0.01em;
}

/* ── Toolbar ──────────────────────────────────────────────────────── */

.toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 2.5rem;
    background: var(--glass-bg);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border-bottom: 1px solid var(--color-border);
    flex-shrink: 0;
    /* backdrop-filter makes the toolbar its own stacking context; raise it so an open dropdown
       (a descendant) paints above the page content/grid below. Stays under modals (z-index 1000). */
    position: relative;
    z-index: 100;
}

.toolbar-tabs {
    display: flex;
    gap: 0.25rem;
}

.toolbar-filters {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.filter-select {
    font-family: var(--font-sans);
    font-size: 0.8rem;
    padding: 0.35rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, 0.6);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    color: var(--color-text-secondary);
    cursor: pointer;
    outline: none;
    transition: border-color 0.2s, box-shadow 0.2s;
}

.filter-select:focus {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px rgba(24, 181, 164, 0.12);
}

/* Realtime free-text filter box in toolbars. */
.invoice-search {
    min-width: 220px;
    color: var(--color-text);
}

.invoice-search::placeholder {
    color: var(--color-text-secondary);
}

/* Centre zone of the Sales toolbar — the search sits in the middle, growing to fill the space between the
   left tabs and the right view/date/⋯ controls, with the input itself a fixed, centred width. */
.toolbar-search {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    justify-content: center;
    padding: 0 1.5rem;
}

.toolbar-search input[type="search"] {
    width: 100%;
    max-width: 425px;
    font-family: var(--font-sans);
    font-size: 0.8rem;
    padding: 0.5rem 0.85rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, 0.6);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    color: var(--color-text);
    outline: none;
    transition: border-color 0.2s, box-shadow 0.2s;
}

.toolbar-search input[type="search"]:focus {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px rgba(24, 181, 164, 0.12);
}

.toolbar-search input[type="search"]::placeholder {
    color: var(--color-text-secondary);
}

/* Toolbar "More" dropdown menu. */
.toolbar-dropdown {
    position: relative;
    display: inline-flex;
}

.toolbar-dropdown-backdrop {
    position: fixed;
    inset: 0;
    /* Above the page content (so outside clicks are caught) but below the toolbar (z-index 100),
       so the menu — a child of the toolbar — still paints on top of this backdrop. */
    z-index: 90;
}

.toolbar-dropdown-menu {
    position: absolute;
    top: calc(100% + 0.45rem);
    right: 0;
    z-index: 50;
    min-width: 210px;
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    padding: 0.35rem;
    background: var(--glass-bg-strong);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-md);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.18);
}

.toolbar-dropdown-item {
    display: block;
    width: 100%;
    text-align: left;
    padding: 0.5rem 0.7rem;
    font-family: var(--font-sans);
    font-size: 0.83rem;
    color: var(--color-text);
    background: transparent;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
}

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

.toolbar-dropdown-item:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* ── Tabs ─────────────────────────────────────────────────────────── */

.tab {
    background: none;
    border: none;
    padding: 0.75rem 1.25rem;
    font-family: var(--font-sans);
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--color-text-muted);
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color 0.15s, border-color 0.15s;
}

.tab:hover {
    color: var(--color-text);
}

.tab-active {
    color: var(--color-primary);
    border-bottom-color: var(--color-primary);
}

.tab-count {
    font-size: 0.75rem;
    color: var(--color-text-muted);
    margin-left: 0.35rem;
}

/* ── Cards ────────────────────────────────────────────────────────── */

.card {
    background: var(--glass-bg-strong);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    padding: 1.25rem 1.5rem;
    transition: box-shadow 0.2s, transform 0.15s;
}

.card:hover {
    box-shadow: var(--shadow-md);
}

.card-with-logo {
    display: flex;
    align-items: flex-start;
    gap: 1.25rem;
}

.card-with-logo .card-body {
    flex: 1;
    min-width: 0;
}

.card-logo {
    width: 48px;
    height: 48px;
    max-width: 48px;
    max-height: 48px;
    object-fit: contain;
    border-radius: var(--radius-sm);
    flex-shrink: 0;
    align-self: center;
}

.card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.5rem;
}

.card-title {
    font-size: 1rem;
    font-weight: 600;
}

.card-detail {
    font-size: 0.85rem;
    color: var(--color-text-secondary);
    margin-top: 0.25rem;
}

.card-detail-subtle {
    color: var(--color-text-muted);
    font-size: 0.8rem;
}

.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 1rem;
}

/* ── Badges ───────────────────────────────────────────────────────── */

.badge {
    display: inline-block;
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 0.2em 0.6em;
    border-radius: 5px;
    background: rgba(0, 0, 0, 0.05);
    color: var(--color-text-secondary);
}

.badge-enduser {
    background: #e0f7f5;
    color: #0d7d74;
}

.badge-dealer {
    background: #fff3e0;
    color: #c77800;
}

.badge-distributor {
    background: #ede7f6;
    color: #7b1fa2;
}

.badge-manufacturer {
    background: #fce4ec;
    color: #c62828;
}

.badge-local {
    background: #e3f2fd;
    color: #1565c0;
}

.badge-remote {
    background: #e8f5e9;
    color: #2e7d32;
}

.badge-signalr {
    background: #fff3e0;
    color: #e65100;
}

.badge-online {
    background: #e8f5e9;
    color: #2e7d32;
}

.badge-offline {
    background: #fef2f2;
    color: #dc2626;
}

/* ── Buttons ──────────────────────────────────────────────────────── */

.btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-family: var(--font-sans);
    font-size: 0.85rem;
    font-weight: 500;
    padding: 0.5rem 1rem;
    border-radius: var(--radius-sm);
    border: none;
    cursor: pointer;
    transition: background 0.2s, box-shadow 0.2s, transform 0.1s;
}

.btn:active {
    transform: scale(0.97);
}

.btn-primary {
    background: linear-gradient(135deg, var(--color-primary), #14a090);
    color: #ffffff;
    box-shadow: 0 2px 8px rgba(24, 181, 164, 0.25);
}

.btn-primary:hover {
    background: linear-gradient(135deg, var(--color-primary-hover), #0f8a7c);
    box-shadow: 0 4px 16px rgba(24, 181, 164, 0.35);
}

.btn-secondary {
    background: rgba(255, 255, 255, 0.6);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    color: var(--color-text-secondary);
    border: 1px solid var(--color-border);
}

.btn-secondary:hover {
    background: rgba(255, 255, 255, 0.85);
}

.btn-danger {
    background: linear-gradient(135deg, var(--color-coral), #e55a5a);
    color: #ffffff;
    box-shadow: 0 2px 8px rgba(255, 107, 107, 0.25);
}

.btn-danger:hover {
    background: linear-gradient(135deg, #e55a5a, #d04545);
    box-shadow: 0 4px 16px rgba(255, 107, 107, 0.35);
}

.danger-card {
    border-color: var(--color-coral);
}

/* ── Diagnostic Panel ─────────────────────────────────────────────── */

.diagnostic-panel {
    background: var(--glass-bg-strong);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}

.diagnostic-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 1.25rem;
    border-bottom: 1px solid var(--color-border-subtle);
}

.diagnostic-count {
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

.diagnostic-log {
    max-height: 600px;
    overflow-y: auto;
}

.log-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.8rem;
}

.log-table thead {
    position: sticky;
    top: 0;
    background: var(--color-bg-subtle);
}

.log-table th {
    text-align: left;
    padding: 0.5rem 1rem;
    font-weight: 600;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-muted);
    border-bottom: 1px solid var(--color-border);
}

.log-table td {
    padding: 0.4rem 1rem;
    border-bottom: 1px solid var(--color-border-subtle);
    vertical-align: top;
}

.log-time {
    font-family: 'SF Mono', 'Cascadia Code', 'Consolas', monospace;
    white-space: nowrap;
    color: var(--color-text-muted);
}

.log-detail {
    color: var(--color-text-secondary);
    max-width: 500px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ── Service Tiles (Diagnostics) ──────────────────────────────────── */

.service-tile {
    background: var(--glass-bg-strong);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    margin-bottom: 0.75rem;
    border-left: 3px solid var(--color-border);
    overflow: hidden;
}

.service-tile--healthy {
    border-left-color: #2e7d32;
}

.service-tile--degraded {
    border-left-color: #f57f17;
}

.service-tile--disconnected {
    border-left-color: #dc2626;
}

.service-tile-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 1.25rem;
    cursor: pointer;
    user-select: none;
    transition: background 0.15s;
}

.service-tile-header:hover {
    background: var(--color-bg-subtle);
}

.service-tile-identity {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.service-tile-name {
    font-weight: 600;
    font-size: 0.92rem;
}

.service-tile-key {
    font-size: 0.78rem;
    color: var(--color-text-muted);
    background: var(--color-bg-subtle);
    padding: 0.1em 0.4em;
    border-radius: 3px;
}

.service-tile-actions {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.service-tile-protocol {
    font-size: 0.78rem;
    color: var(--color-text-muted);
}

.service-tile-detail {
    padding: 0 1.25rem 1rem;
    border-top: 1px solid var(--color-border-subtle);
}

.service-tile-columns {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.5rem;
    padding-top: 0.75rem;
}

.service-tile-detail .detail-list {
    font-size: 0.82rem;
}

.tile-chevron {
    transition: transform 0.2s ease;
    color: var(--color-text-muted);
    flex-shrink: 0;
}

.tile-chevron--open {
    transform: rotate(180deg);
}

.badge-degraded {
    background: #fff8e1;
    color: #f57f17;
}

/* ── Status Icons (connection & source) ──────────────────────────── */

.status-icon {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    vertical-align: middle;
}

.badge-source {
    display: inline-flex;
    align-items: center;
    gap: 0.3em;
}

.badge-source .status-icon {
    width: 12px;
    height: 12px;
}

.error-timestamp {
    font-size: 0.75rem;
    color: var(--color-text-muted);
    margin-left: 0.5rem;
}

.section-heading {
    font-size: 1rem;
    font-weight: 600;
    color: var(--color-text-secondary);
    margin-bottom: 1rem;
}

/* ── About ────────────────────────────────────────────────────────── */

.about-content {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(560px, 1fr));
    gap: 1rem;
}

.detail-list {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.4rem 1.5rem;
    font-size: 0.9rem;
}

.detail-list dt {
    font-weight: 600;
    color: var(--color-text);
}

.detail-list dd {
    color: var(--color-text-secondary);
}

/* ── States ───────────────────────────────────────────────────────── */

.loading-indicator {
    text-align: center;
    padding: 3rem 1rem;
    color: var(--color-text-muted);
}

.empty-state {
    text-align: center;
    padding: 3rem 1rem;
    color: var(--color-text-muted);
}

.error-banner {
    background: #fef2f2;
    border: 1px solid #fecaca;
    border-radius: var(--radius-md);
    padding: 1.25rem 1.5rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.error-banner p {
    color: #dc2626;
    font-size: 0.9rem;
}

.not-found {
    text-align: center;
    padding: 4rem 1rem;
    color: var(--color-text-muted);
    font-size: 1.1rem;
}

.text-error {
    color: #dc2626;
}

/* ── Brand Badges ────────────────────────────────────────────────── */

.badge-belcanto {
    background: #e8f5e9;
    color: #2e7d32;
}

.badge-ygacoustics {
    background: #e3f2fd;
    color: #1565c0;
}

/* ── Sale/Invoice Status Badges ──────────────────────────────────── */

.badge-draft {
    background: #f3f4f6;
    color: #6b7280;
}

.badge-confirmed {
    background: #e0f7f5;
    color: #0d7d74;
}

.badge-invoiced {
    background: #e3f2fd;
    color: #1565c0;
}

.badge-issued {
    background: #e3f2fd;
    color: #1565c0;
}

.badge-paid {
    background: #e8f5e9;
    color: #2e7d32;
}

.badge-awaitingdispatch {
    background: #fff8e1;
    color: #f57f17;
}

.badge-dispatched {
    background: #e0f2f1;
    color: #00695c;
}

.badge-overdue {
    background: #fef2f2;
    color: #dc2626;
}

.badge-received {
    background: #e3f2fd;
    color: #1565c0;
}

.badge-disputed {
    background: #fff3e0;
    color: #e65100;
}

.badge-cancelled {
    background: #f3f4f6;
    color: #9ca3af;
}

.badge-pendingsale {
    background: rgba(234, 179, 8, 0.18);
    color: #a16207;
}

.badge-sold {
    background: rgba(16, 185, 129, 0.18);
    color: #065f46;
}

/* ── Repair / RMA Status Badges ──────────────────────────────────── */

.badge-awaitingreceipt {
    background: #f3f4f6;
    color: #6b7280;
}

.badge-receivedunprocessed {
    background: #e3f2fd;
    color: #1565c0;
}

.badge-underreview {
    background: #fff3e0;
    color: #e65100;
}

.badge-awaitingparts {
    background: #fef2f2;
    color: #dc2626;
}

.badge-underrepair {
    background: #fff8e1;
    color: #f57f17;
}

.badge-repaircomplete {
    background: #e0f7f5;
    color: #0d7d74;
}

.badge-awaitingshipment {
    background: #ede7f6;
    color: #4527a0;
}

.badge-shipped {
    background: #e8f5e9;
    color: #2e7d32;
}

.badge-onhold {
    background: #fce4ec;
    color: #880e4f;
}

.badge-active {
    background: #e8f5e9;
    color: #2e7d32;
}

.badge-delivered {
    background: #eef1f6;
    color: #5a607a;
}

.badge-superseded {
    background: #f3f4f6;
    color: #6b7280;
}

.badge-archived {
    background: #f3f4f6;
    color: #9ca3af;
}

/* ── Condition Badges ────────────────────────────────────────────── */

.badge-new {
    background: #e8f5e9;
    color: #2e7d32;
}

.badge-used {
    background: #fff3e0;
    color: #c77800;
}

.badge-demo {
    background: #e3f2fd;
    color: #1565c0;
}

/* ── Loan Status Badges ──────────────────────────────────────────── */

.badge-out {
    background: #fff8e1;
    color: #f57c00;
}

.badge-returned {
    background: #e8f5e9;
    color: #2e7d32;
}

.card-detail-muted {
    color: #999;
    font-size: 0.85em;
}

/* ── Inline Forms ────────────────────────────────────────────────── */

.form-panel {
    background: var(--glass-bg-strong);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    padding: 1.5rem;
    margin-bottom: 1.5rem;
}

.form-panel h3 {
    font-size: 1rem;
    font-weight: 600;
    margin-bottom: 1rem;
}

.form-row {
    display: flex;
    gap: 1rem;
    margin-bottom: 0.75rem;
    flex-wrap: wrap;
}

.form-group {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    flex: 1;
    min-width: 180px;
}

.form-group label {
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-muted);
}

.form-group input,
.form-group select,
.form-group textarea {
    font-family: var(--font-sans);
    font-size: 0.85rem;
    padding: 0.4rem 0.65rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, 0.6);
    color: var(--color-text);
    outline: none;
    transition: border-color 0.2s, box-shadow 0.2s;
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px rgba(24, 181, 164, 0.12);
}

.form-group textarea {
    resize: vertical;
    min-height: 60px;
}

.settings-two-col {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.5rem;
    align-items: start;
}

.form-actions {
    display: flex;
    gap: 0.5rem;
    margin-top: 0.75rem;
}

/* ── Pricing Table ───────────────────────────────────────────────── */

.pricing-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
    background: var(--glass-bg-strong);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}

.pricing-table thead {
    background: var(--color-bg-subtle);
}

.pricing-table th {
    text-align: left;
    padding: 0.6rem 1rem;
    font-weight: 600;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-muted);
    border-bottom: 1px solid var(--color-border);
}

.pricing-table td {
    padding: 0.5rem 1rem;
    border-bottom: 1px solid var(--color-border-subtle);
}

.pricing-table tr:last-child td {
    border-bottom: none;
}

.pricing-table .currency {
    color: var(--color-text-muted);
    font-size: 0.75rem;
    margin-right: 0.15rem;
}

/* Sales line-item table — more spacious rows */
.pricing-table.pricing-table-sales td {
    padding: 0.65rem 1rem;
    vertical-align: middle;
}

.pricing-table .col-price { min-width: 110px; }

.pricing-table .col-discount {
    text-align: right;
    white-space: nowrap;
    width: 72px;
    color: var(--color-coral);
    font-weight: 500;
}

.pricing-table .col-total { font-weight: 600; white-space: nowrap; }

/* Strikethrough original price when a discount is active */
.pricing-table .price-was {
    display: block;
    text-decoration: line-through;
    color: var(--color-text-muted);
    font-size: 0.78em;
    line-height: 1.2;
}

.pricing-table .price-now {
    display: block;
    font-weight: 600;
    line-height: 1.4;
}

/* Inputs and selects inside pricing-table (e.g. supplier line item editor) */
.pricing-table td input,
.pricing-table td select {
    font-family: var(--font-sans);
    font-size: 0.85rem;
    padding: 0.3rem 0.5rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, 0.6);
    color: var(--color-text);
    outline: none;
    transition: border-color 0.2s, box-shadow 0.2s;
}

.pricing-table td input:focus,
.pricing-table td select:focus {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px rgba(24, 181, 164, 0.12);
}

/* ── Order contents editor (Axe-style line-item table + picker dialog) ── */

.contents-table tbody tr:hover td {
    background: rgba(24, 181, 164, 0.06);
}

.contents-table tr.row-selected td {
    background: rgba(24, 181, 164, 0.14);
}

/* Category filter chips above the picker grid, with the create-product escape hatch pushed to the right. */
.picker-cats {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-bottom: 0.6rem;
}

.picker-cat {
    border: 1px solid var(--color-border);
    background: var(--glass-bg);
    color: var(--color-text-secondary);
    border-radius: 999px;
    padding: 0.25rem 0.75rem;
    font-size: 0.82rem;
    font-family: var(--font-sans);
    cursor: pointer;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}

.picker-cat:hover {
    background: rgba(24, 181, 164, 0.08);
}

.picker-cat-active {
    background: rgba(24, 181, 164, 0.14);
    border-color: var(--color-primary);
    color: var(--color-text);
    font-weight: 600;
}

/* Split Add button: the main half opens the picker as always; the ▾ half drops a small ctx-menu with the
   Add / Add-custom choice (the picker's in-dialog Custom-item checkbox was removed in favour of this). */
.btn-split {
    position: relative;
    display: inline-flex;
}

.btn-split .btn-split-main {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}

.btn-split .btn-split-toggle {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    border-left: 1px solid rgba(255, 255, 255, 0.35);
    padding-left: 0.5rem;
    padding-right: 0.5rem;
}

/* The house .ctx-menu positions fixed for pointer-placed menus; this one anchors under the split button. */
.btn-split .ctx-menu {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
}

/* Resizable picker dialog (llbDialog.enhance): a flex column at a fixed starting height, so dragging the
   corner grabber grows/shrinks the GRID — everything else keeps its natural height. The grid's inline
   Height (kept for the virtualisation trigger) is overridden by the !important flex sizing below.
   Padding and heading margins are tightened so title → chips → grid sit close to the top. */
.modal-dialog.picker-dialog {
    display: flex;
    flex-direction: column;
    height: min(78dvh, 680px);
    padding: 1rem 1.25rem 1.25rem;
}

.picker-dialog h4 {
    margin-bottom: 0.6rem;
}

.picker-dialog > * {
    flex-shrink: 0;
}

.picker-dialog > .picker-grid {
    flex: 1 1 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.picker-grid .dg-container {
    flex: 1 1 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.picker-grid .dg-toolbar {
    flex-shrink: 0;
}

.picker-grid .dg-scroll-container {
    height: auto !important;
    flex: 1 1 0;
    min-height: 0;
}

/* Shared grab-handle affordance for any llbDialog.enhance'd dialog (the note dialog carries its own copy). */
.llb-dialog-titlebar {
    cursor: move;
    user-select: none;
    touch-action: none;
}

/* ── Pricing Tree View ──────────────────────────────────────────── */

.pricing-tree-brand {
    margin-top: 0.5rem;
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-sm);
    background: var(--glass-bg);
    backdrop-filter: blur(var(--glass-blur));
}

.pricing-tree-brand > summary {
    list-style: none;
    cursor: pointer;
    padding: 0.75rem 1rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: 600;
    user-select: none;
}

.pricing-tree-brand > summary::-webkit-details-marker {
    display: none;
}

.pricing-tree-brand > summary::before {
    content: "\25B6";
    font-size: 0.65rem;
    transition: transform 0.15s ease;
    color: var(--color-text-muted);
}

.pricing-tree-brand[open] > summary::before {
    transform: rotate(90deg);
}

.pricing-tree-brand-name {
    font-size: 0.95rem;
}

.pricing-tree-tier {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.35rem 1rem;
    font-size: 0.82rem;
    color: var(--color-text-muted);
    border-top: 1px solid var(--color-border-subtle);
}

.pricing-tree-tier-label {
    font-weight: 500;
    color: var(--color-text);
    min-width: 100px;
}

.pricing-tree-pct {
    font-family: 'Cascadia Code', 'Fira Code', monospace;
    font-size: 0.78rem;
    padding: 0.15rem 0.5rem;
    border-radius: 3px;
}

.pricing-tree-pct-override {
    background: rgba(32, 178, 170, 0.12);
    color: var(--color-primary);
    font-weight: 600;
}

.pricing-tree-pct-override-text {
    font-weight: 600;
    color: var(--color-text);
}

.pricing-tree-pct-inherited-text {
    color: var(--color-text-muted);
    font-style: italic;
}

.pricing-tree-series {
    margin: 0.25rem 0;
}

.pricing-tree-series > summary {
    list-style: none;
    cursor: pointer;
    padding: 0.4rem 1rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.88rem;
    border-top: 1px solid var(--color-border-subtle);
    user-select: none;
}

.pricing-tree-series > summary::-webkit-details-marker {
    display: none;
}

.pricing-tree-series > summary::before {
    content: "\25B6";
    font-size: 0.55rem;
    transition: transform 0.15s ease;
    color: var(--color-text-muted);
}

.pricing-tree-series[open] > summary::before {
    transform: rotate(90deg);
}

.pricing-tree-series-name {
    font-weight: 500;
}

.pricing-tree-editable {
    cursor: pointer;
    transition: background 0.15s;
}

.pricing-tree-editable:hover {
    background: rgba(255, 255, 255, 0.08);
    text-decoration: underline;
    text-decoration-style: dotted;
}

.pricing-tree-edit-input {
    width: 70px;
    padding: 2px 4px;
    font-size: 0.8rem;
    font-family: 'Fira Code', 'Cascadia Code', monospace;
    background: var(--glass-bg-strong);
    border: 1px solid var(--color-primary);
    border-radius: 3px;
    color: var(--color-text);
    outline: none;
}

.pricing-tree-clear-btn {
    display: inline-block;
    margin-left: 2px;
    padding: 0 3px;
    font-size: 0.65rem;
    line-height: 1;
    color: var(--color-text-muted);
    cursor: pointer;
    opacity: 0.5;
    vertical-align: middle;
}

.pricing-tree-clear-btn:hover {
    opacity: 1;
    color: var(--color-danger, #e74c3c);
}

/* ── Import Panel ───────────────────────────────────────────────── */

.import-textarea {
    width: 100%;
    min-height: 160px;
    font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace;
    font-size: 0.82rem;
    line-height: 1.5;
    padding: 0.75rem 1rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-bg);
    color: var(--color-text);
    resize: vertical;
}

.import-textarea:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px rgba(32, 178, 170, 0.15);
}

/* ── Card Actions (Edit / Delete) ────────────────────────────────── */

.card-actions {
    display: flex;
    gap: 0.35rem;
    margin-left: auto;
}

.card-actions .btn-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border-radius: var(--radius-sm);
    border: 1px solid var(--color-border);
    background: var(--color-bg);
    color: var(--color-text-muted);
    cursor: pointer;
    font-size: 0.8rem;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}

.card-actions .btn-icon:hover {
    background: var(--color-bg-hover);
    color: var(--color-text);
}

.card-actions .btn-icon-danger:hover {
    background: #fef2f2;
    color: #dc2626;
    border-color: #fecaca;
}

.card-actions .btn-icon-sell {
    color: #14b8a6;
}

.card-actions .btn-icon-sell:hover {
    background: rgba(20, 184, 166, 0.12);
    color: #0d9488;
}

/* ── Map Pin Button (address book → map navigation) ──────────── */

.map-pin-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    padding: 0;
    border: none;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--color-text-muted);
    cursor: pointer;
    transition: color 0.15s, background 0.15s;
}

.map-pin-btn:hover {
    color: #2dd4bf;
    background: rgba(45, 212, 191, 0.12);
}

/* ── Modal Dialog ─────────────────────────────────────────────── */

@keyframes modal-fade-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes modal-slide-up {
    from { opacity: 0; transform: translateY(16px) scale(0.97); }
    to { opacity: 1; transform: translateY(0) scale(1); }
}

.modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(10, 12, 20, 0.4);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    animation: modal-fade-in 0.2s ease-out;
}

.modal-dialog {
    position: relative;
    background: var(--glass-bg-strong);
    /* The glass blur lives on the ::after layer below, NOT on this element. A backdrop-filter makes an element
       the containing block for position:fixed descendants (Filter Effects 2 — Chrome now conforms), so with it
       here a NESTED Modal's fixed backdrop mapped to this box instead of the viewport and was clipped by this
       element's own overflow — the order dialogs' Add-item picker rendered as an unusable band (2026-08-12).
       The pseudo-element has no descendants, so nothing can be trapped; the explicit 'none' also defeats the
       identical rule in the DataGrid package's datagrid.css, which loads before this file. */
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-lg);
    padding: 1.75rem;
    min-width: 520px;
    max-width: 720px;
    /* Never let a modal grow taller than the viewport — long content scrolls inside the dialog. */
    max-height: 90dvh;
    overflow-y: auto;
    box-shadow: var(--shadow-lg), 0 0 60px rgba(24, 181, 164, 0.08);
    animation: modal-slide-up 0.25s ease-out;
}

/* The dialog's glass layer (::after because the mobile bottom-sheet already uses ::before for its drag
   handle). Behind the dialog's own translucent background, covering the whole box, never intercepting
   clicks — visually identical to the blur previously set on .modal-dialog itself. */
.modal-dialog::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    backdrop-filter: blur(24px);
    -webkit-backdrop-filter: blur(24px);
    pointer-events: none;
}

/* Opt-in variant for modals with a long scrollable body and a pinned header/footer (e.g. the Users
   editor): the dialog itself clips, and the inner .…-body region does the scrolling instead. */
.modal-dialog.modal-flex {
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.modal-dialog h4 {
    margin: 0 0 1.25rem;
    font-size: 1.05rem;
}

.modal-dialog .modal-footer {
    display: flex;
    gap: 0.5rem;
    justify-content: flex-end;
    margin-top: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid var(--color-border);
}

/* Highlight the table row currently being edited */
.row-editing td {
    background: #fffbeb;
}

.row-selected td {
    background: rgba(24, 181, 164, 0.10);
}

.delete-confirm {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    margin-top: 0.5rem;
    background: #fef2f2;
    border: 1px solid #fecaca;
    border-radius: var(--radius-sm);
    font-size: 0.82rem;
    color: #dc2626;
}

.delete-confirm .btn {
    font-size: 0.78rem;
    padding: 0.3rem 0.75rem;
}

.import-message {
    display: inline-block;
    font-size: 0.85rem;
    font-weight: 500;
    padding: 0.25rem 0.75rem;
    border-radius: var(--radius-sm);
}

.import-success {
    color: #15803d;
    background: #f0fdf4;
}

.import-error {
    color: #b91c1c;
    background: #fef2f2;
}

/* ── Import Page Banners ─────────────────────────────────────────── */

.import-banner {
    padding: 0.75rem 1rem;
    border-radius: var(--radius-sm);
    font-size: 0.9rem;
    font-weight: 500;
    margin-bottom: 1rem;
}

.import-banner-success {
    color: #15803d;
    background: #f0fdf4;
    border: 1px solid #bbf7d0;
}

.import-banner-error {
    color: #b91c1c;
    background: #fef2f2;
    border: 1px solid #fecaca;
}

.import-error-text {
    color: #b91c1c;
    font-weight: 500;
}

/* ── Import Diagnostic Log ───────────────────────────────────────── */

.import-log {
    max-height: 400px;
    overflow-y: auto;
    font-size: 0.85rem;
    font-family: var(--font-sans);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    margin-top: 0.5rem;
}

.import-log-entry {
    padding: 0.35rem 0.75rem;
    border-bottom: 1px solid var(--color-border-subtle);
    display: flex;
    gap: 0.5rem;
    align-items: baseline;
}

.import-log-entry:last-child {
    border-bottom: none;
}

.import-log-level {
    font-weight: 600;
    font-size: 0.75rem;
    text-transform: uppercase;
    flex-shrink: 0;
    width: 3rem;
}

.import-log-info .import-log-level {
    color: var(--color-blue);
}

.import-log-warn .import-log-level {
    color: var(--color-gold);
}

.import-log-error {
    background: #fef2f2;
}

.import-log-error .import-log-level {
    color: #b91c1c;
}

/* ── Map Page ────────────────────────────────────────────────────── */

.map-page-content {
    padding: 0 !important;
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    overflow: hidden;
}

.map-container {
    flex: 1;
    min-height: 0;
    width: 100%;
}

.map-toolbar-count {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.8rem;
    color: var(--color-text-secondary);
    padding: 0.35rem 0.75rem;
    background: var(--glass-bg);
    border-radius: var(--radius-sm);
    border: 1px solid var(--glass-border);
}

/* MapLibre popup styling — glass morphism. */
.maplibregl-popup-content {
    background: var(--glass-bg-strong) !important;
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border) !important;
    border-radius: var(--radius-md) !important;
    box-shadow: var(--shadow-md) !important;
    font-family: var(--font-sans) !important;
    padding: 0.75rem 1rem !important;
    color: var(--color-text);
}

.maplibregl-popup-close-button {
    color: var(--color-text-muted);
    font-size: 1.2rem;
    padding: 4px 8px !important;
}

.map-popup-name {
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--color-teal);
    margin-bottom: 0.15rem;
}

.map-popup-type {
    margin-bottom: 0.35rem;
}

.map-popup-badge {
    display: inline-block;
    font-size: 0.7rem;
    font-weight: 600;
    color: #fff;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.map-popup-address {
    font-size: 0.8rem;
    color: var(--color-text-secondary);
    line-height: 1.4;
    margin-bottom: 0.25rem;
}

.map-popup-contact {
    font-size: 0.78rem;
    color: var(--color-text-muted);
}

/* ── Mini Map (Address Book editor) ──────────────────────────────── */

.mini-map-container {
    width: 100%;
    height: 300px;
    border-radius: var(--radius-md);
    border: 1px solid var(--glass-border);
    overflow: hidden;
}

.location-panel {
    background: var(--glass-bg);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-md);
    padding: 1rem 1.25rem;
    margin-bottom: 1rem;
}

.location-panel h3 {
    margin: 0 0 0.75rem;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--color-text);
}

.location-coords {
    font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', monospace;
    font-size: 0.8rem;
    color: var(--color-text-secondary);
    margin: 0.5rem 0;
}

.location-actions {
    display: flex;
    gap: 0.5rem;
    margin-top: 0.75rem;
    align-items: center;
}

.location-message {
    font-size: 0.8rem;
    color: var(--color-text-secondary);
    margin-left: 0.5rem;
}

/* ── Geocode Log (modal) ─────────────────────────────────────────── */

.geocode-log {
    background: #0d1117;
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-sm);
    padding: 0.75rem 1rem;
    max-height: 400px;
    min-height: 200px;
    overflow-y: auto;
    font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', monospace;
    font-size: 0.78rem;
    line-height: 1.5;
    color: #c9d1d9;
}

.geocode-log-line {
    white-space: pre-wrap;
    word-break: break-word;
}

.geocode-log-success {
    color: #3fb950;
}

.geocode-log-error {
    color: #f85149;
}

.geocode-log-warn {
    color: #d29922;
}

/* ── Mobile / Touch Layout ───────────────────────────────────────── */

/* Hidden by default — media query reveals them on mobile */

.mobile-header {
    display: none;
}

.mobile-nav-overlay {
    display: none;
}

.hamburger-btn {
    display: none;
}

@keyframes slide-up-sheet {
    from { opacity: 0; transform: translateY(40px); }
    to { opacity: 1; transform: translateY(0); }
}

@media (max-width: 768px) {

    /* ── Sidebar: off-screen by default, slides in on toggle */

    .sidebar {
        transform: translateX(-100%);
        transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);
        z-index: 200;
    }

    .sidebar.mobile-open {
        transform: translateX(0);
        box-shadow: 6px 0 40px rgba(0, 0, 0, 0.4);
    }

    /* ── Overlay behind the open sidebar */

    .mobile-nav-overlay {
        display: block;
        position: fixed;
        inset: 0;
        background: rgba(0, 0, 0, 0.5);
        z-index: 190;
        animation: modal-fade-in 0.2s ease-out;
    }

    /* ── Main content fills the full viewport width */

    .main-content {
        margin-left: 0;
    }

    /* ── Mobile top header bar */

    .mobile-header {
        display: flex;
        align-items: center;
        gap: 0.75rem;
        padding: 0.6rem 1rem;
        background: var(--glass-bg);
        backdrop-filter: blur(var(--glass-blur));
        -webkit-backdrop-filter: blur(var(--glass-blur));
        border-bottom: 1px solid var(--color-border);
        position: sticky;
        top: 0;
        z-index: 50;
    }

    .hamburger-btn {
        display: flex;
        align-items: center;
        justify-content: center;
        background: none;
        border: none;
        cursor: pointer;
        padding: 0.4rem;
        color: var(--color-text);
        flex-shrink: 0;
        border-radius: var(--radius-sm);
        transition: background 0.15s;
    }

    .hamburger-btn:hover,
    .hamburger-btn:active {
        background: var(--color-bg-hover);
    }

    /* ── Modals: full-width bottom sheet */

    .modal-backdrop {
        align-items: flex-end;
        padding: 0;
    }

    .modal-dialog {
        min-width: 0 !important;
        max-width: 100% !important;
        width: 100%;
        max-height: 92dvh;
        overflow-y: auto;
        border-radius: var(--radius-lg) var(--radius-lg) 0 0;
        padding: 1.5rem 1rem 1.25rem;
        animation: slide-up-sheet 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    }

    /* Sheet drag handle */
    .modal-dialog::before {
        content: '';
        display: block;
        width: 36px;
        height: 4px;
        background: var(--color-border);
        border-radius: 2px;
        margin: -0.5rem auto 1.25rem;
    }

    /* ── Toolbar: stacks vertically */

    .toolbar {
        flex-direction: column;
        align-items: stretch;
        gap: 0.5rem;
        padding: 0.75rem 1rem;
    }

    .toolbar-filters {
        flex-wrap: wrap;
        gap: 0.4rem;
    }

    .filter-select {
        flex: 1 1 130px;
    }

    /* ── Page content: tighter padding */

    .page-content {
        padding: 0.75rem;
    }

}

/* ──────────────────────────────────────────────────────────────────────
   Price Import Wizard
   ────────────────────────────────────────────────────────────────────── */

.btn-small {
    padding: 0.25rem 0.6rem;
    font-size: 0.8rem;
    margin-right: 0.25rem;
}

.wizard-steps {
    display: flex;
    gap: 0.25rem;
    margin-bottom: 1rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--glass-border);
}

.wizard-step {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.4rem 0.8rem;
    border-radius: var(--radius-md);
    font-size: 0.85rem;
    color: var(--color-text-secondary);
    background: transparent;
    border: 1px solid transparent;
}

.wizard-step.active {
    background: var(--glass-bg-strong);
    border-color: var(--color-teal);
    color: var(--color-text-primary);
}

.wizard-step.done {
    color: var(--color-teal);
}

.wizard-step-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--glass-bg);
    font-size: 0.75rem;
    font-weight: 600;
}

.wizard-step.active .wizard-step-num {
    background: var(--color-teal);
    color: white;
}

.wizard-step.done .wizard-step-num {
    background: var(--color-teal);
    color: white;
}

.price-match-badge {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.05rem 0.4rem;
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--color-teal);
    background: rgba(64, 192, 175, 0.15);
    border: 1px solid rgba(64, 192, 175, 0.4);
    border-radius: var(--radius-sm);
    vertical-align: middle;
}

/* ── Global Search ───────────────────────────────────────────────── */

.nav-search-btn {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    width: 100%;
    padding: 0.55rem 0.75rem;
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: var(--radius-sm);
    color: rgba(255,255,255,0.7);
    font-family: var(--font-sans);
    font-size: 0.875rem;
    font-weight: 500;
    cursor: pointer;
    text-align: left;
    transition: background 0.15s, color 0.15s;
    margin-bottom: 0.25rem;
}

.nav-search-btn:hover {
    background: rgba(255,255,255,0.12);
    color: #fff;
}

.nav-search-btn .nav-icon {
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    opacity: 0.7;
}

.nav-search-btn:hover .nav-icon { opacity: 1; }

.nav-search-kbd {
    margin-left: auto;
    font-size: 0.68rem;
    font-family: var(--font-sans);
    color: rgba(255,255,255,0.35);
    background: rgba(255,255,255,0.07);
    border: 1px solid rgba(255,255,255,0.12);
    border-radius: 4px;
    padding: 0.1rem 0.35rem;
    letter-spacing: 0.02em;
}

.gs-backdrop {
    position: fixed;
    inset: 0;
    z-index: 9000;
    background: rgba(10, 10, 30, 0.55);
    backdrop-filter: blur(6px);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding-top: 8vh;
}

.gs-modal {
    width: 100%;
    max-width: 660px;
    background: rgba(255,255,255,0.97);
    border: 1px solid var(--color-border);
    border-radius: 14px;
    box-shadow: 0 24px 64px rgba(0,0,0,0.22), 0 4px 16px rgba(0,0,0,0.08);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    max-height: 75vh;
}

.gs-input-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.9rem 1.1rem;
    border-bottom: 1px solid var(--color-border);
}

.gs-search-icon {
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    color: var(--color-text-muted);
}

.gs-input {
    flex: 1;
    border: none;
    outline: none;
    background: transparent;
    font-family: var(--font-sans);
    font-size: 1rem;
    font-weight: 500;
    color: var(--color-text);
    line-height: 1.4;
}

.gs-input::placeholder { color: var(--color-text-muted); font-weight: 400; }

.gs-esc {
    font-size: 0.72rem;
    font-family: var(--font-sans);
    color: var(--color-text-muted);
    background: var(--color-bg-subtle);
    border: 1px solid var(--color-border);
    border-radius: 4px;
    padding: 0.15rem 0.4rem;
    flex-shrink: 0;
}

.gs-spinner {
    width: 18px;
    height: 18px;
    border: 2px solid var(--color-border);
    border-top-color: var(--color-teal);
    border-radius: 50%;
    animation: gs-spin 0.6s linear infinite;
    flex-shrink: 0;
}

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

.gs-body {
    overflow-y: auto;
    padding: 0.5rem 0 0.75rem;
}

.gs-hint {
    padding: 1.25rem 1.25rem;
    font-size: 0.875rem;
    color: var(--color-text-muted);
    text-align: center;
}

.gs-hint strong { color: var(--color-text-secondary); }

.gs-group { margin-bottom: 0.25rem; }

.gs-group-header {
    padding: 0.5rem 1.1rem 0.25rem;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-text-muted);
}

.gs-result {
    display: block;
    width: 100%;
    padding: 0.55rem 1.1rem;
    background: transparent;
    border: none;
    text-align: left;
    cursor: pointer;
    transition: background 0.1s;
    font-family: var(--font-sans);
}

.gs-result:hover { background: var(--color-bg-hover); }

.gs-result-main {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.15rem;
}

.gs-result-title {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--color-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}

.gs-result-tag {
    flex-shrink: 0;
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--color-teal);
    background: rgba(24, 181, 164, 0.1);
    border: 1px solid rgba(24, 181, 164, 0.3);
    border-radius: 4px;
    padding: 0.1rem 0.4rem;
    white-space: nowrap;
}

.gs-result-sub {
    font-size: 0.8rem;
    color: var(--color-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.gs-group-overflow {
    padding: 0.25rem 1.1rem 0.35rem;
    font-size: 0.775rem;
    color: var(--color-text-muted);
    font-style: italic;
}

/* ── Sale / Supplier Invoice link badge ──────────────────────── */

.badge-link-count {
    display: inline-block;
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--color-teal);
    background: rgba(24, 181, 164, 0.12);
    border: 1px solid rgba(24, 181, 164, 0.35);
    border-radius: 10px;
    padding: 0.1rem 0.5rem;
    white-space: nowrap;
}

/* ── Graphs page ─────────────────────────────────────────────── */

.graphs-content {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

/* KPI card values that click through to another page (e.g. the Graphs Overview's top product/customer). */
.card-link {
    cursor: pointer;
    color: var(--color-green, #4e8d76);
    width: fit-content;
}

.card-link:hover {
    text-decoration: underline;
}

/* Reports page: summary bar above the brand-sales grid. */
.report-summary {
    display: flex;
    align-items: baseline;
    gap: 1.5rem;
    margin-bottom: 0.85rem;
    color: var(--color-text-muted);
    font-size: 0.9rem;
}

.report-summary .report-summary-label {
    font-weight: 600;
    color: var(--color-text);
    font-size: 1rem;
}

.chart-card {
    padding: 1.5rem 1.75rem 1rem;
}

/* Sales Over Time stretches to fill the viewport height below the toolbar.
   ApexCharts only honours a number or "100%" for height, and for "100%" it reads the chart
   element's PARENT height — so .chart-fill must carry a real, definite height. It must NOT be a
   flex item with flex:1 (that sets flex-basis:0 and collapses the explicit height). */
.chart-card-fill .chart-fill {
    height: calc(100vh - 240px);
    min-height: 360px;
}

.chart-title {
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin: 0 0 1.25rem;
}

/* ApexCharts: transparent SVG background + force visible label colours. */
.apexcharts-canvas svg {
    background: transparent !important;
}

.apexcharts-xaxis text,
.apexcharts-yaxis text,
.apexcharts-xaxis-texts-g text,
.apexcharts-yaxis-texts-g text,
.apexcharts-datalabel,
.apexcharts-legend-text {
    fill: #5a607a !important;
    font-family: 'Plus Jakarta Sans', sans-serif;
}

.apexcharts-gridline {
    stroke: rgba(0, 0, 0, 0.08) !important;
}

.apexcharts-xaxis-tick,
.apexcharts-yaxis-tick {
    stroke: #8b90a8 !important;
}

/* Receivables detail table */
.receivables-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.875rem;
}

.receivables-table th {
    padding: 0.45rem 0.75rem;
    text-align: left;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-text-muted);
    border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}

.receivables-table td {
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid rgba(0, 0, 0, 0.04);
    vertical-align: middle;
}

.receivables-table .num-col {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.receivables-table .text-muted {
    color: var(--color-text-muted);
}

.receivables-table .invoice-num {
    font-family: monospace;
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

/* Outstanding-invoice rows deep-link to the invoice's detail modal. */
.receivables-table tbody tr.clickable-row {
    cursor: pointer;
    transition: background 0.12s;
}

.receivables-table tbody tr.clickable-row:hover {
    background: var(--glass-bg);
}

.receivables-table tbody tr.clickable-row:hover .invoice-num {
    color: var(--color-primary);
}

.outstanding-amount {
    font-weight: 600;
}

.receivables-total-row td {
    font-weight: 700;
    border-top: 2px solid rgba(0, 0, 0, 0.1);
    border-bottom: none;
    padding-top: 0.65rem;
}

.age-badge {
    display: inline-block;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 600;
    white-space: nowrap;
}

.age-future { background: rgba(24, 181, 164, 0.12); color: #0e8a7d; }
.age-overdue-30 { background: rgba(240, 165, 0, 0.15); color: #966500; }
.age-overdue-60 { background: rgba(255, 107, 107, 0.2); color: #c0282b; }
.age-overdue-90 { background: rgba(200, 30, 30, 0.2); color: #a01010; }
.age-overdue-90plus { background: rgba(150, 0, 0, 0.2); color: #780000; }

/* ── Loans split layout + Notes panel ─────────────────────────────── */

.loans-split {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
}

.loans-split-pane {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
}

.loans-split-pane--notes {
    border-top: 1px solid var(--color-border);
}

/* Body below each pane's toolbar. The grid manages its own scroll; the notes body scrolls itself. */
.loans-split-body {
    flex: 1;
    min-height: 0;
    padding: 1rem 1.25rem;
}

.loans-split-body.notes-body {
    padding: 1.25rem 1.5rem;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.notes-title {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0 0.25rem;
    font-weight: 700;
    font-size: 0.95rem;
    letter-spacing: -0.01em;
    color: var(--color-text);
}

.notes-show-done {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.8rem;
    color: var(--color-text-secondary);
    white-space: nowrap;
    cursor: pointer;
}

.notes-empty {
    padding: 1rem 0.25rem;
    color: var(--color-text-secondary);
    font-style: italic;
    font-size: 0.875rem;
}

.note-row {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 0.6rem 0.7rem;
    background: var(--glass-bg);
    border: 1px solid var(--glass-border);
    border-radius: 8px;
    transition: border-color 0.15s;
}

.note-row:hover {
    border-color: var(--color-primary);
}

.note-check {
    flex-shrink: 0;
    width: 16px;
    height: 16px;
    margin-top: 0.15rem;
    cursor: pointer;
}

.note-main {
    flex: 1;
    min-width: 0;
    cursor: pointer;
}

.note-text {
    font-size: 0.9rem;
    line-height: 1.4;
    color: var(--color-text);
    white-space: pre-wrap;
    word-break: break-word;
}

.note-meta {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-top: 0.25rem;
    font-size: 0.72rem;
    color: var(--color-text-secondary);
}

/* A done note keeps its writers' colours — it is still a conversation — but drops back so the active list stays
   the loud one. Opacity rather than a colour override, which the per-writer inline colour would win anyway. */
.note-row--done .note-text {
    text-decoration: line-through;
    color: var(--color-text-secondary);
    opacity: 0.7;
}

/* ── Per-writer text colour ────────────────────────────────────────
   Each person's writing in the note list carries their own colour (assigned in Services/AuthorColours.cs) so a
   replied-to note reads as a conversation rather than one block of text. The colour lands as an inline style on
   each run; this is only the legend above the list, shown once more than one person's writing is on the page. */
.note-writers {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.85rem;
    padding: 0.5rem 1.5rem 0;
    font-size: 0.72rem;
    color: var(--color-text-secondary);
}

.note-writer {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.note-writer-swatch {
    width: 0.55rem;
    height: 0.55rem;
    border-radius: 50%;
}

.note-del {
    flex-shrink: 0;
    padding: 0 0.25rem;
    background: none;
    border: none;
    color: var(--color-text-secondary);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.15s, color 0.15s;
}

.note-row:hover .note-del {
    opacity: 1;
}

.note-del:hover {
    color: var(--color-danger, #e5484d);
}

.notes-done-header {
    margin: 0.75rem 0 0.1rem;
    padding-left: 0.25rem;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-text-secondary);
}

/* ── Tasks ─────────────────────────────────────────────────────────
   The task list reuses the .note-row skeleton (a tick, a two-line body, a hover delete) because it is the same
   shape of thing, and adds only what tasks need on top: the time-bucket headers, the overdue treatment, and the
   dialog's three question rows. Own .task-* / .tasks-* prefix rather than extending .note-* — the same call the
   notes CSS made about .woo-doc-*. */

.tasks-group-header {
    margin: 0.9rem 0 0.15rem;
    padding-left: 0.25rem;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-text-secondary);
}

.tasks-group-header--overdue {
    color: #b06a00;
}

.task-row--overdue {
    border-color: #e8c48a;
    background: rgba(176, 106, 0, 0.05);
}

.task-due--overdue {
    color: #b06a00;
    font-weight: 600;
}

.task-count--overdue {
    background: #b06a00;
    color: #fff;
}

.task-state {
    font-weight: 600;
}

.task-state--skipped,
.task-state--cancelled {
    color: #b06a00;
}

.task-state--done {
    color: #15803d;
}

/* A skipped or stopped occurrence must not read like a completed one, so it keeps its text un-struck. */
.note-row--done .task-state--skipped ~ *,
.note-row--done .task-state--cancelled ~ * {
    font-style: italic;
}

.tasks-toast {
    margin: 0.5rem 0 0;
    padding: 0.5rem 0.7rem;
    border-radius: 8px;
    background: rgba(78, 141, 118, 0.1);
    border: 1px solid rgba(78, 141, 118, 0.3);
    font-size: 0.82rem;
}

.tasks-toast--error {
    background: rgba(220, 38, 38, 0.08);
    border-color: rgba(220, 38, 38, 0.3);
    color: #dc2626;
}

/* The dialog's Who / When / Repeat rows — each a line of radio-or-checkbox choices with their own inline input. */
.task-choice-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem 1.1rem;
}

.task-choice {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.85rem;
    cursor: pointer;
}

.task-choice input[type="date"],
.task-choice input[type="time"],
.task-choice select {
    padding: 0.25rem 0.4rem;
    font-size: 0.85rem;
}

.task-dialog-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.75rem;
}

.task-dialog-actions {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

/* ── Note attachments ──────────────────────────────────────────────
   Own class names rather than the orders dialogs' .woo-doc-* / .woo-attach: that prefix is a historical accident
   already shared by two consumers, and notes' chips are a different shape entirely. */

.note-attach-count {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
}

.note-attach-count svg {
    width: 0.8rem;
    height: 0.8rem;
}

.note-attachments {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}

.note-attachment {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    max-width: 15rem;
    padding: 0.35rem 0.5rem;
    background: var(--glass-bg);
    border: 1px solid var(--glass-border);
    border-radius: 8px;
}

.note-attachment-preview {
    display: grid;
    place-items: center;
    flex-shrink: 0;
    width: 44px;
    height: 44px;
    overflow: hidden;
    border-radius: 6px;
    background: rgba(127, 127, 127, 0.12);
    text-decoration: none;
}

.note-attachment-preview img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.note-attachment-icon {
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--color-text-secondary);
}

.note-attachment-meta {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.note-attachment-name {
    overflow: hidden;
    font-size: 0.78rem;
    color: var(--color-text);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.note-attachment-size {
    font-size: 0.68rem;
    color: var(--color-text-secondary);
    text-decoration: none;
}

.note-attachment-size:hover {
    text-decoration: underline;
}

/* Mirrors .note-del, but always visible — it lives in a dialog, not a hover row. */
.note-attachment-remove {
    flex-shrink: 0;
    padding: 0 0.15rem;
    background: none;
    border: none;
    color: var(--color-text-secondary);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
    transition: color 0.15s;
}

.note-attachment-remove:hover {
    color: var(--color-danger, #e5484d);
}

.note-attach {
    display: inline-flex;
    align-items: center;
    cursor: pointer;
}

.note-attach.is-busy {
    opacity: 0.6;
    pointer-events: none;
}

.note-attach-empty {
    font-size: 0.8rem;
    font-style: italic;
    color: var(--color-text-secondary);
}

/* Sits beside the Attach button, pointing at the clipboard-paste alternative. */
.note-attach-hint {
    margin-left: 0.5rem;
    font-size: 0.75rem;
    color: var(--color-text-secondary);
}

/* ── Dashboard (the landing page) ─────────────────────────────────────
   A responsive grid of glanceable cards. Every figure and row is a link into the page that does the work —
   the dashboard surfaces, it never edits. */
.dash-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
    gap: 1rem;
    align-items: start;
}

.dash-card {
    background: var(--glass-bg);
    border: 1px solid var(--glass-border);
    border-radius: 10px;
    padding: 0.9rem 1rem;
}

.dash-card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.6rem;
}

.dash-card-head h4 {
    margin: 0;
    font-size: 1rem;
}

.dash-card-head h4 a {
    color: inherit;
    text-decoration: none;
}

.dash-card-head h4 a:hover {
    color: var(--color-primary);
}

.dash-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.dash-badge {
    font-size: 0.72rem;
    font-weight: 600;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    background: var(--color-surface-alt, #f0f2f1);
    color: var(--color-text-secondary);
    white-space: nowrap;
}

.dash-badge--red {
    background: rgba(229, 72, 77, 0.14);
    color: #b3261e;
}

.dash-badge--amber {
    background: rgba(176, 106, 0, 0.12);
    color: #8a5300;
}

/* One item line: main text ellipsised, detail right-aligned. Rows that link carry hover feedback. */
.dash-row {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    padding: 0.28rem 0.3rem;
    border-radius: 6px;
    font-size: 0.85rem;
    color: inherit;
    text-decoration: none;
}

a.dash-row:hover {
    background: var(--color-surface-alt, #f0f2f1);
}

.dash-row-main {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dash-row-side {
    flex: 0 0 auto;
    font-size: 0.75rem;
    color: var(--color-text-secondary);
    white-space: nowrap;
}

/* The unread-note marker — the same red as the note rows' unseen shading, condensed to a dot. */
.dash-dot {
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #e5484d;
    align-self: center;
}

.dash-red {
    color: #b3261e;
}

.dash-total,
.dash-note {
    margin: 0.15rem 0.3rem 0.35rem;
    font-size: 0.8rem;
}

.dash-empty {
    margin: 0.15rem 0.3rem;
    font-size: 0.8rem;
    font-style: italic;
    color: var(--color-text-secondary);
}

.dash-more {
    display: block;
    padding: 0.2rem 0.3rem;
    font-size: 0.75rem;
    color: var(--color-text-secondary);
    text-decoration: none;
}

.dash-more:hover {
    color: var(--color-primary);
}

/* ── Per-user read receipts on Notes and Tasks rows ───────────────────
   Red = changed by someone else since you last opened it; yellow = opened, but they had the last word; no
   shading = you touched it last. Deliberately declared AFTER .task-row--overdue so the read signal wins the
   background on an overdue task while its amber border and date colouring stay. */
.note-row--unseen {
    background: rgba(229, 72, 77, 0.10);
}

.note-row--seen {
    background: rgba(240, 185, 30, 0.12);
}

/* ── Resizable / movable note dialog (llbDialog.enhance) ──────────────
   The JS sets resize/overflow and drag positioning; this side makes the layout cooperate: a flex column so
   growing the dialog grows the note textarea (the reason anyone resizes it), and a title bar that reads as
   grabbable. touch-action: none is what lets pointer-event dragging work on a touch screen. */
.modal-dialog.note-dialog {
    display: flex;
    flex-direction: column;
}

.note-dialog .llb-dialog-titlebar {
    cursor: move;
    user-select: none;
    touch-action: none;
}

.note-dialog .note-text-group {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    min-height: 0;
}

.note-dialog .note-text-group textarea {
    flex: 1 1 auto;
    min-height: 6rem;
    /* The dialog's own corner grabber is the resize affordance now — a second one on the textarea fights it. */
    resize: none;
}


/* ═══════════════════════════════════════════════════════════════════
   Linden Leaf Botanicals — botanical reskin
   Same glass-morphism design system as Axe; only the accent and brand
   differ. These rules come last so they override the :root defaults above.
   ═══════════════════════════════════════════════════════════════════ */

:root {
    /* Accent drawn from the brand logo's sage leaf (#7e9591), deepened a touch so buttons and
       links still read as actionable rather than washed-out grey. */
    --color-green: #4e8d76;
    --color-primary: var(--color-green);
    --color-primary-hover: #3f7561;
    --shadow-glow: 0 0 40px rgba(78, 141, 118, 0.14);
}

body {
    background-image:
        radial-gradient(ellipse at 15% 10%, rgba(78, 141, 118, 0.12) 0%, transparent 50%),
        radial-gradient(ellipse at 85% 80%, rgba(74, 144, 217, 0.07) 0%, transparent 50%),
        radial-gradient(ellipse at 50% 50%, rgba(240, 165, 0, 0.04) 0%, transparent 60%);
}

/* ── Brand typeface (Atten New) ──────────────────────────────────────
   LLB's brand font, self-hosted from lindenleaf.co.uk's own licensed
   web-font file. The site publishes Medium/Regular/Book only — there is
   no "Atten New ExtraBold" web file to pull (it's an Adobe Fonts weight),
   so the wordmark uses Medium, the heaviest available. To upgrade to the
   true ExtraBold later: drop an AttenNew-ExtraBold.woff2 into
   wwwroot/fonts, add a second @font-face for it at font-weight 800, then
   bump .brand-wordmark / .mobile-brand to font-weight 800. */
@font-face {
    font-family: 'Atten New';
    src: url('../fonts/AttenNew-Medium.woff') format('woff');
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}

/* ── Brand ───────────────────────────────────────────────────────── */

.sidebar-brand {
    display: flex;
    align-items: center;
    /* Left-aligned logo (overrides the earlier justify-content:center), flush to the rail edge — no margin. The
       65px logo is exactly the box height, so no vertical padding either — it sets the white header box to ~65px. */
    justify-content: flex-start;
    padding: 0;
}

.sidebar-brand .brand-logo {
    width: 58px;
    height: 65px;
    flex: 0 0 auto;
}

/* Wordmark (text.png) centred in the space left of the rail after the logo. */
.brand-text-wrap {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
    overflow: hidden;
}

.brand-text {
    display: block;
}

/* ── Context menu (DataGrid views combo + row menus) ───────────────────
   The GSection.Blazor.DataGrid package styles only `.dg-view-dropdown .ctx-menu-item` (overflow); the BASE
   `.ctx-menu*` look is the app's to provide (as Axe does). Without it LLB's `<button class="ctx-menu-item">`
   fell back to native button chrome — the square boxes on Save as… / Manage views… (issue #40). */
.ctx-menu-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1200;
}

.ctx-menu {
    position: fixed;
    z-index: 1201;
    min-width: 190px;
    padding: 0.3rem;
    background: var(--glass-bg-strong);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border);
    border-radius: 10px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.28);
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.ctx-menu-title {
    padding: 0.4rem 0.55rem 0.45rem;
    margin-bottom: 0.2rem;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--color-text-muted);
    border-bottom: 1px solid var(--glass-border);
    max-width: 260px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ctx-menu-item {
    text-align: left;
    background: transparent;
    border: none;
    color: var(--color-text);
    padding: 0.5rem 0.55rem;
    border-radius: 6px;
    font-size: 0.88rem;
    cursor: pointer;
    white-space: nowrap;
}

.ctx-menu-item:hover {
    background: var(--color-primary);
    color: #fff;
}

.ctx-menu-item-danger {
    color: var(--color-coral);
}

.ctx-menu-item-danger:hover {
    background: var(--color-coral);
    color: #fff;
}

.brand-wordmark {
    font-family: 'Atten New', var(--font-sans);
    font-weight: 500;
    font-size: 1.3rem;
    line-height: 1.15;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--color-text);
}

.mobile-brand {
    font-family: 'Atten New', var(--font-sans);
    font-weight: 500;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--color-text);
}

/* ── Order status badges (extend Axe's badge palette) ────────────── */

.badge-prepared {
    background: #fff8e1;
    color: #f57f17;
}

.badge-pushedtoroyalmail {
    background: #e3f2fd;
    color: #1565c0;
}

.badge-readytosend {
    background: #ede7f6;
    color: #5e35b1;
}

.badge-sent {
    background: #e8f5e9;
    color: #2e7d32;
}

.badge-complete {
    background: #e6f0ec;
    color: #2f6b54;
}

/* ── Generic data table (orders list) ────────────────────────────── */

.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9rem;
}

.data-table thead th {
    text-align: left;
    padding: 0.55rem 0.9rem;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-muted);
    border-bottom: 1px solid var(--color-border);
    white-space: nowrap;
}

.data-table tbody td {
    padding: 0.7rem 0.9rem;
    border-bottom: 1px solid var(--color-border-subtle);
    vertical-align: middle;
}

.data-table tbody tr {
    cursor: pointer;
    transition: background 0.12s ease;
}

.data-table tbody tr:hover {
    background: var(--color-bg-hover);
}

.data-table .num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Data-health report tables are static (not clickable rows) and carry a wordy explanation column, so top-align
   cells and give the narrative a smaller, muted, wrapping treatment. */
.health-table {
    margin-bottom: 1.25rem;
    font-size: 0.85rem;
}

.health-table tbody tr {
    cursor: default;
}

.health-table tbody td {
    vertical-align: top;
}

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

/* ── Detail panels (order workflow page) ─────────────────────────── */

.panel {
    background: var(--glass-bg-strong);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-md);
    padding: 1.25rem 1.4rem;
    box-shadow: var(--shadow-sm);
    margin-bottom: 1.25rem;
}

.panel > h3 {
    font-size: 1rem;
    margin-bottom: 1rem;
}

.panel-hint {
    font-size: 0.85rem;
    color: var(--color-text-secondary);
    margin-top: 0.5rem;
    line-height: 1.5;
}

.kv {
    display: grid;
    grid-template-columns: 180px 1fr;
    gap: 0.45rem 1rem;
    font-size: 0.9rem;
    margin: 0;
}

.kv dt {
    color: var(--color-text-muted);
}

.kv dd {
    margin: 0;
}

.step-note {
    padding: 0.85rem 1rem;
    border-radius: var(--radius-sm);
    background: rgba(47, 158, 107, 0.10);
    border: 1px solid rgba(47, 158, 107, 0.28);
    font-size: 0.88rem;
    line-height: 1.5;
    margin: 0.75rem 0 0;
}

/* Amber variant for advisory warnings (e.g. the W5 missing-duty-stamp banner). */
.step-note.is-warning {
    background: rgba(240, 165, 0, 0.10);
    border-color: rgba(240, 165, 0, 0.35);
}

/* ── Product status badges (WooCommerce post statuses) ────────────── */

.badge-publish {
    background: #e6f4ee;
    color: #2f6b54;
}

.badge-private {
    background: #fff8e1;
    color: #b07a00;
}

.badge-draft,
.badge-pending {
    background: rgba(120, 120, 120, 0.14);
    color: var(--color-text-secondary);
}

/* ── Product catalogue ───────────────────────────────────────────── */

.product-thumb {
    width: 40px;
    height: 40px;
    object-fit: cover;
    border-radius: var(--radius-sm);
    border: 1px solid var(--color-border-subtle);
    display: block;
}

.product-thumb-empty {
    background: var(--color-bg-hover);
}

.product-name {
    font-weight: 600;
}

.product-detail-image {
    width: 180px;
    height: 180px;
    object-fit: cover;
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border-subtle);
    flex: 0 0 auto;
}

.product-description {
    margin-top: 1rem;
    font-size: 0.88rem;
    line-height: 1.55;
    color: var(--color-text-secondary);
}

.product-description img,
.product-description iframe {
    max-width: 100%;
    height: auto;
}

.raw-json {
    margin-top: 0.5rem;
    max-height: 320px;
    overflow: auto;
    background: var(--color-bg-hover);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-sm);
    padding: 0.75rem;
    font-size: 0.72rem;
    line-height: 1.45;
    white-space: pre-wrap;
    word-break: break-word;
}

/* ── Order status badges (WooCommerce order statuses) ─────────────── */

.badge-completed {
    background: #e6f4ee;
    color: #2f6b54;
}

.badge-processing {
    background: #e7f0fb;
    color: #2c5f9e;
}

.badge-refunded {
    background: #fff8e1;
    color: #b07a00;
}

.badge-failed {
    background: #fdecec;
    color: #b23b3b;
}

.badge-checkoutdraft,
.badge-trash {
    background: rgba(120, 120, 120, 0.14);
    color: var(--color-text-secondary);
}

/* ── Sales / customers ───────────────────────────────────────────── */

.mono {
    font-family: ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace;
    font-size: 0.85rem;
}

.detail-heading {
    display: block;
    font-weight: 600;
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--color-text-secondary);
    margin-bottom: 0.4rem;
}

.address-block {
    font-size: 0.88rem;
    line-height: 1.5;
}

/* Bottle-number table rows aren't clickable — drop the data-table row affordance. */
.bottles-table tbody tr {
    cursor: default;
}

.bottles-table tbody tr:hover {
    background: transparent;
}

/* Per-product consecutive fill — the small "Fill ↓" button beside the first bottle-number / duty-stamp input
   of a multi-bottle product, which counts the rest of that product's column up from the number typed there. */
.bottles-cell-fill {
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

.bottles-cell-fill input[type="text"] {
    flex: 1 1 auto;
    min-width: 0;
}

.bottles-cell-fill .btn {
    flex: 0 0 auto;
    white-space: nowrap;
}

/* ── Grouped bottle-number entry (BottleNumbersEditor) ────────────── */

/* The per-product header row: name, SKU, bottle count, cage tick / paste notice, and the mode toggle. */
.bottles-line-head td {
    background: var(--color-surface-alt, #f6f7f8);
    border-top: 2px solid var(--color-border, #e2e6e6);
    padding: 0.45rem 0.7rem;
}

.bottles-line-title {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.9rem;
}

.bottles-line-name {
    font-weight: 600;
}

.bottles-line-sku,
.bottles-line-count {
    font-size: 0.75rem;
    color: var(--color-text-secondary);
    white-space: nowrap;
}

.bottles-line-title .custom-active-row {
    font-size: 0.78rem;
    margin: 0;
}

.bottles-mode-toggle {
    margin-left: auto;
    white-space: nowrap;
}

/* A product that authoritatively carries no duty stamp renders no inputs — just this quiet marker. */
.bottles-duty-none {
    font-size: 0.75rem;
    color: var(--color-text-secondary);
}

/* The grouped first→last pair of inputs, and the status note beneath them. */
.bottles-range {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.bottles-range input[type="text"] {
    flex: 1 1 auto;
    min-width: 0;
}

.bottles-range-arrow {
    flex: 0 0 auto;
    color: var(--color-text-secondary);
}

.bottles-range-note {
    font-size: 0.75rem;
    margin-top: 0.25rem;
}

.bottles-range-note.is-ok {
    color: var(--color-green, #4e8d76);
}

.bottles-range-note.is-warn {
    color: var(--color-gold, #f0a500);
}

.bottles-count-cell,
.bottles-slot-label {
    font-size: 0.8rem;
    color: var(--color-text-secondary);
}

.bottles-count-cell {
    white-space: nowrap;
}

.bottles-paste-notice {
    font-size: 0.75rem;
    color: var(--color-gold, #f0a500);
}

/* Custom product-code inputs on the Products page (table-cell + detail modal). */
.code-input {
    width: 5.5rem;
    padding: 0.3rem 0.45rem;
    font-family: ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace;
    font-size: 0.85rem;
}

/* ── Hidden products (Products page + Settings) ───────────────────── */

/* The "Hidden" tag shown against a hidden product when "Show hidden products" is on. */
.badge-hidden {
    background: rgba(0, 0, 0, 0.06);
    color: var(--color-text-muted);
}

/* A hidden product's row is shown muted (only ever visible when "Show hidden products" is on). */
.data-table tbody tr.row-hidden td {
    opacity: 0.55;
}

.data-table tbody tr.row-hidden:hover td {
    opacity: 0.75;
}

/* The same muting for the DataGrid (hidden shop products on the Products grid, retired custom products). */
.dg-row.row-hidden td {
    opacity: 0.55;
}

.dg-row.row-hidden:hover td {
    opacity: 0.75;
}

/* ── Custom (off-shop) products (Products page) ───────────────────── */

/* The "Custom" tag shown against an LLB-authored off-shop product, in the brand sage. */
.badge-custom {
    background: rgba(78, 141, 118, 0.14);
    color: var(--color-green, #4e8d76);
}

/* The "Your own products" section sits below the shop catalogue grid. */
.custom-products {
    margin-top: 2rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--color-border, rgba(0, 0, 0, 0.08));
}

.custom-products-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.9rem;
}

/* The Active checkbox row in the custom-product modal. */
.custom-active-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.9rem;
    cursor: pointer;
    font-size: 0.9rem;
}

.custom-active-row input {
    width: auto;
    margin: 0;
}

/* Settings page — a labelled toggle row. */
.settings-toggle {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    cursor: pointer;
}

.settings-toggle input[type="checkbox"] {
    width: 1.1rem;
    height: 1.1rem;
    margin-top: 0.15rem;
    flex: 0 0 auto;
    cursor: pointer;
}

.settings-toggle .settings-toggle-label {
    font-weight: 600;
}

.settings-toggle .settings-toggle-hint {
    margin: 0.15rem 0 0;
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

/* ── Sortable table headers (Products list) ──────────────────────── */

/* A clickable column header: click to sort by it, click again to reverse. */
.data-table thead th.sortable {
    cursor: pointer;
    user-select: none;
}

.data-table thead th.sortable:hover {
    color: var(--color-text-secondary);
}

/* The active sort column reads in the brand colour so it's obvious what the list is ordered by. */
.data-table thead th.sortable.sorted {
    color: var(--color-primary);
}

/* The ▲/▼ arrow next to the active column's label. A fixed-width slot keeps headers from shifting
   as the indicator appears/disappears (on .num columns it sits just left of the right-aligned label). */
.data-table thead th.sortable .sort-indicator {
    display: inline-block;
    width: 0.85em;
    margin-left: 0.25rem;
    font-size: 0.7em;
    color: var(--color-primary);
}

/* ── Payment-method glyphs (Sales + Orders pay column) ───────────────
   Brand-coloured inline SVGs rendered from the payment method string; used inside the DataGrid
   pay column on both pages. (The old hand-rolled .sales-table-scroll / .sales-grid bitmap matrix
   and .sales-list order sheet were retired when Sales moved to the shared DataGrid — llb#35.) */
.pay-glyph {
    width: 18px;
    height: 18px;
    display: inline-block;
    vertical-align: middle;
}

/* Brand colours for the payment glyphs. The glyphs use currentColor for both fill and stroke, so a single
   `color` paints each one its brand colour; an unbranded glyph keeps the muted cell colour. */
.pay-glyph.pay-apple { color: #000000; }   /* Apple Pay — black mark */
.pay-glyph.pay-google { color: #4285f4; }  /* Google Pay — Google blue */
.pay-glyph.pay-paypal { color: #003087; }  /* PayPal — PayPal blue */
.pay-glyph.pay-card { color: #635bff; }    /* Card payments (Stripe) — Stripe indigo */

/* ── Sales MATRIX column inside the shared DataGrid ──────────────────
   The Matrix is now ONE movable/hideable column (Id="matrix"), not ~30 product columns. Its HeaderTemplate and
   cell Template each render a horizontal strip of 1.15rem sub-cells — rotated product labels in the header,
   coloured quantities in the cells — in the same order (_matrixUnits), so header and cells line up. The set of
   sub-cells adapts to the rows on the grid. Everything is scoped to .matrix-single / .matrix-strip so the rest of
   the grid (same .dg-table) is untouched. The 1.15rem sub-cell width MUST match the column width calc() in
   Sales.razor (Width = calc(N * 1.15rem)). */
.dg-table th.matrix-single,
.dg-table td.matrix-single {
    padding: 0;
    border-left: 1px solid var(--color-border-subtle);
    vertical-align: bottom;
}

/* The strip that both the header and each cell render — a flex row of fixed-width sub-cells. */
.matrix-strip {
    display: flex;
    align-items: stretch;
    height: 100%;
}

/* Header strip: rotated labels bottom-aligned to where the cells begin. */
.matrix-strip-head {
    align-items: flex-end;
}

.matrix-strip .matrix-lbl,
.matrix-strip .matrix-cell {
    flex: 0 0 1.15rem;
    width: 1.15rem;
    min-width: 1.15rem;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.62rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    /* hairline between sub-cells without affecting layout width */
    box-shadow: inset -1px 0 0 var(--color-border-subtle);
}

/* Rotated single-line product labels in the header (auto height, bottom-aligned by the strip above). */
.matrix-strip-head .matrix-lbl {
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    padding: 0.3rem 0;
    font-size: 0.6rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    color: var(--color-text-secondary);
}

.matrix-strip .matrix-cell {
    min-height: 1.4rem;
    color: var(--color-text-primary);
}

/* Filled-cell colours, per product — the same palette as before: gin green, the three named cocktail elements by
   their fruit colour, the 3-pack set tri-banded (vertical bands in the narrow cell); everything else plain white. */
.matrix-strip .matrix-cell.cell-gin { background: #c9e8cf; color: #14532a; }
.matrix-strip .matrix-cell.cell-orange { background: #ffd9a3; color: #7a3e00; }
.matrix-strip .matrix-cell.cell-lemon { background: #fff1a6; color: #6b5600; }
.matrix-strip .matrix-cell.cell-lime { background: #d6f0b0; color: #355e10; }
.matrix-strip .matrix-cell.cell-ceset { background: linear-gradient(180deg, #ffd9a3 0 33.33%, #fff1a6 33.33% 66.66%, #d6f0b0 66.66%); color: #5a4500; }

/* ── WooCommerce order navigator dialog ──────────────────────────────────────────────────────────
   Master–detail layout: a left rail of stages, a scrolling main area, a top status dropdown and a
   footer status bar. All classes are scoped under .woo-* so no other page's modal/form layout is
   touched. Uses the shared .modal-flex shell (pinned header/footer + inner scroll). */
/* Fixed height so the dialog never resizes as you move between stages — it's as tall as the tallest stage
   needs (capped to the viewport), and the main area scrolls when a stage's content overflows. */
.woo-dialog {
    height: min(90dvh, 840px);
}

.woo-header {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-bottom: 0.75rem;
}

.woo-header h4 {
    margin: 0;
    font-size: 1.05rem;
}

.woo-topbar {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding-bottom: 0.75rem;
    margin-bottom: 0.75rem;
    border-bottom: 1px solid var(--color-border);
}

/* Sits last in .woo-topbar; margin-left:auto pushes it to the far right of the row (top right of the dialog),
   away from the status dropdown and well clear of the routine OK button in the footer. */
.woo-delete-btn {
    margin-left: auto;
}

.woo-status-label {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--color-text-secondary);
}

.woo-status-select {
    flex: 0 0 220px;
}

.woo-body {
    display: flex;
    gap: 1.25rem;
    flex: 1;
    min-height: 0;
    overflow: hidden;
}

/* Width is hand-fitted to the longest label rather than content-sized (max-content), because the active
   item is semibold — a content-sized rail would jog a few px wider whenever the longest stage happens to
   be selected, twitching the whole main panel. 160px = "Information" + its glyph, with roughly three
   characters' padding either side of the pill. */
.woo-nav {
    flex: 0 0 160px;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    padding-right: 0.6rem;
    border-right: 1px solid var(--color-border);
    overflow-y: auto;
}

.woo-nav-item {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    width: 100%;
    padding: 0.55rem 1.5rem;
    white-space: nowrap;
    border: none;
    background: transparent;
    border-radius: var(--radius-sm);
    text-align: left;
    font-size: 0.9rem;
    color: var(--color-text);
    cursor: pointer;
}

.woo-nav-item:hover {
    background: var(--color-bg-hover);
}

.woo-nav-item.active {
    background: rgba(78, 141, 118, 0.12);
    color: var(--color-primary);
    font-weight: 600;
}

.woo-nav-item:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: -2px;
}

.woo-nav-glyph {
    flex: 0 0 auto;
    width: 1.1rem;
    font-size: 0.85rem;
    text-align: center;
}

.woo-nav-glyph.is-complete { color: var(--color-green); }
.woo-nav-glyph.is-warning { color: var(--color-gold); }

.woo-main {
    flex: 1;
    min-width: 0;
    padding-right: 0.25rem;
    overflow-y: auto;
    /* overflow-y:auto alone makes overflow-x compute to auto too, adding a stray horizontal scrollbar; pin it. */
    overflow-x: hidden;
    /* The dialog is a fixed width, so long text/URLs/tracking numbers wrap here instead of widening it. */
    overflow-wrap: break-word;
}

.woo-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--color-border);
}

.woo-status-summary {
    font-size: 0.85rem;
    color: var(--color-text-secondary);
}

.woo-status-summary.is-ready {
    color: var(--color-green);
    font-weight: 600;
}

.woo-history {
    margin-top: 0;
}

/* Required-attestation tick rows (W5 / Xero / OneDrive / Mukund) — a checkbox followed by its label. */
.woo-required-tick {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.5rem;
    font-size: 0.85rem;
    cursor: pointer;
}

.woo-tick-note {
    color: var(--color-text-secondary);
    font-size: 0.78rem;
}

/* Ticks sitting side by side rather than stacked (Xero / OneDrive on the Postage stage). */
.woo-tick-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1.75rem;
    margin-top: 0.6rem;
}

.woo-tick-row .woo-required-tick {
    margin-top: 0;
}

.woo-attach {
    display: inline-flex;
    align-items: center;
    cursor: pointer;
}

/* The action buttons of a documents row. They have to share one grid cell: .woo-doc-row is a three-column grid,
   so a second button (Generate beside Attach) would otherwise become a fourth child and wrap onto its own line. */
.woo-doc-actions {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    /* Holds the row's height when it has no button to show (a Xero bill with no VAT receipt to raise it from),
       so rows don't shrink and grow as their state changes. */
    min-height: 1.85rem;
}

/* Remove / Generate / Attach / Reset… read as one set of controls, so they are sized as one. An explicit height
   with no vertical padding is what makes them match: Attach is a <label> and the rest are <button>s, and the two
   size differently from their own user-agent styles even given identical classes. */
/* Both selectors are two-class on purpose: .btn-sm is declared further down and its padding shorthand would
   otherwise win the vertical padding back on equal specificity. */
.woo-doc-actions .btn,
.btn.woo-action-btn {
    min-width: 5.5rem;
    height: 1.85rem;
    padding-top: 0;
    padding-bottom: 0;
    justify-content: center;
}

.btn-sm {
    padding: 0.3rem 0.7rem;
    font-size: 0.78rem;
}

/* ── Postage stage layout ─────────────────────────────────────────── */

/* Divider between the stage's blocks (package / Royal Mail / cost / documents). */
.woo-rule {
    border: 0;
    border-top: 1px solid var(--color-border);
    margin: 1.25rem 0;
}

/* Block heading + inline state on the left, action buttons pushed right. */
.woo-section-head {
    display: flex;
    align-items: center;
    gap: 0.75rem 1rem;
    flex-wrap: wrap;
    margin-bottom: 0.75rem;
}

.woo-section-head .detail-heading {
    margin-bottom: 0;
}

.woo-section-meta {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    font-size: 0.82rem;
    color: var(--color-text-secondary);
}

.woo-section-meta strong {
    color: var(--color-text);
    font-weight: 600;
}

.woo-section-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-left: auto;
}

/* The Click & Drop section head: identity (heading + C&D order number) on the left, the one action and its
   timestamp stacked on the right. Top-aligned rather than centred, so the button sits level with the heading
   whether or not the order has been pushed yet. */
.woo-cd-head {
    align-items: flex-start;
}

.woo-cd-identity {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.woo-cd-actions {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.35rem;
    margin-left: auto;
    text-align: right;
}

/* Open in Click & Drop / Track are jump-outs, not actions on the order, so they read as links rather than
   competing with the real buttons above them. */
.woo-cd-links {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.3rem;
    margin: 0 0 0.85rem;
    font-size: 0.85rem;
}

/* Document rows on the Postage stage: kind | link + uploaded | action. */
.woo-doc-table {
    display: flex;
    flex-direction: column;
}

.woo-doc-row {
    display: grid;
    grid-template-columns: 150px 1fr auto;
    align-items: center;
    gap: 0.4rem 1rem;
    padding: 0.45rem 0.6rem;
    border-radius: 6px;
}

.woo-doc-row:nth-child(odd) {
    background: var(--color-bg-subtle);
}

.woo-doc-label {
    font-size: 0.85rem;
    color: var(--color-text-secondary);
}

.woo-doc-file {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    min-width: 0;
    font-size: 0.85rem;
}

.woo-doc-file a {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
}

/* Money input with the £ sitting inside the field. Wraps the <input> only (not its label), so the symbol
   centres on the box rather than on the whole label + input stack. */
.money-input {
    position: relative;
    display: flex;
}

.money-input::before {
    content: "£";
    position: absolute;
    left: 0.65rem;
    top: 50%;
    transform: translateY(-50%);
    font-size: 0.85rem;
    color: var(--color-text-muted);
    pointer-events: none;
}

.money-input input {
    flex: 1 1 auto;
    min-width: 0;
    padding-left: 1.5rem;
}

/* The derived VAT figure sitting beside the two postage boxes, baseline-aligned with them. */
.money-note {
    align-self: flex-end;
    padding-bottom: 0.45rem;
    font-size: 0.85rem;
    white-space: nowrap;
}

/* ── Xero create-invoice dialog (XeroInvoiceDialog) ─────────────────────────────────────────────────────── */

/* The contact-matching result list: one radio row per candidate contact plus the explicit create-new row. */
.xero-contact-results {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    max-height: 240px;
    overflow-y: auto;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    padding: 0.4rem;
}

.xero-contact-option {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.35rem 0.5rem;
    border-radius: 5px;
    cursor: pointer;
    font-size: 0.9rem;
}

.xero-contact-option:hover {
    background: var(--color-bg-hover);
}

.xero-contact-option.is-selected {
    background: rgba(78, 141, 118, 0.12);
}

.xero-contact-option input[type="radio"] {
    margin: 0;
    flex: 0 0 auto;
}

.xero-contact-name {
    font-weight: 600;
    white-space: nowrap;
}

.xero-contact-meta {
    display: flex;
    gap: 0.75rem;
    min-width: 0;
    color: var(--color-text-muted);
    font-size: 0.8rem;
}

.xero-contact-meta span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.xero-new-contact-name {
    flex: 1 1 auto;
    min-width: 0;
}

.xero-postage-options {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    font-size: 0.9rem;
}

.xero-postage-options input[type="radio"] {
    margin-right: 0.4rem;
}

/* The read-only draft-lines preview — a plain compact table, not a DataGrid (four columns, a handful of rows). */
.xero-preview-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
}

.xero-preview-table th {
    text-align: left;
    font-weight: 600;
    color: var(--color-text-muted);
    border-bottom: 1px solid var(--color-border);
    padding: 0.3rem 0.5rem;
}

.xero-preview-table td {
    padding: 0.3rem 0.5rem;
    border-bottom: 1px solid var(--color-border-subtle);
}

.xero-preview-table .num {
    text-align: right;
    white-space: nowrap;
}

/* ── Company edit dialog (Companies page) ────────────────────────────────────────────────────────
   Fixed-size four-tab dialog (Main | Accounting | Delivery | Orders) — the same pinned-header/footer +
   internally-scrolling-body shape as the .woo-dialog navigator, so switching tabs never resizes it.
   Uses the shared .modal-flex shell; everything here is scoped under .company-*. */
.company-dialog {
    height: min(90dvh, 780px);
}

/* Tab strip pinned under the title. The underline rule gives .tab's -1px-overlapping active border
   something to sit on (elsewhere .toolbar-tabs sits on a toolbar that provides its own rule). */
.company-tabs {
    flex: 0 0 auto;
    border-bottom: 1px solid var(--color-border);
    margin-bottom: 1rem;
}

.company-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    /* overflow-y:auto alone makes overflow-x compute to auto too, adding a stray horizontal scrollbar; pin it. */
    overflow-x: hidden;
    /* The dialog is a fixed width, so long text/emails wrap here instead of widening it. */
    overflow-wrap: break-word;
    padding-right: 0.25rem;
}

/* Orders tab: the body stops scrolling itself and becomes a column — the stat tiles stay put and the
   order table takes the remaining height with its own internal scroll. */
.company-body.company-body-orders {
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.company-stats {
    flex: 0 0 auto;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0.75rem;
    margin-bottom: 1rem;
}

.stat-tile {
    background: var(--color-bg-subtle);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-md);
    padding: 0.7rem 0.9rem;
}

.stat-tile-label {
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-muted);
    margin-bottom: 0.2rem;
}

.stat-tile-value {
    font-size: 1.2rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.stat-tile-sub {
    font-size: 0.7rem;
    color: var(--color-text-muted);
    margin-top: 0.15rem;
}

.company-orders-scroll {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-sm);
}

/* Sticky header needs its own opaque-ish background or scrolled rows show through the glass theme. */
.company-orders-scroll .data-table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--glass-bg-strong);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}

/* Footer pinned below the scrolling body. Button DOM order keeps Close rightmost per the house rule. */
.company-footer {
    flex: 0 0 auto;
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--color-border);
}

/* ── Data-integrity report lists (Settings → Data integrity) ───────── */

/* Findings are one-line facts, often long (a company name plus its key, a duty code plus a date). Wrapping is
   right — truncating a finding hides the identifier that makes it actionable. */
.integrity-list {
    margin: 0.35rem 0 0;
    padding-left: 1.15rem;
    font-size: 0.85rem;
    line-height: 1.55;
    color: var(--color-text-secondary);
}

.integrity-list li {
    margin-bottom: 0.15rem;
    overflow-wrap: anywhere;
}
