/* app.css ───── Count client ─────
   The field surface. Deliberately sparser than Manage's stylesheet set: this app has
   four screens (sign-in, picker, counting, degraded) and no tables, filters, or drawers.

   Brand tokens per scope §11 — Manrope wordmark, near-black chrome, lime accent used
   ONCE, on the thing the product is about: the count that's due. */

*, *::before, *::after {
    box-sizing: border-box;
}

body {
    margin: 0;
    /* The counting screen is a fixed surface — no rubber-band scroll under a scanner. */
    overscroll-behavior-y: none;
}

/* ───── Brand logo (programmatic GoStocktake wordmark) ─────
   Mirrors the first-paint loader so the wordmark is identical across splash and app. */

.brand-logo {
    display: inline-flex;
    align-items: baseline;
    gap: 0;
    line-height: 1;
    user-select: none;
    font-family: 'Manrope', sans-serif;
    font-weight: 500;
    letter-spacing: -1.5px;
    font-size: 1.15rem;
    color: #111111;
}

    .brand-logo .brand-go {
        border-bottom: 2px solid #D9E021; /* lime accent under "Go" only */
        padding-bottom: 1px;
    }

    .brand-logo .brand-stocktake {
        color: #111111;
    }

    .brand-logo.brand-logo-lg {
        font-size: 1.9rem;
    }

        .brand-logo.brand-logo-lg .brand-go {
            border-bottom-width: 3px;
            padding-bottom: 2px;
        }

/* ───── Page shell ───── */

.count-page {
    padding: 1.25rem;
    max-width: 560px;
    margin: 0 auto;
}

/* ───── Sign-in field sizing (field surface — larger than the admin portal) ───── */

.count-field .mud-input-root {
    font-size: 1.15rem;
}

.count-field .mud-input-label {
    font-size: 1.1rem;
}

/* ───── Empty state ───── */

.count-empty {
    font-size: 1rem;
    color: var(--mud-palette-text-secondary);
    padding: 2rem 0;
    text-align: center;
}

/* ───── Picker ─────
   Two levels, both collapsible: a pinned member on a single workspace with no open lists
   never sees a choice at all — they land straight in what's-due (scope §8, "the simple
   single-site path collapses to near-nothing").

   Lime appears exactly once, on the due figure. That is the product. */

.pick-card {
    display: block;
    width: 100%;
    text-align: left;
    appearance: none;
    background: var(--mud-palette-surface);
    border: 0.5px solid var(--mud-palette-divider);
    border-radius: 12px;
    padding: 1.1rem 1.25rem;
    font-family: inherit;
    cursor: pointer;
    transition: border-color 0.15s ease;
}

    .pick-card:hover:not(:disabled) {
        border-color: var(--mud-palette-primary);
    }

    .pick-card:disabled {
        cursor: not-allowed;
        background: var(--mud-palette-background-grey);
    }

.pick-card-row {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.pick-card-text {
    flex: 1;
    min-width: 0;
}

.pick-card-title {
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--mud-palette-text-primary);
    line-height: 1.3;
}

.pick-card:disabled .pick-card-title {
    color: var(--mud-palette-text-disabled);
}

.pick-card-sub {
    font-size: 0.85rem;
    color: var(--mud-palette-text-secondary);
    margin-top: 3px;
}

/* ── The due figure — THE lime moment ──
   Big number, lime pulse. Mirrors Manage's .wh-due; the same accent for the same
   meaning (what's due is the product), so the two apps read as one system. */

.pick-due {
    display: inline-flex;
    align-items: flex-start;
    flex-shrink: 0;
}

.pick-due-number {
    font-size: 2.2rem;
    font-weight: 700;
    line-height: 1;
    color: var(--mud-palette-text-primary);
    letter-spacing: -1px;
}

.pick-due-pulse {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: #D9E021; /* lime — the accent, used once */
    margin-left: 0.4rem;
    box-shadow: 0 0 0 0 rgba(217, 224, 33, 0.6);
    animation: pick-pulse 2.2s infinite;
    flex-shrink: 0;
}

@keyframes pick-pulse {
    0% {
        box-shadow: 0 0 0 0 rgba(217, 224, 33, 0.5);
    }

    70% {
        box-shadow: 0 0 0 10px rgba(217, 224, 33, 0);
    }

    100% {
        box-shadow: 0 0 0 0 rgba(217, 224, 33, 0);
    }
}

@media (prefers-reduced-motion: reduce) {
    .pick-due-pulse {
        animation: none;
    }
}

/* ── Blocked workspace (lapsed / archived) ──
   Shown, not hidden: a counter needs to know the workspace exists and why they can't
   count in it — "it's not in the list" is a support call. */

.pick-blocked {
    font-size: 0.85rem;
    color: var(--mud-palette-warning);
    margin-top: 3px;
}

/* ───── Counting screen ─────
   The layout is a sandwich: a PINNED scan strip at the top (where the counter's attention
   is — a scan lands here), a scrolling working surface below, and a PINNED progress bar at
   the bottom. The strip never scrolls away, because the counter is scanning while the table
   moves underneath.

   Visual language is the landing mockup's — session header, alternating rows, counted rows
   dimmed, lime progress fill — with the two things a marketing mockup can't show: the scan
   strip and the quantity control. */

.cs-shell {
    /* Pinned to the viewport under the fixed dense appbar, rather than deriving height
       through MudMainContent — one rule, no ancestor height chain. */
    position: fixed;
    top: 48px;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    max-width: 560px;
    margin: 0 auto;
}

/* ── Session header (mockup: .session-header) ── */

.cs-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.75rem 1rem;
    border-bottom: 0.5px solid var(--mud-palette-divider);
    flex-shrink: 0;
}

.cs-header-title {
    font-size: 1rem;
    font-weight: 600;
    color: var(--mud-palette-text-primary);
    line-height: 1.3;
}

.cs-header-sub {
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
    margin-top: 2px;
}

/* The lime "Counting" pill — straight from the mockup's .badge-active. */
.cs-pill {
    background: #D9E021;
    color: #111111;
    font-size: 0.7rem;
    font-weight: 700;
    padding: 4px 12px;
    border-radius: 20px;
    letter-spacing: 0.3px;
    white-space: nowrap;
    flex-shrink: 0;
}

/* ── Unsynced indicator ──
   Load-bearing, and absent from the mockup. A non-zero figure is the counter's signal not
   to walk away yet — everything about the storage design exists to protect these entries,
   and this is the only place they learn the entries are still local. */

.cs-sync {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.75rem;
    font-weight: 500;
    padding: 3px 9px;
    border-radius: 20px;
    white-space: nowrap;
    flex-shrink: 0;
}

    .cs-sync.clear {
        color: var(--mud-palette-text-secondary);
        background: var(--mud-palette-background-grey);
    }

    .cs-sync.pending {
        color: var(--mud-palette-warning);
        background: rgba(255, 152, 0, 0.1);
    }

.cs-sync-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
}

/* ── The scan strip (pinned) ──
   Where a scan lands and where the counter looks. Three states: idle (waiting), resolved
   (a catalogue SKU + its working quantity), unknown (an unmatched barcode). */

.cs-strip {
    flex-shrink: 0;
    padding: 1rem;
    border-bottom: 0.5px solid var(--mud-palette-divider);
    background: var(--mud-palette-surface);
    min-height: 148px;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

    .cs-strip.unknown {
        background: rgba(255, 152, 0, 0.06);
    }

.cs-strip-idle {
    text-align: center;
    color: var(--mud-palette-text-secondary);
}

.cs-strip-name {
    font-size: 1.15rem;
    font-weight: 600;
    color: var(--mud-palette-text-primary);
    line-height: 1.25;
    /* Two lines max — a long description must not push the quantity control off-screen. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.cs-strip-meta {
    font-size: 0.8rem;
    color: var(--mud-palette-text-secondary);
    margin-top: 3px;
}

/* ── Quantity control ──
   Big targets. This is operated with a thumb, possibly gloved, while holding a scanner. */

.cs-qty {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.75rem;
}

.cs-qty-input {
    width: 88px;
    flex-shrink: 0;
}

    .cs-qty-input .mud-input-root {
        font-size: 1.5rem;
        font-weight: 600;
    }

    .cs-qty-input input {
        text-align: center;
    }

/* ── Working surface (scrolls) ── */

.cs-body {
    flex: 1;
    min-height: 0; /* or it refuses to shrink below content height */
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

.cs-filters {
    display: flex;
    gap: 0.4rem;
    padding: 0.6rem 1rem;
    overflow-x: auto;
    scrollbar-width: none;
    border-bottom: 0.5px solid var(--mud-palette-divider);
    position: sticky;
    top: 0;
    background: var(--mud-palette-surface);
    z-index: 1;
}

    .cs-filters::-webkit-scrollbar {
        display: none;
    }

.cs-chip {
    appearance: none;
    font-family: inherit;
    height: 32px;
    padding: 0 0.85rem;
    font-size: 0.85rem;
    border-radius: 16px;
    background: var(--mud-palette-background-grey);
    color: var(--mud-palette-text-secondary);
    border: 0.5px solid var(--mud-palette-divider);
    cursor: pointer;
    white-space: nowrap;
    flex-shrink: 0;
}

    .cs-chip.on {
        background: rgba(17, 17, 17, 0.06);
        color: var(--mud-palette-primary);
        border-color: var(--mud-palette-primary);
        font-weight: 500;
    }

/* ── SKU rows (mockup: .sku-row) ── */

.cs-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.7rem 1rem;
    border-bottom: 0.5px solid var(--mud-palette-divider);
    cursor: pointer;
}

    .cs-row.alt {
        background: var(--mud-palette-background-grey);
    }

    /* Counted: dimmed, not hidden. The counter needs to see it's done, and be able to
       re-count it (a correction is just another count). */
    .cs-row.counted {
        opacity: 0.45;
    }

.cs-row-text {
    flex: 1;
    min-width: 0;
}

.cs-row-name {
    font-size: 0.95rem;
    color: var(--mud-palette-text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cs-row-sub {
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
    margin-top: 2px;
}

.cs-row-state {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--mud-palette-text-secondary);
    flex-shrink: 0;
}

/* ── Progress (pinned bottom; mockup: .progress-wrap) ── */

.cs-progress {
    flex-shrink: 0;
    padding: 0.75rem 1rem;
    border-top: 0.5px solid var(--mud-palette-divider);
    background: var(--mud-palette-surface);
}

.cs-progress-meta {
    display: flex;
    justify-content: space-between;
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
    margin-bottom: 6px;
}

.cs-progress-track {
    height: 5px;
    background: var(--mud-palette-divider);
    border-radius: 3px;
    overflow: hidden;
}

.cs-progress-fill {
    height: 100%;
    background: #D9E021; /* lime — the accent, on the thing the product is about */
    border-radius: 3px;
    transition: width 0.25s ease;
}

/* ───── Search (collapsible) ─────
   The manual path: for a SKU whose barcode won't scan (damaged label, no label on the
   shelf), or that the counter can see but can't find in a 2,000-row list.

   Collapsed by default — screen space on the counting surface belongs to the SKU list.
   Opens over the working surface, not beside it.

   Deliberately NOT barcode-only. If someone is typing, the barcode has failed them;
   making them key 13 digits correctly is punishment. They type "cranberry" or the last
   four digits, and either matches. */

.cs-search {
    padding: 0.6rem 1rem;
    border-bottom: 0.5px solid var(--mud-palette-divider);
    background: var(--mud-palette-surface);
    flex-shrink: 0;
}

.cs-search-results {
    max-height: 40vh;
    overflow-y: auto;
    border-top: 0.5px solid var(--mud-palette-divider);
    margin-top: 0.6rem;
}

.cs-search-hint {
    font-size: 0.8rem;
    color: var(--mud-palette-text-secondary);
    padding: 0.75rem 0;
    text-align: center;
}

/* A search hit that isn't in the working set — countable, but not part of this pass.
   Marked, not hidden: counting it IS valid (any real scan is a real count), and the
   counter should know it's an extra rather than assume the list was wrong. */
.cs-row-off {
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--mud-palette-text-secondary);
    background: var(--mud-palette-background-grey);
    border: 0.5px solid var(--mud-palette-divider);
    border-radius: 4px;
    padding: 1px 6px;
    flex-shrink: 0;
}

/* The location selector — a direct flex child of .cs-shell, so it needs an explicit
       basis or it stretches into the free space and pushes the working surface down. */
.cs-location {
    flex: 0 0 auto;
    padding: 0.6rem 1rem;
    border-bottom: 0.5px solid var(--mud-palette-divider);
    background: var(--mud-palette-surface);
}


/* Lime submit — the accent on the action the whole screen exists for. */
.cs-submit {
    background: #D9E021 !important;
    color: #111111 !important;
}

    .cs-submit:hover {
        background: #c8ce1e !important;
    }

    .cs-submit:disabled {
        background: var(--mud-palette-action-disabled-background) !important;
        color: var(--mud-palette-action-disabled) !important;
    }

.cs-qty > .cs-submit {
    margin-left: 1.25rem;
}

/* ───── Camera overlay ─────
   A MODE, not a state. A live viewfinder shrinking the SKU list would be useless — so it
   goes full-screen, and STAYS open across scans: scan, the SKU drops into the strip
   underneath, you set a quantity, it's still ready for the next. Open/close friction per
   item would make shelf-counting unbearable. */

.cam {
    position: fixed;
    inset: 0;
    z-index: 2000;
    background: #000;
    display: flex;
    flex-direction: column;
}

.cam-video {
    flex: 1;
    width: 100%;
    object-fit: cover;
    min-height: 0;
}

/* The aiming window. A barcode is wide and short, so the reticle is too — it teaches the
   counter to hold the phone the right way without a word of instruction. */
.cam-reticle {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 78%;
    height: 128px;
    border: 2px solid rgba(255, 255, 255, 0.85);
    border-radius: 12px;
    box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.35);
    pointer-events: none;
}

.cam-bar {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 1rem;
    background: linear-gradient(rgba(0,0,0,0.6), transparent);
}

/* The result rail — what the last scan resolved to, over the video. The counter confirms
   the hit without leaving the viewfinder. */
.cam-result {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 1rem;
    background: linear-gradient(transparent, rgba(0,0,0,0.85) 30%);
    color: #fff;
}

.cam-result-name {
    font-size: 1.05rem;
    font-weight: 600;
    line-height: 1.3;
}

.cam-result-sub {
    font-size: 0.8rem;
    opacity: 0.7;
    margin-top: 2px;
}

.cam-result-qty {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.75rem;
}

.cam-result-qty > .cs-submit {
    margin-left: 1.25rem;
}

.cam-error {
    padding: 2rem;
    color: #fff;
    text-align: center;
    margin: auto;
}

/* The camera rail's quantity field sits on video — MudBlazor's outlined field inherits
   the rail's white text and has no background, so both need stating. */
.cam-result-qty .cs-qty-input .mud-input-root {
    background: rgba(255, 255, 255, 0.95);
    color: #111111;
    border-radius: 4px;
}

.cam-result-qty .cs-qty-input input {
    color: #111111;
}

.cam-result-qty .cs-qty-input .mud-input-outlined-border {
    border-color: rgba(255, 255, 255, 0.5);
}