/* =============================================================
   Customer Portal — full-width, compact, theme-token driven.

   Chrome comes from CustomerPortalLayout.razor. Every colour flows
   through theme.css tokens so light/dark/notion/vintage all look
   correct. Stage colours (posted=warning, checked-in=info,
   weighed-in=violet, weighed-out=success) stay semantic-recognisable
   regardless of theme.
   ============================================================= */

/* ══════════════════════════════════════════════════════════
   OVERRIDE site.css defaults — the global <app> element uses
   `display: flex; flex-direction: column` (or `row` at desktop
   breakpoints) which constrains the portal to the natural width
   of its children instead of filling the viewport. Force the
   <app> wrapper back to block layout whenever the portal shell
   is being rendered inside it. :has() is supported on every
   modern browser as of 2023+.
   ══════════════════════════════════════════════════════════ */
app:has(.cp-shell) {
    display: block !important;
    width: 100% !important;
    max-width: none !important;
}

/* ══════════════════════════════════════════════════════════
   STAGE COLOUR SYSTEM — scoped to `.cp-shell` so it never
   leaks into the rest of the app. Each stage defines three
   shades:
     • --cp-X         — the brand colour (borders, solid fills)
     • --cp-X-strong  — darker variant for TEXT on light tints
                        (WCAG AA 4.5:1 against white)
     • --cp-X-tint    — ~10% translucent for tinted backgrounds
   Dark themes override each var with brighter shades so the
   colours stay legible against dark surfaces.
   ══════════════════════════════════════════════════════════ */
.cp-shell {
    /* Light-mode stage palette — amber / blue / violet / emerald
       chosen specifically for 4.5:1+ contrast as text on white. */
    --cp-posted:         #d97706;  /* amber-600   */
    --cp-posted-strong:  #b45309;  /* amber-700   */
    --cp-posted-tint:    rgba(217, 119, 6, 0.10);

    --cp-checkedin:        #2563eb;  /* blue-600   */
    --cp-checkedin-strong: #1d4ed8;  /* blue-700   */
    --cp-checkedin-tint:   rgba(37, 99, 235, 0.10);

    --cp-weighedin:        #7c3aed;  /* violet-600 */
    --cp-weighedin-strong: #6d28d9;  /* violet-700 */
    --cp-weighedin-tint:   rgba(124, 58, 237, 0.10);

    --cp-weighedout:        #059669;  /* emerald-600 */
    --cp-weighedout-strong: #047857;  /* emerald-700 */
    --cp-weighedout-tint:   rgba(5, 150, 105, 0.10);

    /* Fixed "solid" shades — used for filled pills / active chips where
       the FG text is always white. Same value in light + dark mode so
       white text stays WCAG AA in every theme. (Brighter amber-400 on
       dark mode + white text would fail 1.6:1 — this is the fix.) */
    --cp-posted-solid:     #d97706;
    --cp-checkedin-solid:  #2563eb;
    --cp-weighedin-solid:  #7c3aed;
    --cp-weighedout-solid: #047857;

    width: 100%;
    min-height: 100vh;
    min-height: 100dvh;            /* true viewport height on mobile browsers */
    display: flex;
    flex-direction: column;
    background: var(--bg-primary);
    color: var(--text-primary);
    font-family: 'Inter', 'Segoe UI', sans-serif;
}

/* Dark-theme overrides — brighter shades, stronger tints. */
[data-theme="dark"] .cp-shell,
[data-theme="meta-dark"] .cp-shell,
[data-theme="wa-dark"] .cp-shell,
[data-theme="spotify"] .cp-shell {
    --cp-posted:         #fbbf24;  /* amber-400 */
    --cp-posted-strong:  #fde68a;  /* amber-200 — text on dark bg */
    --cp-posted-tint:    rgba(251, 191, 36, 0.18);

    --cp-checkedin:        #60a5fa;  /* blue-400 */
    --cp-checkedin-strong: #bfdbfe;  /* blue-200 */
    --cp-checkedin-tint:   rgba(96, 165, 250, 0.18);

    --cp-weighedin:        #a78bfa;  /* violet-400 */
    --cp-weighedin-strong: #ddd6fe;  /* violet-200 */
    --cp-weighedin-tint:   rgba(167, 139, 250, 0.18);

    --cp-weighedout:        #34d399;  /* emerald-400 */
    --cp-weighedout-strong: #a7f3d0;  /* emerald-200 */
    --cp-weighedout-tint:   rgba(52, 211, 153, 0.18);
}

/* ══════════════════════════════════════════════════════════
   TOP BAR — premium dark chrome with subtle gradient + pink
   accent underline. Sticky, low-profile, but still has enough
   presence to feel "brand chrome" rather than "page content".

   Colours are HARD-CODED dark (not `var(--chrome-bg)`), because
   `--chrome-bg` flips to warm-white under the notion theme and
   other light schemes — which broke the gradient's top half into
   a jarring white strip. Brand chrome shouldn't ride the theme
   picker anyway; it should read the same across every theme.
   ══════════════════════════════════════════════════════════ */
.cp-topbar {
    position: sticky;
    top: 0;
    z-index: 50;
    background: linear-gradient(180deg, #1a1a1a 0%, #111111 100%);
    color: #f3f3f3;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.4);
}

/* Hot-pink gradient accent line underneath — brand tie-in */
.cp-topbar-accent {
    height: 2px;
    background: linear-gradient(90deg,
        transparent 0%,
        var(--accent-tertiary) 30%,
        var(--accent-primary) 50%,
        var(--accent-tertiary) 70%,
        transparent 100%);
    opacity: 0.85;
}

.cp-topbar-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 14px;
}

@media (min-width: 768px) {
    .cp-topbar-inner { padding: 12px 20px; }
}

/* Brand cluster (logo + text) — clickable, subtle hover feedback */
.cp-brand {
    display: flex;
    align-items: center;
    gap: 11px;
    min-width: 0;
    text-decoration: none;
    color: inherit;
    padding: 4px 8px 4px 2px;
    border-radius: 10px;
    transition: background 0.15s ease;
}

.cp-brand:hover { background: rgba(255, 255, 255, 0.04); }

.cp-brand-logo {
    width: 36px;
    height: 36px;
    object-fit: contain;
    border-radius: 8px;
    flex-shrink: 0;
    filter: drop-shadow(0 2px 8px var(--accent-30));
}

@media (min-width: 768px) {
    .cp-brand-logo { width: 40px; height: 40px; }
}

.cp-brand-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
    line-height: 1.15;
}

.cp-brand-name {
    font-weight: 700;
    font-size: 0.95rem;
    letter-spacing: -0.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: #ffffff;
}

@media (min-width: 768px) {
    .cp-brand-name { font-size: 1.02rem; }
}

.cp-brand-sub {
    font-size: 0.62rem;
    color: rgba(255, 255, 255, 0.55);  /* fixed — chrome is always dark */
    letter-spacing: 0.14em;
    text-transform: uppercase;
    font-weight: 700;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 1px;
}

.cp-brand-dot {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--accent-primary);
    box-shadow: 0 0 8px var(--accent-primary);
    flex-shrink: 0;
}

.cp-topbar-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}

/* Live indicator — pulsing green dot + "Live" text. Visual reassurance
   to the customer that the connection is healthy. */
.cp-live {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 10px;
    border-radius: 999px;
    background: rgba(42, 213, 189, 0.12);
    color: var(--success);
    border: 1px solid rgba(42, 213, 189, 0.25);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.cp-live-pulse {
    width: 7px;
    height: 7px;
    background: var(--success);
    border-radius: 50%;
    box-shadow: 0 0 0 0 rgba(42, 213, 189, 0.6);
    animation: cp-live-pulse 2s ease-out infinite;
}

@keyframes cp-live-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(42, 213, 189, 0.55); }
    70%  { box-shadow: 0 0 0 8px rgba(42, 213, 189, 0); }
    100% { box-shadow: 0 0 0 0 rgba(42, 213, 189, 0); }
}

.cp-live-text {
    line-height: 1;
}

/* Icon button (theme toggle) */
.cp-icon-btn {
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 10px;
    color: inherit;
    width: 38px;
    height: 38px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background 0.15s ease, transform 0.1s ease, border-color 0.15s ease;
}

.cp-icon-btn:hover {
    background: rgba(255, 255, 255, 0.12);
    border-color: rgba(255, 255, 255, 0.18);
}

.cp-icon-btn:active { transform: scale(0.95); }

.cp-icon-btn [data-lucide] { width: 17px; height: 17px; }

/* User avatar — accent gradient circle with initials */
.cp-avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary));
    color: var(--on-accent);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 800;
    font-size: 0.78rem;
    letter-spacing: 0.02em;
    box-shadow: 0 2px 10px var(--accent-30);
    border: 2px solid rgba(255, 255, 255, 0.1);
    flex-shrink: 0;
    user-select: none;
}

/* Logout button */
.cp-logout-btn {
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 10px;
    color: inherit;
    height: 38px;
    padding: 0 14px;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    cursor: pointer;
    font-weight: 600;
    font-size: 0.83rem;
    font-family: inherit;
    transition: all 0.15s ease;
}

.cp-logout-btn:hover {
    background: var(--error);
    border-color: var(--error);
    color: #fff;
}

.cp-logout-btn [data-lucide] { width: 16px; height: 16px; }

/* Mobile — hide non-essentials, let brand + avatar + logout fit */
@media (max-width: 640px) {
    .cp-live-text { display: none; }
    .cp-live {
        padding: 6px;
        background: transparent;
        border-color: transparent;
    }
    .cp-brand-name { font-size: 0.9rem; }
    .cp-brand-sub  { font-size: 0.58rem; letter-spacing: 0.1em; }
}

@media (max-width: 480px) {
    .cp-logout-text { display: none; }
    .cp-logout-btn { padding: 0; width: 38px; justify-content: center; }
    .cp-avatar     { width: 34px; height: 34px; font-size: 0.72rem; }
    .cp-brand-logo { width: 32px; height: 32px; }
    .cp-topbar-inner { padding: 9px 10px; gap: 8px; }
    .cp-topbar-actions { gap: 6px; }
}

@media (max-width: 380px) {
    .cp-brand-text    { display: none; }
    .cp-live          { display: none; }
}

/* ══════════════════════════════════════════════════════════
   MAIN CONTENT — full-viewport width. Minimal outer padding
   so the grid breathes just a hair from the edges but doesn't
   waste screen real estate.
   ══════════════════════════════════════════════════════════ */
.cp-main {
    flex: 1;
    width: 100%;
    margin: 0;
    padding: 10px 8px 40px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

@media (min-width: 640px)  { .cp-main { padding: 12px 12px 50px; gap: 12px; } }
@media (min-width: 1024px) { .cp-main { padding: 14px 14px 60px; gap: 14px; } }

.cp-hide-sm { display: inline; }
@media (max-width: 640px) { .cp-hide-sm { display: none; } }

/* ── Loading / access-denied ──────────────────────────── */
.cp-loading,
.cp-access-denied {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 40px 20px;
    text-align: center;
    color: var(--text-secondary);
    min-height: 50vh;
}

.cp-loading [data-lucide] {
    width: 32px;
    height: 32px;
    color: var(--accent-primary);
}

.cp-access-denied h2 {
    margin: 8px 0 4px;
    color: var(--text-primary);
    font-weight: 700;
    font-size: 1.4rem;
}

.cp-access-denied p { margin: 0; max-width: 420px; }

.cp-denied-icon {
    width: 48px;
    height: 48px;
    color: var(--error);
    margin-bottom: 8px;
}

.cp-denied-help {
    font-size: 0.85rem;
    color: var(--text-muted);
}

/* ── Hero (tight) ─────────────────────────────────────── */
.cp-hero {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 16px;
    background: linear-gradient(135deg, var(--surface) 0%, var(--surface-warm) 100%);
    border: 1px solid var(--border-primary);
    border-radius: 14px;
    box-shadow: var(--shadow-sm);
    flex-wrap: wrap;
}

.cp-hero > div { min-width: 0; flex: 1 1 240px; }

.cp-hero-title {
    margin: 0;
    font-weight: 800;
    font-size: 1.25rem;
    letter-spacing: -0.01em;
    line-height: 1.15;
    color: var(--text-primary);
}

.cp-hero-sub {
    margin: 4px 0 0;
    color: var(--text-secondary);
    font-size: 0.85rem;
    line-height: 1.4;
}

.cp-hero-sub strong { color: var(--text-primary); font-weight: 700; }
.cp-hero-sub em     { font-style: normal; color: var(--accent-primary); font-weight: 600; }

.cp-hero-refresh { flex-shrink: 0; }

/* ── Section ──────────────────────────────────────────── */
.cp-section {
    background: var(--surface);
    border: 1px solid var(--border-primary);
    border-radius: 14px;
    padding: 14px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    box-shadow: var(--shadow-sm);
}

.cp-section-tight { padding: 12px 14px; gap: 10px; }
.cp-section-grid  { padding: 10px; gap: 10px; }

@media (min-width: 1024px) {
    .cp-section        { padding: 18px; gap: 14px; }
    .cp-section-tight  { padding: 14px 18px; gap: 12px; }
    .cp-section-grid   { padding: 14px; gap: 12px; }
}

.cp-section-hdr {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.cp-section-title {
    margin: 0;
    font-weight: 700;
    font-size: 1rem;
    color: var(--text-primary);
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.cp-section-title [data-lucide] {
    width: 17px;
    height: 17px;
    color: var(--accent-primary);
}

.cp-section-count {
    background: var(--accent-light);
    color: var(--accent-primary);
    padding: 1px 10px;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
}

/* ── Buttons ──────────────────────────────────────────── */
.cp-btn {
    background: transparent;
    color: var(--text-primary);
    border: 1px solid var(--border-primary);
    border-radius: 8px;
    padding: 7px 12px;
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: all 0.15s ease;
    font-family: inherit;
    white-space: nowrap;
}

.cp-btn [data-lucide] { width: 15px; height: 15px; }
.cp-btn:hover:not(:disabled) { background: var(--bg-secondary); }
.cp-btn:active:not(:disabled) { transform: scale(0.98); }
.cp-btn:disabled { opacity: 0.55; cursor: not-allowed; }

.cp-btn-primary {
    background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary));
    color: var(--on-accent);
    border-color: var(--accent-primary);
    box-shadow: var(--shadow-accent-sm);
}

.cp-btn-primary:hover:not(:disabled) {
    filter: brightness(1.08);
    box-shadow: var(--shadow-accent-md);
}

.cp-btn-ghost {
    background: transparent;
    border-color: transparent;
    color: var(--text-secondary);
    padding: 6px 10px;
}

.cp-btn-ghost:hover:not(:disabled) {
    background: var(--bg-secondary);
    color: var(--text-primary);
}

.cp-btn-save {
    min-width: 78px;
    justify-content: center;
    padding: 7px 10px;
}

/* ── Filter chips (replaces stage-stats row) ─────────── */
.cp-chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 2px 0;
}

.cp-chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 12px;
    border-radius: 999px;
    border: 1px solid var(--border-primary);
    background: var(--bg-secondary);
    color: var(--text-secondary);
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.18s ease, color 0.18s ease,
                border-color 0.18s ease, box-shadow 0.18s ease,
                transform 0.1s ease;
    font-family: inherit;
    white-space: nowrap;
}

/* Tactile feedback on click — chip subtly compresses */
.cp-chip:active { transform: scale(0.96); }

.cp-chip [data-lucide] {
    width: 14px;
    height: 14px;
    opacity: 0.8;
}

.cp-chip:hover {
    border-color: var(--text-muted);
    color: var(--text-primary);
}

.cp-chip-count {
    background: var(--bg-tertiary);
    color: var(--text-primary);
    padding: 1px 8px;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 800;
    min-width: 24px;
    text-align: center;
    font-variant-numeric: tabular-nums;
    line-height: 1.5;
}

.cp-chip.is-active {
    background: var(--accent-primary);
    color: var(--on-accent);
    border-color: var(--accent-primary);
    box-shadow: var(--shadow-accent-sm);
}

.cp-chip.is-active [data-lucide] { opacity: 1; }
.cp-chip.is-active .cp-chip-count { background: rgba(255, 255, 255, 0.25); color: #fff; }

/* Stage-specific chip accents when active — always readable,
   uses the "-solid" fixed shade so white text passes AA in every theme. */
.cp-chip.cp-chip-posted.is-active      { background: var(--cp-posted-solid);     border-color: var(--cp-posted-solid); }
.cp-chip.cp-chip-checked-in.is-active  { background: var(--cp-checkedin-solid);  border-color: var(--cp-checkedin-solid); }
.cp-chip.cp-chip-weighed-in.is-active  { background: var(--cp-weighedin-solid);  border-color: var(--cp-weighedin-solid); }
.cp-chip.cp-chip-weighed-out.is-active { background: var(--cp-weighedout-solid); border-color: var(--cp-weighedout-solid); }

/* Subtle coloured hover for non-active chips — lifts the icon
   colour so you know which stage the chip represents before you click. */
.cp-chip.cp-chip-posted:hover:not(.is-active)      { color: var(--cp-posted-strong);     border-color: var(--cp-posted); }
.cp-chip.cp-chip-checked-in:hover:not(.is-active)  { color: var(--cp-checkedin-strong);  border-color: var(--cp-checkedin); }
.cp-chip.cp-chip-weighed-in:hover:not(.is-active)  { color: var(--cp-weighedin-strong);  border-color: var(--cp-weighedin); }
.cp-chip.cp-chip-weighed-out:hover:not(.is-active) { color: var(--cp-weighedout-strong); border-color: var(--cp-weighedout); }

/* ── Search strip ─────────────────────────────────────── */
.cp-search-strip {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.cp-search {
    position: relative;
    display: flex;
    align-items: center;
    flex: 1;
    min-width: 220px;
}

.cp-search > [data-lucide] {
    position: absolute;
    left: 10px;
    width: 15px;
    height: 15px;
    color: var(--text-muted);
    pointer-events: none;
}

.cp-search input {
    width: 100%;
    background: var(--bg-secondary);
    color: var(--text-primary);
    border: 1px solid var(--border-primary);
    border-radius: 10px;
    padding: 8px 34px 8px 34px;
    font-size: 0.88rem;
    font-family: inherit;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.cp-search input:focus {
    outline: none;
    border-color: var(--accent-primary);
    box-shadow: 0 0 0 3px var(--accent-15);
}

.cp-search-clear {
    position: absolute;
    right: 6px;
    background: transparent;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 4px;
    border-radius: 6px;
    display: flex;
}

.cp-search-clear:hover {
    color: var(--text-primary);
    background: var(--bg-primary);
}

.cp-search-clear [data-lucide] {
    position: static;
    width: 13px;
    height: 13px;
}

.cp-result-count {
    font-size: 0.78rem;
    color: var(--text-muted);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* ── Empty state ──────────────────────────────────────── */
.cp-empty {
    padding: 28px;
    text-align: center;
    color: var(--text-muted);
    background: var(--bg-secondary);
    border-radius: 12px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
}

.cp-empty [data-lucide] {
    width: 26px;
    height: 26px;
    opacity: 0.65;
    color: var(--accent-primary);
}

/* ── Contract strip (compact cards) ───────────────────── */
.cp-contract-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 10px;
}

@media (min-width: 560px) {
    .cp-contract-grid {
        grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    }
}

.cp-contract-card {
    background: var(--bg-primary);
    border: 1px solid var(--border-primary);
    border-radius: 10px;
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}

.cp-contract-card:hover {
    border-color: var(--accent-primary);
    transform: translateY(-1px);
    box-shadow: var(--shadow-md);
}

.cp-contract-hdr {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.cp-contract-no {
    font-family: 'JetBrains Mono', 'Menlo', monospace;
    font-weight: 700;
    font-size: 0.88rem;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}

.cp-contract-status {
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 2px 7px;
    border-radius: 999px;
    background: var(--bg-secondary);
    color: var(--text-secondary);
    border: 1px solid var(--border-primary);
}

/* Status pills — darker text on tinted bg so they pass WCAG AA
   contrast (was amber-on-amber / teal-on-teal which failed). */
.cp-status-open    { background: var(--cp-weighedout-tint); color: var(--cp-weighedout-strong); border-color: transparent; }
.cp-status-closed  { background: var(--bg-tertiary); color: var(--text-secondary); border-color: var(--border-primary); }
.cp-status-pending,
.cp-status-future  { background: var(--cp-posted-tint); color: var(--cp-posted-strong); border-color: transparent; }

.cp-contract-product {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--text-secondary);
    font-size: 0.82rem;
    overflow: hidden;
}

.cp-contract-product [data-lucide] {
    width: 13px;
    height: 13px;
    color: var(--text-muted);
    flex-shrink: 0;
}

.cp-contract-product span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Progress wrapper — "Delivery · 5%" header above the bar so the
   percentage is always readable against the card surface, regardless
   of the fill width or theme. Fill still gradients for visual punch. */
.cp-contract-progress {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.cp-contract-progress-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 6px;
    font-variant-numeric: tabular-nums;
}

.cp-contract-progress-label {
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-muted);
    font-weight: 700;
}

.cp-contract-progress-value {
    font-size: 0.95rem;
    font-weight: 800;
    color: var(--text-primary);
    letter-spacing: -0.01em;
}

.cp-contract-bar {
    position: relative;
    width: 100%;
    height: 10px;
    background: var(--bg-secondary);
    border: 1px solid var(--border-primary);
    border-radius: 999px;
    overflow: hidden;
}

.cp-contract-fill {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--cp-fill-from), var(--cp-fill-to));
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
                0 0 10px var(--cp-fill-glow, transparent);
    transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}

/* Tier palette — also drives the subtle outer glow colour for each */
.cp-contract-bar.tier-complete {
    --cp-fill-from: #059669;
    --cp-fill-to: var(--success);
    --cp-fill-glow: rgba(42, 213, 189, 0.35);
}
.cp-contract-bar.tier-complete ~ * .cp-contract-progress-value,
.cp-contract-progress:has(.tier-complete) .cp-contract-progress-value {
    color: var(--cp-weighedout-strong);
}

.cp-contract-bar.tier-great {
    --cp-fill-from: #0891b2;
    --cp-fill-to: #22d3ee;
    --cp-fill-glow: rgba(34, 211, 238, 0.30);
}
.cp-contract-progress:has(.tier-great) .cp-contract-progress-value {
    color: var(--cp-checkedin-strong);
}

.cp-contract-bar.tier-good {
    --cp-fill-from: #d97706;
    --cp-fill-to: var(--warning);
    --cp-fill-glow: rgba(255, 176, 28, 0.30);
}
.cp-contract-progress:has(.tier-good) .cp-contract-progress-value {
    color: var(--cp-posted-strong);
}

.cp-contract-bar.tier-low {
    --cp-fill-from: var(--accent-secondary);
    --cp-fill-to: var(--accent-primary);
    --cp-fill-glow: rgba(255, 0, 131, 0.30);
}
.cp-contract-progress:has(.tier-low) .cp-contract-progress-value {
    color: var(--accent-primary);
}

.cp-contract-figures {
    margin: 0;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 4px;
    font-size: 0.8rem;
}

.cp-contract-figures > div {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}

.cp-contract-figures dt {
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
    font-weight: 600;
}

.cp-contract-figures dd {
    margin: 0;
    font-weight: 700;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.cp-contract-balance dd { color: var(--accent-primary); }

/* ==================================================================
   TRUCK GRID — proper table on desktop, flips to stacked cards on
   phone via CSS. Same markup, responsive behaviour via media queries.
   ================================================================== */
.cp-grid-wrap {
    width: 100%;
    overflow-x: auto;
    border-radius: 10px;
    border: 1px solid var(--border-primary);
    background: var(--bg-primary);
    -webkit-overflow-scrolling: touch;

    /* Firefox — colour only (Firefox can't size scrollbars bigger than
       "auto". "auto" gives the OS-default medium bar). */
    scrollbar-color: var(--accent-primary) var(--bg-tertiary);
    scrollbar-width: auto;

    /* Leave a little breathing room under the table so the scrollbar
       doesn't overlap the bottom row's bottom border. */
    padding-bottom: 2px;
}

/* ══════════════════════════════════════════════════════════
   CUSTOM HORIZONTAL SCROLLBAR — WebKit (Chrome / Edge / Safari).
   Big, grippable, accent-coloured, with hover + active states
   so it actually feels like something you can grab.
   ══════════════════════════════════════════════════════════ */
.cp-grid-wrap::-webkit-scrollbar {
    height: 16px;                      /* ← much taller than the default 8-10px */
    width: 16px;
    background: var(--bg-tertiary);
}

.cp-grid-wrap::-webkit-scrollbar-track {
    background: var(--bg-tertiary);
    border-radius: 0 0 10px 10px;      /* sit cleanly inside the wrap's rounded border */
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.06);
    margin: 0 4px;
}

.cp-grid-wrap::-webkit-scrollbar-thumb {
    /* Gradient thumb in the brand pink — 4px transparent border
       creates comfortable "padding" between the thumb edge and the
       track, making the thumb feel rounded + floating rather than
       filling the whole 16px slot. */
    background: linear-gradient(180deg,
        var(--accent-secondary, #dc0073) 0%,
        var(--accent-primary, #ff0083) 55%,
        var(--accent-tertiary, #b40060) 100%);
    background-clip: padding-box;
    border: 4px solid transparent;
    border-radius: 999px;
    min-width: 60px;
    box-shadow: 0 1px 3px rgba(255, 0, 131, 0.35),
                inset 0 1px 0 rgba(255, 255, 255, 0.2);
    transition: border-width 0.15s ease, box-shadow 0.18s ease, filter 0.18s ease;
}

.cp-grid-wrap::-webkit-scrollbar-thumb:hover {
    border-width: 3px;                 /* thumb "grows" slightly on hover */
    filter: brightness(1.08);
    box-shadow: 0 2px 8px rgba(255, 0, 131, 0.45),
                inset 0 1px 0 rgba(255, 255, 255, 0.28);
}

.cp-grid-wrap::-webkit-scrollbar-thumb:active {
    border-width: 2px;                 /* even bigger on grab */
    filter: brightness(1.12);
    box-shadow: 0 3px 12px rgba(255, 0, 131, 0.55),
                inset 0 1px 0 rgba(255, 255, 255, 0.35);
}

.cp-grid-wrap::-webkit-scrollbar-corner {
    background: transparent;
}

/* Dark themes — subtler track, thumb pops more against the darker bg */
[data-theme="dark"] .cp-grid-wrap::-webkit-scrollbar-track,
[data-theme="meta-dark"] .cp-grid-wrap::-webkit-scrollbar-track,
[data-theme="wa-dark"] .cp-grid-wrap::-webkit-scrollbar-track,
[data-theme="spotify"] .cp-grid-wrap::-webkit-scrollbar-track {
    background: rgba(255, 255, 255, 0.03);
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.4);
}

/* Mobile — the grid flips to stacked cards, so no horizontal scroll
   is needed. Leave the browser default for any residual scroll. */
@media (max-width: 960px) {
    .cp-grid-wrap::-webkit-scrollbar { height: 0; width: 0; }
}

.cp-grid {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: 0.84rem;
}

/* Sortable header */
.cp-grid thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--bg-secondary);
    color: var(--text-secondary);
    text-align: left;
    padding: 9px 10px;
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    border-bottom: 1px solid var(--border-primary);
    white-space: nowrap;
    user-select: none;
}

.cp-th-sort { cursor: pointer; transition: background 0.12s ease, color 0.12s ease; }
.cp-th-sort:hover { background: var(--bg-tertiary); color: var(--text-primary); }
.cp-th-sort.is-active { color: var(--accent-primary); background: var(--accent-light); }

.cp-th-inner {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.cp-sort-icon {
    width: 12px;
    height: 12px;
    opacity: 0.55;
    transition: opacity 0.12s ease;
}

.cp-th-sort.is-active .cp-sort-icon { opacity: 1; }

/* Body cells */
.cp-grid tbody td {
    padding: 9px 10px;
    border-top: 1px solid var(--border-primary);
    vertical-align: middle;
    color: var(--text-primary);
}

.cp-grid tbody tr:first-child td { border-top: none; }

.cp-row {
    background: var(--bg-primary);
    transition: background 0.18s ease, box-shadow 0.2s ease, transform 0.2s ease;
    animation: cp-row-in 0.35s cubic-bezier(0.4, 0, 0.2, 1) backwards;
}

.cp-row:hover {
    background: var(--bg-secondary);
    box-shadow: 0 1px 0 var(--accent-20) inset;
}

/* Gentle stagger-in animation when the grid first loads or re-filters.
   Keeps it subtle (0.35s, barely-noticeable y-offset) so it reads as
   smooth-feeling rather than busy. */
@keyframes cp-row-in {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Stagger the first 12 rows slightly. Beyond that, they animate at
   the same time so slow machines aren't bogged down. */
.cp-grid tbody tr:nth-child(1)  { animation-delay: 0ms; }
.cp-grid tbody tr:nth-child(2)  { animation-delay: 20ms; }
.cp-grid tbody tr:nth-child(3)  { animation-delay: 40ms; }
.cp-grid tbody tr:nth-child(4)  { animation-delay: 60ms; }
.cp-grid tbody tr:nth-child(5)  { animation-delay: 80ms; }
.cp-grid tbody tr:nth-child(6)  { animation-delay: 100ms; }
.cp-grid tbody tr:nth-child(7)  { animation-delay: 120ms; }
.cp-grid tbody tr:nth-child(8)  { animation-delay: 140ms; }
.cp-grid tbody tr:nth-child(9)  { animation-delay: 160ms; }
.cp-grid tbody tr:nth-child(10) { animation-delay: 180ms; }
.cp-grid tbody tr:nth-child(11) { animation-delay: 200ms; }
.cp-grid tbody tr:nth-child(12) { animation-delay: 220ms; }

/* Respect reduced-motion preference */
@media (prefers-reduced-motion: reduce) {
    .cp-row { animation: none !important; }
}

/* Left-border stage accent — reads at a glance even on tiny rows. */
.cp-row > td:first-child {
    border-left: 3px solid transparent;
    font-weight: 700;
}
.cp-row.cp-stage-posted      > td:first-child { border-left-color: var(--cp-posted); }
.cp-row.cp-stage-checked-in  > td:first-child { border-left-color: var(--cp-checkedin); }
.cp-row.cp-stage-weighed-in  > td:first-child { border-left-color: var(--cp-weighedin); }
.cp-row.cp-stage-weighed-out > td:first-child { border-left-color: var(--cp-weighedout); }

/* Amber wash for rows that still need security input — stronger
   than the old 8% warning-light so it's actually visible. */
.cp-row-editable {
    background: linear-gradient(90deg, var(--cp-posted-tint) 0, var(--bg-primary) 45%);
}
.cp-row-editable:hover {
    background: linear-gradient(90deg, var(--cp-posted-tint) 0, var(--bg-secondary) 45%);
}

.cp-row-locked {
    opacity: 0.96;
}

/* Column sizing hints — browsers still auto-fit, but these widths are
   now tuned so every cell shows its full value without clipping the
   number, date, registration, or driver ID.

   CRITICAL COLUMNS use `min-width` (not just `width`) so the browser
   CAN'T shrink them when the table doesn't fit the viewport. They
   push the table into horizontal scroll instead of squishing. The
   4 columns that get this treatment are:
     • cp-col-date   (Posted, Checked-in, Weigh-in, Weigh-out)
     • cp-col-req    (Driver ID #, Truck registration)
   Because those are the values the customer literally needs to
   review to decide whether to change them. */
.cp-col-ticket   { width: 118px; }
.cp-col-stage    { width: 140px; }
.cp-col-product  { min-width: 170px; }
.cp-col-contract { width: 128px; }
.cp-col-date     { width: 120px; min-width: 120px; }   /* HARD floor — cannot shrink */
.cp-col-mass     { width: 112px; text-align: right; }
.cp-col-lab      { width: 165px; }
.cp-col-req      { width: 225px; min-width: 225px; }   /* HARD floor — cannot shrink */
.cp-col-save     { width: 108px; text-align: right; }

/* Mirror the min-widths onto the actual body cells. In HTML tables
   the column's effective minimum = max(thead min-width, tbody min-width).
   Setting both guarantees the browser respects the floor. */
.cp-cell-date    { min-width: 120px; }
.cp-cell-input   { min-width: 225px; }

/* Cell content — NEVER set display:flex on a <td>, it breaks table layout.
   All "stack vertically" behaviour is done via display:block on the inline
   children, which naturally stack inside a normal table-cell. */

.cp-cell-ticket { min-width: 0; }

.cp-ticket-no {
    font-family: 'JetBrains Mono', 'Menlo', monospace;
    font-weight: 800;
    font-size: 0.95rem;
    color: var(--text-primary);
    letter-spacing: -0.01em;
    display: block;
}

.cp-cell-main {
    font-weight: 600;
    color: var(--text-primary);
    line-height: 1.35;
    overflow: hidden;
    text-overflow: ellipsis;
    display: block;
    white-space: nowrap;
}

.cp-cell-product { min-width: 0; }

.cp-cell-muted {
    color: var(--text-secondary);
    font-family: 'JetBrains Mono', 'Menlo', monospace;
    font-size: 0.82rem;
}

/* Date-column cell — children stack naturally thanks to display:block. */
.cp-cell-date {
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
}

.cp-date-main {
    display: block;
    font-weight: 600;
    font-size: 0.82rem;
    color: var(--text-primary);
    white-space: nowrap;
}

.cp-date-time {
    display: block;
    font-size: 0.72rem;
    color: var(--text-muted);
    font-weight: 500;
}

.cp-date-mass {
    display: block;
    font-size: 0.72rem;
    color: var(--accent-primary);
    font-weight: 700;
    margin-top: 1px;
}

.cp-date-gate {
    display: block;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.78rem;
    /* Use the checkedin-strong shade so the gate reg reads cleanly
       against both light and dark surfaces. */
    color: var(--cp-checkedin-strong);
    font-weight: 600;
}

.cp-date-dash {
    display: block;
    color: var(--text-muted);
    font-weight: 600;
}

/* ══════════════════════════════════════════════════════════
   LAPTOP SIZING (≈ 1.3k — 1280 / 1366 / 1440 / 1500 px)
   Compacts most of the grid so 14 cols fit with less
   horizontal scrolling — but DELIBERATELY leaves these four
   untouched because the customer needs to read them at full
   size regardless of screen width:

     • Posted column + all other date columns
     • Driver ID # input
     • Truck registration input
     • Lock-chips (readonly display of the same values)

   Everything else (ticket #, stage, product, contract, mass,
   lab, save) shrinks a touch to make room. The horizontal
   scrollbar already looks gorgeous so a little horizontal
   scroll on narrow laptops is fine — prioritise legibility of
   the security fields over fitting everything on screen.

   Mobile (≤ 960 px) uses its own card layout below and is
   untouched by this rule. Full-HD desktops (≥ 1501 px) keep
   the spacious default sizing.
   ══════════════════════════════════════════════════════════ */
@media (min-width: 961px) and (max-width: 1500px) {
    .cp-grid                  { font-size: 0.80rem; }
    .cp-grid thead th         { padding: 8px 8px; font-size: 0.63rem; }
    .cp-grid tbody td         { padding: 7px 8px; }

    .cp-ticket-no             { font-size: 0.9rem; }
    .cp-mass-num              { font-size: 1.02rem; }
    .cp-mass-unit             { font-size: 0.66rem; }
    .cp-stage-pill            { font-size: 0.58rem; padding: 3px 7px; letter-spacing: 0.015em; }
    .cp-lab-pill              { font-size: 0.58rem; padding: 3px 7px; letter-spacing: 0.015em; }
    .cp-lab-fm, .cp-lab-net   { font-size: 0.74rem; }

    .cp-btn-save              { min-width: 72px; padding: 7px 10px; font-size: 0.8rem; }

    /* Tighter column widths for the "can shrink" cols. Date and
       req columns are OMITTED here on purpose — they keep their
       full default widths so the text is always visible. */
    .cp-col-ticket   { width: 110px; }
    .cp-col-stage    { width: 128px; }
    .cp-col-product  { min-width: 150px; }
    .cp-col-contract { width: 116px; }
    .cp-col-mass     { width: 102px; }
    .cp-col-lab      { width: 150px; }
    .cp-col-save     { width: 98px; }

    /* NOTE — .cp-col-date, .cp-col-req, .cp-input, .cp-lock-chip
       and .cp-date-main / .cp-date-time are intentionally NOT
       overridden in this media query. They keep their default
       full-size readable values. */

    .cp-section-title         { font-size: 0.98rem; }
    .cp-section-sub           { font-size: 0.8rem; }
    .cp-hero-title            { font-size: 1.15rem; }
    .cp-hero-sub              { font-size: 0.82rem; }
    .cp-chip                  { font-size: 0.78rem; padding: 6px 10px; }
    .cp-chip-count            { font-size: 0.66rem; min-width: 22px; }
}

/* ═════════════════════════════════════════════════════════
   TONNAGE CELLS — the primary number the customer cares
   about. Big, bold, monospace, right-aligned. Separated from
   the weigh-in/out DATE columns so the number reads clean.
   ═════════════════════════════════════════════════════════ */
.cp-cell-mass {
    text-align: right;
    padding-right: 14px !important;
    white-space: nowrap;
}

.cp-mass-num {
    display: inline-block;
    font-family: 'JetBrains Mono', 'Menlo', monospace;
    font-size: 1.15rem;
    font-weight: 800;
    color: var(--text-primary);
    letter-spacing: -0.015em;
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

.cp-mass-unit {
    display: inline-block;
    margin-left: 3px;
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--text-muted);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    vertical-align: baseline;
}

/* ═════════════════════════════════════════════════════════
   LAB COLUMN — status pill (done / pending) + FM% + net-mass
   for completed lab work. Stacks cleanly with block children.
   ═════════════════════════════════════════════════════════ */
.cp-cell-lab {
    line-height: 1.25;
}

.cp-lab-pill {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    line-height: 1.3;
    margin-bottom: 3px;
    box-shadow: var(--shadow-sm);
}

.cp-lab-pill [data-lucide] {
    width: 11px;
    height: 11px;
}

.cp-lab-done {
    background: var(--cp-weighedout-solid);
    color: #fff;
    border: 1px solid var(--cp-weighedout-strong);
}

.cp-lab-pending {
    background: var(--cp-posted-solid);
    color: #fff;
    border: 1px solid var(--cp-posted-strong);
}

.cp-lab-fm {
    display: block;
    font-size: 0.78rem;
    color: var(--text-secondary);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.cp-lab-fm strong {
    color: var(--cp-posted-strong);
    font-weight: 800;
}

.cp-lab-net {
    display: block;
    font-size: 0.8rem;
    color: var(--text-secondary);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    font-family: 'JetBrains Mono', 'Menlo', monospace;
}

.cp-lab-net strong {
    color: var(--cp-weighedout-strong);
    font-weight: 800;
}

/* Stage pill */
.cp-stage-pill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 8px;
    border-radius: 999px;
    font-size: 0.62rem;                /* was 0.68rem — "Checked in" now fits single-line */
    font-weight: 700;
    letter-spacing: 0.02em;            /* was 0.05em — tighter for uppercase */
    text-transform: uppercase;
    color: #fff !important;
    box-shadow: var(--shadow-sm);
    white-space: nowrap;               /* belt + braces — never wrap */
}

/* Solid pill fills — use the fixed "-solid" shades so white text
   passes WCAG AA in every theme, not just light mode. */
.cp-stage-pill.cp-stage-posted      { background: var(--cp-posted-solid);     border-color: var(--cp-posted-strong); }
.cp-stage-pill.cp-stage-checked-in  { background: var(--cp-checkedin-solid);  border-color: var(--cp-checkedin-strong); }
.cp-stage-pill.cp-stage-weighed-in  { background: var(--cp-weighedin-solid);  border-color: var(--cp-weighedin-strong); }
.cp-stage-pill.cp-stage-weighed-out { background: var(--cp-weighedout-solid); border-color: var(--cp-weighedout-strong); }

.cp-stage-pill-dot {
    width: 6px;
    height: 6px;
    background: rgba(255, 255, 255, 0.9);
    border-radius: 50%;
    flex-shrink: 0;
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.25);
}

/* Input cells — <td> stays as table-cell; inputs are block-level (100% wide)
   so they naturally stack when there are two (registration + pkg count).
   `overflow: visible` + wide parent column guarantees the full text of a
   long registration or ID is readable without internal scrolling.

   The column's hard `min-width: 225px` floor is set on the desktop col
   definition above — NOT reset here — so the column can't shrink below
   that on any screen width ≥ 961px. Mobile resets it to 0 in the
   @media (max-width: 960px) block at the bottom of this file. */
.cp-cell-input {
    overflow: visible;
}

.cp-input {
    display: block;
    width: 100%;
    background: var(--surface);
    color: var(--text-primary);
    border: 1px solid var(--border-primary);
    border-radius: 7px;
    padding: 8px 10px;
    font-size: 0.9rem;               /* bumped so the value reads clearly */
    font-weight: 500;
    font-family: inherit;
    letter-spacing: 0.01em;
    transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
    min-width: 0;
    box-sizing: border-box;
    text-overflow: ellipsis;         /* if content somehow exceeds width */
}

/* Tiny gap between two inputs stacked in the same cell */
.cp-cell-input .cp-input + .cp-input {
    margin-top: 5px;
}

.cp-input:focus {
    outline: none;
    border-color: var(--accent-primary);
    background: var(--bg-primary);
    /* Layered focus ring — soft halo + crisp accent line, feels premium */
    box-shadow: 0 0 0 1px var(--accent-primary),
                0 0 0 5px var(--accent-15),
                0 2px 8px var(--accent-20);
}

.cp-input::placeholder {
    color: var(--text-muted);
    opacity: 0.8;
}

.cp-input-small {
    font-size: 0.78rem;
    padding: 6px 9px;
}

.cp-cell-save {
    text-align: right;
    white-space: nowrap;
}

/* Lock chip — shown instead of input when row is locked. Takes the
   full cell width (flex container expands) so the stored value never
   gets mid-truncated on long IDs / registrations. */
.cp-lock-chip {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 10px;
    border-radius: 7px;
    background: var(--bg-tertiary);
    color: var(--text-primary);
    font-size: 0.88rem;
    font-weight: 600;
    font-family: 'JetBrains Mono', monospace;
    letter-spacing: 0.02em;
    border: 1px dashed var(--border-primary);
    cursor: default;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    width: 100%;
    box-sizing: border-box;
}

.cp-lock-chip [data-lucide] {
    width: 13px;
    height: 13px;
    color: var(--text-muted);
    flex-shrink: 0;
}

.cp-lock-indicator {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--bg-tertiary);
    color: var(--text-muted);
    border: 1px solid var(--border-primary);
}

.cp-lock-indicator [data-lucide] {
    width: 14px;
    height: 14px;
}

/* ── Mobile: rows become cards (same markup, pure CSS flip) ── */
@media (max-width: 960px) {
    .cp-grid-wrap {
        overflow: visible;
        border: none;
        background: transparent;
    }

    .cp-grid,
    .cp-grid thead,
    .cp-grid tbody,
    .cp-grid tr,
    .cp-grid td {
        display: block;
        width: 100%;
    }

    .cp-grid thead { display: none; }

    .cp-grid tbody tr {
        background: var(--surface);
        border: 1px solid var(--border-primary);
        border-radius: 12px;
        padding: 12px;
        margin-bottom: 10px;
        box-shadow: var(--shadow-sm);
    }

    .cp-grid tbody td {
        border: none;
        padding: 5px 0;
        display: grid;
        grid-template-columns: 100px 1fr;
        gap: 8px;
        align-items: center;
    }

    .cp-grid tbody td:first-child { border-left: none !important; padding-top: 0; }

    .cp-grid tbody td::before {
        content: attr(data-lbl);
        font-size: 0.64rem;
        text-transform: uppercase;
        letter-spacing: 0.08em;
        color: var(--text-muted);
        font-weight: 700;
    }

    .cp-grid tbody td.cp-cell-save {
        grid-template-columns: 1fr;
        margin-top: 6px;
    }

    .cp-grid tbody td.cp-cell-save::before { display: none; }

    .cp-btn-save { width: 100%; }

    .cp-row.cp-stage-posted      { border-left: 4px solid var(--cp-posted); }
    .cp-row.cp-stage-checked-in  { border-left: 4px solid var(--cp-checkedin); }
    .cp-row.cp-stage-weighed-in  { border-left: 4px solid var(--cp-weighedin); }
    .cp-row.cp-stage-weighed-out { border-left: 4px solid var(--cp-weighedout); }

    .cp-row-editable,
    .cp-row-editable:hover {
        background: linear-gradient(135deg, var(--cp-posted-tint) 0, var(--surface) 40%);
    }

    /* Mobile: mass cell keeps its big number but left-aligns so it
       sits naturally in the stacked row. */
    .cp-grid tbody td.cp-cell-mass {
        text-align: left;
        padding-right: 0 !important;
    }
    .cp-mass-num { font-size: 1.25rem; }

    /* Mobile: lab pill + values flow inline with label */
    .cp-grid tbody td.cp-cell-lab {
        align-items: center;
    }

    /* Reset the desktop min-widths — on mobile each cell becomes a
       stacked card row; a 225px min would blow out the viewport on
       narrow phones. Let them fill the card naturally. */
    .cp-col-date,
    .cp-col-req,
    .cp-cell-date,
    .cp-cell-input {
        min-width: 0 !important;
        width: auto !important;
    }

    /* Make the "Loading #" row the card title, big and centered */
    .cp-grid tbody td.cp-cell-ticket::before { display: none; }
    .cp-grid tbody td.cp-cell-ticket {
        grid-template-columns: 1fr;
        padding-bottom: 6px;
        margin-bottom: 4px;
        border-bottom: 1px dashed var(--border-primary);
    }
    .cp-grid tbody td.cp-cell-ticket .cp-ticket-no {
        font-size: 1.1rem;
    }

    .cp-chip-row { padding: 0; }
    .cp-chip { flex: 1 1 calc(50% - 3px); justify-content: center; }
    .cp-search-strip { gap: 8px; }
    .cp-result-count { order: -1; width: 100%; }
}

@media (max-width: 420px) {
    .cp-chip { padding: 8px 10px; font-size: 0.76rem; min-height: 40px; }
    .cp-chip-count { font-size: 0.64rem; padding: 1px 6px; min-width: 20px; }
    .cp-hero { padding: 12px 14px; }
    .cp-hero-title { font-size: 1.1rem; }
    .cp-hero-sub { font-size: 0.8rem; }
    .cp-input { padding: 10px 11px; font-size: 0.92rem; } /* bigger tap targets */
    .cp-btn-save { min-height: 44px; }
}

/* General mobile-friendly tap-target bump */
@media (max-width: 640px) {
    .cp-chip { min-height: 38px; }
    .cp-btn { min-height: 38px; }
}

/* ── Toast ─────────────────────────────────────────── */
.cp-toast {
    position: fixed;
    left: 50%;
    bottom: 24px;
    transform: translateX(-50%);
    z-index: 9999;
    background: var(--surface-elevated);
    color: var(--text-primary);
    border: 1px solid var(--border-primary);
    border-radius: 10px;
    padding: 12px 16px;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    box-shadow: var(--shadow-xl);
    max-width: calc(100vw - 32px);
    font-weight: 500;
    animation: cp-toast-in 0.25s ease-out;
}

.cp-toast-ok  { border-color: rgba(42, 213, 189, 0.35); }
.cp-toast-ok [data-lucide] { color: var(--success); }
.cp-toast-err { border-color: rgba(247, 39, 74, 0.35); }
.cp-toast-err [data-lucide] { color: var(--error); }
.cp-toast [data-lucide] { width: 18px; height: 18px; flex-shrink: 0; }

@keyframes cp-toast-in {
    from { opacity: 0; transform: translate(-50%, 12px); }
    to   { opacity: 1; transform: translate(-50%, 0); }
}

/* ── Spin ─────────────────────────────────────────── */
.cp-spin { animation: cp-spin 1s linear infinite; }
@keyframes cp-spin { to { transform: rotate(360deg); } }

/* ── Dark-theme tweaks ─────────────────────────── */
[data-theme="dark"] .cp-grid thead th,
[data-theme="meta-dark"] .cp-grid thead th,
[data-theme="wa-dark"] .cp-grid thead th,
[data-theme="spotify"] .cp-grid thead th {
    background: var(--bg-tertiary);
}

[data-theme="dark"] .cp-row:hover,
[data-theme="meta-dark"] .cp-row:hover,
[data-theme="wa-dark"] .cp-row:hover,
[data-theme="spotify"] .cp-row:hover {
    background: var(--bg-tertiary);
}

[data-theme="dark"] .cp-chip,
[data-theme="meta-dark"] .cp-chip,
[data-theme="wa-dark"] .cp-chip,
[data-theme="spotify"] .cp-chip {
    background: var(--bg-tertiary);
}

[data-theme="dark"] .cp-chip-count,
[data-theme="meta-dark"] .cp-chip-count,
[data-theme="wa-dark"] .cp-chip-count,
[data-theme="spotify"] .cp-chip-count {
    background: rgba(255, 255, 255, 0.08);
}

[data-theme="dark"] .cp-lock-chip,
[data-theme="meta-dark"] .cp-lock-chip,
[data-theme="wa-dark"] .cp-lock-chip,
[data-theme="spotify"] .cp-lock-chip {
    background: rgba(255, 255, 255, 0.04);
}
