/* ═══════════════════════════════════════════════════════════════════════════
   Pricing worklist (/pricing, Worklist mode).

   Global rather than isolated, for the same reason as factory-data.css: the page and its
   four child components share every class here, and CSS isolation would mean five copies.

   The palette is factory-data's "Harbour", pulled in deliberately rather than re-picked —
   the two pages describe the same rows, and a second blue would imply a second subject.
   The one thing this file adds is the ours/theirs divide: everything the factory sent reads
   on white, and the three fields we supply sit in the tinted lane on the right.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Palette ───────────────────────────────────────────────────────────────
   Declared on every root the pw-* rules can hang off, not just .pw-page. The two modals and
   their backdrop are rendered as siblings of the page rather than inside it (they are
   position:fixed, so nesting them would trap them in the page's overflow:hidden), and a
   var() that resolves nowhere is not a fallback — it is an invalid declaration. A
   .pw-btn-primary outside this scope paints white text on no background and disappears
   completely, which is exactly how the "Return to Worklist" button went missing.
   ────────────────────────────────────────────────────────────────────────── */
.pw-page,
.pw-modal,
.pw-modal-backdrop,
.pw-mode-heading {
    /* Harbour — kept byte-identical to factory-data.css so the two pages cannot drift. */
    --fd-ink: #0f1d33;
    --fd-ink-2: #44566f;
    --fd-ink-3: #78889f;
    --fd-line: #ccd8e6;
    --fd-line-2: #e6ecf4;
    --fd-rule: #b3c6dd;
    --fd-surface: #fff;
    --fd-sunken: #f2f6fb;
    --fd-rail-bg: #e9f0f8;
    --fd-head-bg: #f2f6fb;
    --fd-accent: #1264d6;
    --fd-accent-ink: #0a4699;
    --fd-accent-soft: #dfeafc;
    --fd-money: #0a3161;
    --fd-hero-bg: #f6faff;
    --fd-hero-head: #dfeafc;
    --fd-hero-line: #a9c8ee;
    --fd-warn: #8a5a08;
    --fd-warn-soft: #fbf1dd;
    --fd-good: #0b6b4a;
    --fd-good-soft: #ddf0e8;

    /* The "this is wrong" tone, for the cube check and expired pricing. Copied verbatim from
       factory-data.css, which already defines all three for its own expired badge — two pages
       showing the same expired price in two different reds is exactly the drift the rest of
       this palette is copied byte-for-byte to avoid. */
    --fd-bad: #a3231b;
    --fd-bad-soft: #fbe9e7;
    --fd-bad-line: #e7a9a3;

    /* One definition of the row grid, so the header and every row stay in step. */
    --pw-cols: 30px 44px 104px minmax(0, 1fr) 136px 68px 76px 96px 78px 74px 92px;
}

.pw-page {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    overflow: hidden;
    padding: 0 16px 16px;
}

/* Same trick as the factory data page: the shell's gradient would otherwise show as a border
   around the page. The element selector breaks the specificity tie with the isolated
   MainLayout rule — see the note in factory-data.css before touching this. */
main.app-main:has(.pw-page) {
    background: #fff;
}

/* ContentLoadingOverlay wraps content in two plain block divs; without this the flex chain
   from .pw-page down to the scrolling list is broken and the page grows instead of scrolling. */
.pw-page > .content-loading-overlay-shell,
.pw-page .content-loading-overlay-body {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
}

/* ── Header ───────────────────────────────────────────────────────────────── */

.pw-head {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 0 13px;
    border-bottom: 1px solid var(--fd-rule);
    flex-shrink: 0;
    flex-wrap: wrap;
}

.pw-head h1 {
    margin: 0;
    font-size: 20px;
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--fd-ink);
}

/* The Search mode's heading row: page title, then the toggle immediately beside it, matching
   where it sits on the worklist. Carries the palette tokens because this markup lives inside
   the Bootstrap filter card, outside .pw-page. */
.pw-mode-heading {
    display: flex;
    align-items: center;
    gap: 14px;
    min-width: 0;
}

/* Bootstrap gives h6 a bottom margin, which would push the title off the toggle's centre. */
.pw-mode-heading .products-filter-title {
    margin-bottom: 0;
}

.pw-modes {
    display: flex;
    flex-shrink: 0;
    border: 1px solid var(--fd-line);
    border-radius: 6px;
    overflow: hidden;
}

.pw-mode {
    font: inherit;
    font-size: 12.5px;
    padding: 5px 14px;
    border: 0;
    background: var(--fd-surface);
    color: var(--fd-ink-2);
    cursor: pointer;
    white-space: nowrap;
    transition: background .12s ease, color .12s ease;
}

.pw-mode + .pw-mode {
    border-left: 1px solid var(--fd-line);
}

.pw-mode:hover {
    background: var(--fd-sunken);
}

.pw-mode.is-on {
    background: var(--fd-accent);
    color: #fff;
    font-weight: 600;
}

.pw-mode:focus-visible,
.pw-btn:focus-visible,
.pw-chip:focus-visible,
.pw-row:focus-visible {
    outline: 2px solid var(--fd-accent);
    outline-offset: 2px;
}

.pw-counts {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}

.pw-count {
    font-size: 11.5px;
    padding: 2px 9px;
    border-radius: 20px;
    border: 1px solid var(--fd-line);
    background: var(--fd-sunken);
    color: var(--fd-ink-2);
    white-space: nowrap;
}

.pw-count.is-todo {
    background: var(--fd-warn-soft);
    border-color: transparent;
    color: var(--fd-warn);
    font-weight: 600;
}

.pw-count.is-ready {
    background: var(--fd-good-soft);
    border-color: transparent;
    color: var(--fd-good);
    font-weight: 600;
}

.pw-spacer {
    flex-grow: 1;
}

.pw-btn {
    font: inherit;
    font-size: 12.5px;
    padding: 5px 12px;
    border-radius: 6px;
    border: 1px solid var(--fd-line);
    background: var(--fd-surface);
    color: var(--fd-ink-2);
    cursor: pointer;
    white-space: nowrap;
    transition: background .12s ease, color .12s ease, border-color .12s ease;
}

.pw-btn:hover:not(:disabled) {
    background: var(--fd-sunken);
    border-color: var(--fd-rule);
}

.pw-btn:disabled {
    opacity: .55;
    cursor: default;
}

.pw-btn-primary {
    background: var(--fd-accent);
    border-color: var(--fd-accent);
    color: #fff;
    font-weight: 600;
}

.pw-btn-primary:hover:not(:disabled) {
    background: var(--fd-accent-ink);
    border-color: var(--fd-accent-ink);
    color: #fff;
}

/* ── Batch bar ────────────────────────────────────────────────────────────── */

.pw-batch {
    flex-shrink: 0;
    margin-top: 12px;
    border: 1px solid var(--fd-hero-line);
    border-radius: 8px;
    background: var(--fd-hero-bg);
    overflow: hidden;
}

.pw-batch-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
    padding: 8px 14px;
    border-bottom: 1px solid var(--fd-hero-line);
    background: var(--fd-hero-head);
}

.pw-batch-head h3 {
    margin: 0;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--fd-ink);
}

.pw-batch-note {
    font-size: 11px;
    color: var(--fd-ink-2);
}

.pw-batch-body {
    padding: 11px 14px;
    display: flex;
    flex-direction: column;
    gap: 9px;
    /* The bar can grow past a comfortable height on a wide selection with many duty
       categories; let it scroll rather than push the list off the page. */
    max-height: 46vh;
    overflow-y: auto;
}

/* Sits below the scrolling body, so the one control that commits anything is always on screen
   however many duty groups a selection happens to have. */
.pw-batch-foot {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    flex-shrink: 0;
    padding: 10px 14px;
    border-top: 1px solid var(--fd-hero-line);
    background: var(--fd-hero-head);
}

.pw-batch-foot.is-pending {
    background: var(--fd-warn-soft);
    border-top-color: var(--fd-warn);
}

.pw-pending {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    font-weight: 600;
    color: var(--fd-warn);
}

.pw-pending svg {
    flex-shrink: 0;
}

/* Three columns, not three rows. Each field carries its own label above its controls, so the
   bar costs one row of height instead of three and the list keeps the screen. */
.pw-fields {
    display: flex;
    align-items: stretch;
    gap: 16px;
    flex-wrap: wrap;
}

/* Size to content and never grow. Growing is what shoved Buyer's Commission against the far
   edge; not growing is the whole fix, and the fields pack left with the slack on the right.
   Freight and commission are fixed runs of chips, so they must not squash either. */
.pw-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
    flex: 0 0 auto;
}

/* Duty is the one whose width varies with the selection, so it is the one that gives way and
   wraps its own groups when the row genuinely runs out of room.
   No max-width: a cap here forced that wrap at a fixed width even with hundreds of pixels to
   spare, which was fixing the wrong half of the problem above. */
.pw-field-duty {
    flex-shrink: 1;
}

/* A rule between columns rather than gap alone; at this density the three otherwise read as
   one run of controls. */
.pw-field + .pw-field {
    border-left: 1px solid var(--fd-line-2);
    padding-left: 16px;
}

.pw-field-label {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--fd-ink-3);
}

.pw-field-body {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
    min-width: 0;
}

/* 1px separators inside a flex column collapse to nothing without this — the same bite
   documented in memory/reference_flex_separator_shrink. */
.pw-sep {
    height: 1px;
    background: var(--fd-line-2);
    flex-shrink: 0;
}

.pw-chip {
    font: inherit;
    font-size: 13px;
    padding: 5px 14px;
    border-radius: 6px;
    border: 1px solid var(--fd-line);
    background: var(--fd-surface);
    color: var(--fd-ink-2);
    cursor: pointer;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    transition: background .12s ease, color .12s ease, border-color .12s ease;
}

.pw-chip:hover:not(:disabled) {
    border-color: var(--fd-accent);
    color: var(--fd-accent-ink);
}

.pw-chip.is-on {
    background: var(--fd-accent);
    border-color: var(--fd-accent);
    color: #fff;
    font-weight: 600;
}

.pw-chip-other {
    border-style: dashed;
    color: var(--fd-ink-3);
}

.pw-hint {
    font-size: 11.5px;
    color: var(--fd-ink-3);
}

.pw-hint-good {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 11.5px;
    color: var(--fd-good);
    font-weight: 600;
}

.pw-inline-input {
    font: inherit;
    font-size: 13px;
    font-variant-numeric: tabular-nums;
    width: 96px;
    padding: 4px 8px;
    border: 1px solid var(--fd-line);
    border-radius: 5px;
    background: var(--fd-surface);
    color: var(--fd-ink);
}

/* Freight and duty entry sit inside chip rows, so they match a chip's height rather than a
   form field's. */
.pw-inline-input-sm {
    width: 78px;
}

.pw-inline-input:focus {
    outline: 2px solid var(--fd-accent);
    outline-offset: -1px;
    border-color: var(--fd-accent);
}

/* ── Duty groups ──────────────────────────────────────────────────────────── */

/* One line, chip height.
   Stacked (name over input) each group stood about twice a chip's height, so the field row
   read as two rows of different things rather than one row of three controls. Laid out
   horizontally it matches the freight and commission chips beside it exactly. */
.pw-group-pill {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 3px 8px 3px 11px;
    border-radius: 6px;
    border: 1px solid var(--fd-line);
    background: var(--fd-surface);
    /* Matches .pw-chip's box: 13px text, 5px vertical padding, 1px border. */
    min-height: 33px;
    white-space: nowrap;
}

.pw-group-pill.is-uncategorized {
    border-style: dashed;
    border-color: var(--fd-rule);
    background: var(--fd-sunken);
}

.pw-group-pill.is-drifted {
    border-color: var(--fd-warn);
    background: var(--fd-warn-soft);
}

/* Staged for writing on Save. Distinct from is-pinned, which is only about what the list is
   showing — a group can be one, the other, both or neither, and conflating them is how you end
   up writing a commission to rows you only meant to look at. */
.pw-group-pill.is-staged {
    border-color: var(--fd-accent);
    background: var(--fd-hero-bg);
}

/* The write control inside a commission pill, mirroring where the duty rate box sits. */
.pw-stage-check {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin: 0;
    padding: 2px 6px;
    border-radius: 5px;
    border: 1px solid var(--fd-line);
    background: var(--fd-surface);
    font-size: 11px;
    color: var(--fd-ink-2);
    cursor: pointer;
    white-space: nowrap;
}

.pw-stage-check:hover {
    border-color: var(--fd-accent);
    color: var(--fd-accent-ink);
}

/* Explicit box. The UA and Bootstrap both give a checkbox its own margins and a size larger
   than this pill wants, which is what left a hand's width of air between the tick and "Set". */
.pw-stage-check input {
    width: 13px;
    height: 13px;
    margin: 0;
    flex-shrink: 0;
    cursor: pointer;
}

.is-staged .pw-stage-check {
    border-color: var(--fd-accent);
    color: var(--fd-accent-ink);
    font-weight: 600;
}

.pw-duty-name {
    font-size: 12.5px;
    color: var(--fd-ink-2);
    white-space: nowrap;
}

.pw-duty-name b {
    color: var(--fd-ink);
    font-weight: 600;
}

/* ⚠ The markup inside these flex rows deliberately has no whitespace between elements.
   .pw-group-pill sets white-space: nowrap, and that inherits — which stops a flex container
   discarding the whitespace between its children, because a non-collapsible space is no longer
   "white space" for that rule. The newline between an <input> and the <span> after it then
   renders as a real space AND takes a gap on each side, which is what made the "Set" control
   twice the width it needed. Keep those tags adjacent. */
.pw-duty-entry {
    display: flex;
    align-items: center;
    gap: 5px;
}

/* Shorter than a standalone field so the pill does not tower over a chip, and right-aligned
   because these are read as a column of rates when several groups sit side by side.

   ⚠ Targets the rate box by class, not "any input in a pill". As a bare `.pw-duty-entry input`
   it also matched the commission pill's checkbox — same specificity, declared later, so it won
   — and stretched a 13px tick to 66px. Any new control inside a pill would have been next. */
.pw-duty-entry .pw-inline-input {
    width: 66px;
    padding: 2px 6px;
    text-align: right;
    border-radius: 4px;
}

.pw-duty-unit {
    font-size: 11px;
    color: var(--fd-ink-3);
}

/* Inside a pill the link sits among 11px labels, so it takes their size rather than the 12.5px
   it inherits elsewhere — at full size it read as the loudest thing in the row. */
.pw-group-pill .pw-link-btn {
    font-size: 11px;
}

.pw-duty-was {
    font-size: 11px;
    color: var(--fd-warn);
    font-weight: 600;
    white-space: nowrap;
}

/* ── Duty free ────────────────────────────────────────────────────────────────
   Duty-free is a property of the item (Item.IsDutyFree), not a rate: these rows are still
   priced at their category's duty, and the duty not paid at entry is margin. Green, because
   it is good news, and small, because it changes nothing the pricer types.

   The fallbacks are for the Search grid, which sits outside .pw-page where the --fd-* tokens
   are defined. */
.pw-duty-free-tag {
    display: inline-block;
    padding: 0 5px;
    border-radius: 4px;
    font-size: 10.5px;
    font-weight: 600;
    line-height: 16px;
    color: var(--fd-good, #0b6b4a);
    background: var(--fd-good-soft, #ddf0e8);
    white-space: nowrap;
    vertical-align: middle;
}

/* In a worklist row the tag shares the 78px duty column with the rate, so it shrinks to "DF". */
.pw-row .pw-duty-free-tag {
    margin-right: 4px;
    padding: 0 4px;
    font-size: 10px;
}

/* In the row detail's build-up the tag follows the rate; Razor drops the space between them. */
.pw-buildup-row .pw-duty-free-tag {
    margin-left: 6px;
}

.pw-group-pill.is-duty-free {
    border-color: var(--fd-good);
    background: var(--fd-good-soft);
}

.pw-group-pill.is-duty-free .pw-duty-name {
    color: var(--fd-good);
}

/* "Mark Duty Free" when nothing selected is tagged yet. The same green box as the Duty Free pill
   it turns into, at the same 33px height as the pills and chips beside it. */
.pw-duty-free-btn {
    display: inline-flex;
    align-items: center;
    min-height: 33px;
    padding: 3px 11px;
    border-radius: 6px;
    border: 1px solid var(--fd-good);
    background: var(--fd-good-soft);
    color: var(--fd-good);
    font: inherit;
    font-size: 12.5px;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
}

.pw-duty-free-btn:hover:not(:disabled) {
    background: var(--fd-good);
    color: #fff;
}

.pw-duty-free-btn:focus-visible {
    outline: 2px solid var(--fd-good);
    outline-offset: 2px;
}

.pw-duty-free-btn:disabled {
    opacity: 0.55;
    cursor: default;
}

/* ── Alerts ───────────────────────────────────────────────────────────────── */

.pw-alert {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 9px 12px;
    border-radius: 6px;
    background: var(--fd-warn-soft);
    border-left: 3px solid var(--fd-warn);
    font-size: 12px;
    line-height: 1.45;
    color: var(--fd-ink-2);
}

.pw-alert b {
    color: var(--fd-warn);
}

.pw-alert svg {
    flex-shrink: 0;
    margin-top: 1px;
    color: var(--fd-warn);
}

.pw-alert-bad {
    background: var(--fd-bad-soft);
    border-left-color: var(--fd-bad);
}

.pw-alert-bad b,
.pw-alert-bad svg {
    color: var(--fd-bad);
}

.pw-link-btn {
    font: inherit;
    font-size: inherit;
    font-weight: 600;
    padding: 0;
    border: 0;
    background: none;
    color: var(--fd-accent-ink);
    text-decoration: underline;
    cursor: pointer;
}

.pw-link-btn:hover {
    color: var(--fd-accent);
}

/* ── Body: list + detail ──────────────────────────────────────────────────── */

.pw-body {
    display: flex;
    flex: 1;
    min-height: 0;
    gap: 16px;
    padding-top: 13px;
}

.pw-list {
    flex: 1;
    min-width: 0;
    min-height: 0;
    border: 1px solid var(--fd-rule);
    border-radius: 8px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    background: var(--fd-surface);
}

.pw-list-scroll {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
}

.pw-colhead {
    display: grid;
    grid-template-columns: var(--pw-cols);
    align-items: center;
    flex-shrink: 0;
    border-bottom: 1px solid var(--fd-rule);
    background: var(--fd-head-bg);
    font-size: 9.5px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--fd-ink-3);
}

.pw-colhead > span {
    padding: 8px 6px;
}

.pw-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* The ours/theirs divide. The left edge of the first tinted cell is the rule. */
.pw-ours {
    background: var(--fd-hero-bg);
}

.pw-colhead .pw-ours {
    background: var(--fd-hero-head);
    color: var(--fd-accent-ink);
}

.pw-ours-start {
    border-left: 2px solid var(--fd-hero-line);
}

/* ── Lanes ────────────────────────────────────────────────────────────────── */

.pw-lane {
    display: flex;
    align-items: center;
    gap: 9px;
    flex-wrap: wrap;
    padding: 6px 12px;
    border-bottom: 1px solid var(--fd-line);
    position: sticky;
    top: 0;
    z-index: 1;
}

.pw-lane + .pw-row {
    border-top: 0;
}

.pw-lane-todo {
    background: var(--fd-warn-soft);
}

.pw-lane-ready {
    background: var(--fd-good-soft);
}

.pw-lane-blocked {
    background: var(--fd-rail-bg);
}

.pw-lane-title {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.pw-lane-todo .pw-lane-title { color: var(--fd-warn); }
.pw-lane-ready .pw-lane-title { color: var(--fd-good); }
.pw-lane-blocked .pw-lane-title { color: var(--fd-ink-2); }

.pw-lane-note {
    font-size: 11.5px;
    color: var(--fd-ink-2);
}

.pw-lane-btn {
    font: inherit;
    font-size: 11px;
    font-weight: 600;
    padding: 2px 9px;
    border-radius: 5px;
    border: 1px solid var(--fd-line);
    background: var(--fd-surface);
    color: var(--fd-ink-2);
    cursor: pointer;
    white-space: nowrap;
}

.pw-lane-btn:hover {
    border-color: var(--fd-accent);
    color: var(--fd-accent-ink);
}

/* ── Rows ─────────────────────────────────────────────────────────────────── */

.pw-row {
    display: grid;
    grid-template-columns: var(--pw-cols);
    align-items: center;
    width: 100%;
    border: 0;
    border-bottom: 1px solid var(--fd-line-2);
    background: var(--fd-surface);
    text-align: left;
    font: inherit;
    cursor: pointer;
    transition: background .1s ease;

    /* Shift-click extends the selection, and without this every range drags a blue smear of
       selected text across the rows it crossed. The row's text is readable and selectable in
       the detail panel, which is where copying it from belongs anyway. */
    user-select: none;
}

.pw-row:hover {
    background: var(--fd-sunken);
}

.pw-row.is-selected {
    background: var(--fd-sunken);
}

/* Focus and selection are different jobs — the checkbox picks the batch, clicking the row
   picks what the panel reads. The inset bar is what says "this is the one you're looking at". */
.pw-row.is-focused {
    background: var(--fd-accent-soft);
    box-shadow: inset 3px 0 0 var(--fd-accent);
}

.pw-row.is-focused:hover {
    background: var(--fd-accent-soft);
}

.pw-row.is-ignored {
    opacity: .6;
}

/* The pinned-group bar. Sits above the scroller, so the way out of a pin is never itself
   scrolled out of view. */
.pw-pinned-bar {
    display: flex;
    align-items: center;
    gap: 9px;
    flex-shrink: 0;
    padding: 7px 12px;
    background: var(--fd-accent-soft);
    border-bottom: 1px solid var(--fd-hero-line);
    font-size: 12px;
    color: var(--fd-accent-ink);
}

.pw-pinned-bar svg {
    flex-shrink: 0;
}

.pw-pinned-bar b {
    font-weight: 600;
}

/* A pinned group reads as pressed, so it is obvious which pill is doing the filtering. */
.pw-group-pill {
    cursor: pointer;
}

.pw-group-pill.is-pinned {
    border-color: var(--fd-accent);
    background: var(--fd-accent-soft);
    box-shadow: inset 0 0 0 1px var(--fd-accent);
}

.pw-group-pill.is-pinned .pw-duty-name,
.pw-group-pill.is-pinned .pw-duty-name b {
    color: var(--fd-accent-ink);
    font-weight: 600;
}

.pw-group-pill:focus-visible {
    outline: 2px solid var(--fd-accent);
    outline-offset: 2px;
}

/* Pointing at a duty or commission group in the batch bar dims everything it does not cover,
   rather than marking the rows it does. Subtraction reads faster here: the eye finds what is
   left rather than hunting for a badge, and it costs no column width in an already dense row.
   No transition — this tracks the pointer, and a fade would lag behind it. */
.pw-list.is-highlighting .pw-row:not(.is-highlighted) {
    opacity: .25;
}

.pw-list.is-highlighting .pw-row.is-highlighted {
    background: var(--fd-accent-soft);
}

.pw-row > span {
    padding: 6px;
    font-size: 12.5px;
    color: var(--fd-ink-2);
    min-width: 0;
}

.pw-cell-check {
    padding: 0 0 0 8px !important;
    display: flex;
    align-items: center;
}

.pw-cell-thumb {
    padding: 5px 4px !important;
}

.pw-thumb {
    display: block;
    width: 34px;
    height: 34px;
    border-radius: 4px;
    border: 1px solid var(--fd-line);
    object-fit: contain;
    background: var(--fd-surface);
}

/* The thumbnail is its own control: it opens the larger image and, in a row, leaves the detail
   panel's focus where it was. Shared by the list rows and the detail panel's own header, which
   is why it sets no size of its own — the image inside it carries that. */
.pw-thumb-btn {
    display: block;
    padding: 0;
    border: 0;
    background: none;
    line-height: 0;
    border-radius: 4px;
    cursor: zoom-in;
    flex-shrink: 0;
}

.pw-thumb-btn:hover .pw-thumb,
.pw-thumb-btn:hover .pw-detail-thumb {
    border-color: var(--fd-accent);
}

.pw-thumb-btn:focus-visible {
    outline: 2px solid var(--fd-accent);
    outline-offset: 1px;
}

.pw-thumb-empty {
    background: repeating-linear-gradient(45deg,
        var(--fd-sunken), var(--fd-sunken) 5px,
        var(--fd-line-2) 5px, var(--fd-line-2) 10px);
}

.pw-sku {
    font-weight: 600;
    color: var(--fd-ink) !important;
    font-variant-numeric: tabular-nums;
}

.pw-truncate {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pw-cost {
    color: var(--fd-money) !important;
    font-weight: 600;
}

.pw-blank {
    color: var(--fd-ink-3) !important;
}

.pw-filled {
    color: var(--fd-ink) !important;
    font-weight: 600;
}

.pw-flag {
    display: inline-flex;
    align-items: center;
    justify-content: flex-end;
    gap: 4px;
    color: var(--fd-warn) !important;
    font-weight: 600;
}

.pw-flag-bad {
    color: var(--fd-bad) !important;
}

.pw-empty {
    padding: 40px 16px;
    text-align: center;
    color: var(--fd-ink-3);
    font-size: 13px;
}

.pw-empty b {
    display: block;
    font-size: 15px;
    color: var(--fd-ink);
    margin-bottom: 4px;
}

/* ── Detail panel ─────────────────────────────────────────────────────────── */

.pw-detail {
    width: 468px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    min-height: 0;
    border: 1px solid var(--fd-rule);
    border-radius: 8px;
    background: var(--fd-surface);
    overflow: hidden;
}

/* Holds the panel's full height so the empty state occupies exactly the space the loaded
   panel will, and focusing a row never shifts the layout. */
.pw-detail-placeholder {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 7px;
    padding: 24px 32px;
    text-align: center;
    color: var(--fd-ink-3);
}

.pw-detail-placeholder svg {
    color: var(--fd-rule);
    margin-bottom: 2px;
}

.pw-detail-placeholder b {
    font-size: 14px;
    font-weight: 600;
    color: var(--fd-ink-2);
}

.pw-detail-placeholder span {
    font-size: 12.5px;
    line-height: 1.5;
    max-width: 30ch;
}

.pw-detail-head {
    display: flex;
    align-items: flex-start;
    gap: 11px;
    padding: 11px 13px;
    border-bottom: 1px solid var(--fd-line);
    background: var(--fd-sunken);
    flex-shrink: 0;
}

.pw-detail-thumb {
    width: 42px;
    height: 42px;
    border-radius: 6px;
    border: 1px solid var(--fd-line);
    object-fit: contain;
    padding: 2px;
    background: var(--fd-surface);
    flex-shrink: 0;
}

.pw-detail-id {
    flex: 1;
    min-width: 0;
}

.pw-detail-sku {
    font-size: 15px;
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--fd-ink);
    font-variant-numeric: tabular-nums;
}

.pw-detail-desc {
    font-size: 12px;
    color: var(--fd-ink-2);
    margin-top: 1px;
}

.pw-pills {
    display: flex;
    gap: 5px;
    flex-wrap: wrap;
    margin-top: 6px;
}

.pw-pill {
    font-size: 11px;
    padding: 2px 8px;
    border-radius: 20px;
    border: 1px solid var(--fd-line);
    background: var(--fd-surface);
    color: var(--fd-ink-2);
    white-space: nowrap;
}

.pw-pill-good {
    background: var(--fd-good-soft);
    border-color: transparent;
    color: var(--fd-good);
    font-weight: 600;
}

.pw-pill-warn {
    background: var(--fd-warn-soft);
    border-color: transparent;
    color: var(--fd-warn);
    font-weight: 600;
}

/* Expired pricing: the same "Priced <date>" pill the fresh case uses, in red instead of green.
   The date is the fact; whether it still stands is what the color carries. Kept separate from
   .pw-pill-warn, which "Archived" uses and which is a note rather than a problem. */
.pw-pill-bad {
    background: var(--fd-bad-soft);
    border-color: transparent;
    color: var(--fd-bad);
    font-weight: 600;
}

.pw-detail-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 12px 13px;
    display: flex;
    flex-direction: column;
    gap: 11px;
}

/* .pw-card has overflow:hidden, so in a flex column it clips instead of scrolling unless
   it keeps its natural height — see memory/reference_flex_separator_shrink. */
.pw-card {
    border: 1px solid var(--fd-line);
    border-radius: 8px;
    overflow: hidden;
    flex-shrink: 0;
}

.pw-card-hero {
    border-color: var(--fd-hero-line);
    background: var(--fd-hero-bg);
}

.pw-card-warn { border-color: var(--fd-warn); }
.pw-card-bad { border-color: var(--fd-bad); }

.pw-card-head {
    display: flex;
    align-items: baseline;
    gap: 9px;
    padding: 8px 13px;
    border-bottom: 1px solid var(--fd-line-2);
    background: var(--fd-head-bg);
}

.pw-card-hero .pw-card-head {
    background: var(--fd-hero-head);
    border-bottom-color: var(--fd-hero-line);
}

.pw-card-warn .pw-card-head {
    background: var(--fd-warn-soft);
    border-bottom-color: var(--fd-warn);
}

.pw-card-bad .pw-card-head {
    background: var(--fd-bad-soft);
    border-bottom-color: var(--fd-bad);
}

.pw-card-head h3 {
    margin: 0;
    font-size: 12.5px;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--fd-ink);
}

.pw-card-verdict {
    margin-left: auto;
    font-size: 11px;
    font-weight: 600;
}

.pw-verdict-good { color: var(--fd-good); }
.pw-verdict-warn { color: var(--fd-warn); }
.pw-verdict-bad { color: var(--fd-bad); }
.pw-verdict-quiet { color: var(--fd-ink-3); font-weight: 400; }

.pw-card-body {
    padding: 10px 13px;
}

.pw-cube {
    display: flex;
    gap: 20px;
    align-items: flex-start;
    flex-wrap: wrap;
}

.pw-figure-label {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--fd-ink-3);
    margin-bottom: 2px;
}

.pw-figure-value {
    font-size: 26px;
    font-weight: 600;
    letter-spacing: -0.03em;
    color: var(--fd-accent-ink);
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}

.pw-figure-value.is-warn { color: var(--fd-warn); }
.pw-figure-value.is-bad { color: var(--fd-bad); }

.pw-figure-sub {
    font-size: 11px;
    color: var(--fd-ink-3);
    margin-top: 2px;
}

.pw-cube-lines {
    flex: 1;
    min-width: 180px;
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.pw-kv {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    font-size: 12px;
    color: var(--fd-ink-2);
}

.pw-kv > span:last-child {
    color: var(--fd-ink);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.pw-buildup-row {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 4px 0;
    border-bottom: 1px solid var(--fd-line-2);
    font-size: 12.5px;
    color: var(--fd-ink-2);
}

.pw-buildup-row > span:last-child {
    color: var(--fd-ink);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.pw-buildup-qual {
    color: var(--fd-ink-3);
    font-size: 11px;
}

.pw-buildup-total {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    padding: 8px 0 1px;
    font-size: 13px;
    font-weight: 600;
    color: var(--fd-ink);
}

.pw-buildup-total > span:last-child {
    font-size: 18px;
    letter-spacing: -0.02em;
    color: var(--fd-accent-ink);
    font-variant-numeric: tabular-nums;
}

.pw-break {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    font-size: 12.5px;
    padding: 3px 6px;
    margin: 0 -6px;
    border-radius: 4px;
    color: var(--fd-ink-3);
}

.pw-break.is-applied {
    background: var(--fd-good-soft);
    color: var(--fd-ink);
}

.pw-break-figures {
    display: flex;
    gap: 14px;
    font-variant-numeric: tabular-nums;
}

.pw-break-landed {
    width: 56px;
    text-align: right;
}

.pw-break.is-applied .pw-break-landed {
    color: var(--fd-money);
    font-weight: 600;
}

.pw-note-lines {
    font-size: 12px;
    line-height: 1.5;
    color: var(--fd-ink-2);
    display: flex;
    flex-direction: column;
    gap: 3px;
}

/* ── Modal shell, shared by the apply preview and the duty rates table ─────── */

.pw-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(15, 29, 51, .42);
    z-index: 1200;
}

.pw-modal {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    z-index: 1201;
    pointer-events: none;
}

.pw-modal-card {
    pointer-events: auto;
    width: min(760px, 100%);
    max-height: 100%;
    display: flex;
    flex-direction: column;
    border: 1px solid var(--fd-rule);
    border-radius: 10px;
    background: var(--fd-surface);
    box-shadow: 0 18px 44px rgba(15, 29, 51, .18);
    overflow: hidden;
}

.pw-modal-wide {
    width: min(980px, 100%);
}

.pw-modal-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 11px 16px;
    border-bottom: 1px solid var(--fd-hero-line);
    background: var(--fd-hero-head);
    flex-shrink: 0;
}

.pw-modal-head h2 {
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--fd-ink);
}

.pw-modal-sub {
    margin-left: auto;
    font-size: 11.5px;
    color: var(--fd-ink-2);
}

.pw-modal-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 14px 16px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.pw-modal-foot {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 11px 16px;
    border-top: 1px solid var(--fd-line);
    background: var(--fd-sunken);
    flex-shrink: 0;
    flex-wrap: wrap;
}

.pw-modal-close {
    font: inherit;
    font-size: 18px;
    line-height: 1;
    padding: 2px 8px;
    border: 0;
    background: none;
    color: var(--fd-ink-3);
    cursor: pointer;
}

.pw-modal-close:hover {
    color: var(--fd-ink);
}

.pw-section-title {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 12.5px;
    font-weight: 600;
}

.pw-section-title.is-good { color: var(--fd-good); }
.pw-section-title.is-warn { color: var(--fd-warn); }

.pw-indent {
    padding-left: 21px;
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.pw-tally {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    font-size: 12px;
    color: var(--fd-ink-2);
    padding: 2px 0;
    border-bottom: 1px solid var(--fd-line-2);
}

.pw-tally:last-child {
    border-bottom: 0;
}

.pw-skip {
    display: flex;
    align-items: baseline;
    gap: 8px;
    font-size: 12px;
}

.pw-skip-sku {
    font-weight: 600;
    color: var(--fd-ink);
    font-variant-numeric: tabular-nums;
    width: 92px;
    flex-shrink: 0;
}

/* ── Assign duty category ─────────────────────────────────────────────────── */

.pw-select {
    font: inherit;
    font-size: 12.5px;
    padding: 4px 8px;
    border: 1px solid var(--fd-line);
    border-radius: 5px;
    background: var(--fd-surface);
    color: var(--fd-ink);
    max-width: 100%;
}

.pw-select:focus {
    outline: 2px solid var(--fd-accent);
    outline-offset: -1px;
    border-color: var(--fd-accent);
}

.pw-assign-bulk {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 10px 12px;
    border-radius: 6px;
    border: 1px solid var(--fd-hero-line);
    background: var(--fd-hero-bg);
}

.pw-assign-list {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--fd-rule);
    border-radius: 8px;

    /* Both axes named, for the reason spelled out on .pw-rates: a flex item whose overflow is
       not `visible` has an automatic minimum size of zero, so plain `hidden` let this list be
       shrunk to the space left over and silently swallowed the items past the fold — a
       selection of thirty showed nine, with no scrollbar to reach the rest. */
    overflow: hidden auto;
    min-height: 120px;
}

.pw-assign-row {
    display: grid;
    grid-template-columns: 46px 104px minmax(0, 1fr) 240px;
    align-items: center;
    gap: 10px;
    padding: 6px 12px;
    border-bottom: 1px solid var(--fd-line-2);
    font-size: 12.5px;
    color: var(--fd-ink-2);
}

.pw-assign-row:last-child {
    border-bottom: 0;
}

.pw-assign-row:nth-child(even) {
    background: var(--fd-sunken);
}

@media (max-width: 700px) {
    .pw-assign-row {
        grid-template-columns: 46px minmax(0, 1fr);
        row-gap: 4px;
    }

    /* The description is the first thing to go when there is no room for four columns. */
    .pw-assign-row > .pw-truncate {
        display: none;
    }
}

/* ── Duty rates table ─────────────────────────────────────────────────────── */

/* align-items must stay stretch (the default). With `center`, each cell is only as tall as its
   own content and sits in the middle of the row — so on a drifted row the short cells painted
   their amber over part of the row height and the card's white showed through above and below,
   most visibly behind the action buttons. The cells centre their own content instead. */
.pw-rates {
    display: grid;
    grid-template-columns: 168px 104px 96px minmax(0, 1fr) 158px;
    align-items: stretch;
    border: 1px solid var(--fd-rule);
    border-radius: 8px;

    /* The scroll belongs to this grid rather than to .pw-modal-body: the categories are the only
       thing in the modal long enough to scroll, and putting it here lets the column headings stay
       pinned while the alert above and the footnote below hold still.

       `overflow` has to name both axes rather than being plain `hidden`. As a flex item of the
       modal body, any overflow that is not `visible` sets this box's automatic minimum size to
       zero — so with `hidden` it was squeezed to whatever height happened to be left and clipped
       the remaining categories outright, with no scrollbar anywhere to reach them. Keeping x
       hidden preserves the corner clipping the border-radius needs. */
    overflow: hidden auto;

    /* A short viewport must not crush it to the header row alone; the body scrolls first. */
    min-height: 132px;
}

/* Pinned, so a scroll past the tenth category still says which column is the rate on file and
   which is the rate people type. This works only because .pw-rates is the scroll container
   itself — sticky resolves against the nearest scrolling ancestor. */
.pw-rates > .pw-rates-head {
    position: sticky;
    top: 0;
    z-index: 1;
    padding: 8px;
    background: var(--fd-head-bg);
    border-bottom: 1px solid var(--fd-rule);
    font-size: 9.5px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--fd-ink-3);
}

.pw-rates > .pw-rates-cell {
    padding: 8px;
    font-size: 12.5px;
    color: var(--fd-ink-2);
    border-bottom: 1px solid var(--fd-line-2);
    min-width: 0;
}

/* Each cell centres its own content now that the grid stretches them. */
.pw-rates > .pw-rates-cell,
.pw-rates > .pw-rates-head {
    display: flex;
    align-items: center;
}

/* text-align does not move a flex item, so the numeric and action columns need this to keep
   sitting on the right edge. */
.pw-rates > .pw-num {
    justify-content: flex-end;
    gap: 6px;
}

.pw-rates > .is-drifted {
    background: var(--fd-warn-soft);
}

.pw-rate-old {
    color: var(--fd-ink-3);
    text-decoration: line-through;
    font-variant-numeric: tabular-nums;
}

.pw-rate-new {
    color: var(--fd-warn);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* ── Editing a rate in place ───────────────────────────────────────────────
   Every rate is a field for an administrator, but a field that stays invisible until it is
   pointed at. Forty boxed inputs would turn a table people read into a form they have to
   parse; a transparent border keeps the column reading as figures until the pointer or the
   keyboard says otherwise.
   ────────────────────────────────────────────────────────────────────────── */

.pw-rate-edit {
    display: inline-flex;
    align-items: center;
    gap: 2px;
}

.pw-rate-input {
    font: inherit;
    font-size: 12.5px;
    font-variant-numeric: tabular-nums;
    text-align: right;
    width: 60px;
    padding: 3px 4px;
    border: 1px solid transparent;
    border-radius: 5px;
    background: transparent;
    color: var(--fd-ink-2);
}

.pw-rate-input:hover:not(:disabled) {
    border-color: var(--fd-line);
    background: var(--fd-surface);
}

.pw-rate-input:focus {
    outline: 2px solid var(--fd-accent);
    outline-offset: -1px;
    border-color: var(--fd-accent);
    background: var(--fd-surface);
    color: var(--fd-ink);
}

/* Typed but not yet saved. The field has to keep saying so after focus moves to the Save
   button beside it, which is why this is not folded into :focus. */
.pw-rate-input.is-dirty {
    border-color: var(--fd-accent);
    background: var(--fd-surface);
    color: var(--fd-ink);
    font-weight: 600;
}

.pw-rate-input.is-invalid {
    border-color: var(--fd-bad);
    background: var(--fd-bad-soft);
    color: var(--fd-bad);
}

.pw-rate-input:disabled {
    opacity: .55;
}

.pw-rate-suffix {
    font-size: 11.5px;
    color: var(--fd-ink-3);
}

/* Why a rate was refused, on its own full-width line under the row it belongs to — the cells
   are too narrow for a sentence and a tooltip is not an error message. */
.pw-rates-note {
    grid-column: 1 / -1;
    padding: 0 8px 8px;
    margin-top: -1px;
    font-size: 11.5px;
    color: var(--fd-bad);
    border-bottom: 1px solid var(--fd-line-2);
}

/* The add-a-category form under the rates table. Its inputs reuse .pw-rate-input, but as a
   standalone form they keep a visible border rather than earning one on hover like the
   in-table edits do. */
.pw-rate-add {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 10px;
}

.pw-rate-add .pw-rate-input {
    border-color: var(--fd-line);
    background: var(--fd-surface);
}

.pw-rate-add-name {
    width: 220px;
    text-align: left;
}

.pw-rate-add-note {
    border-bottom: none;
    padding: 4px 0 0;
    margin-top: 0;
}

.pw-meter {
    display: flex;
    align-items: center;
    gap: 8px;
}

.pw-meter-track {
    display: block;
    width: 92px;
    height: 5px;
    border-radius: 3px;
    background: var(--fd-line-2);
    overflow: hidden;
    flex-shrink: 0;
}

.pw-meter-track > i {
    display: block;
    height: 100%;
    background: var(--fd-good);
}

.is-drifted .pw-meter-track > i {
    background: var(--fd-warn);
}

/* ── Narrow viewports ─────────────────────────────────────────────────────── */

/* The panel is permanent, so it narrows rather than floating over the list — an always-open
   overlay would cover the rows it is meant to describe. */
@media (max-width: 1400px) {
    .pw-detail {
        width: 400px;
    }
}

@media (max-width: 1200px) {
    .pw-detail {
        width: 340px;
    }
}

@media (max-width: 900px) {
    .pw-page {
        --pw-cols: 30px 44px 96px minmax(0, 1fr) 72px 78px 74px 88px;
    }

    /* Below this the list and the panel cannot both be legible. The list wins — it is the
       thing you work down — and "Full factory page" carries the detail on a phone. */
    .pw-detail {
        display: none;
    }

    /* Factory, cost and units drop first: they are context, not the decision. */
    .pw-hide-narrow {
        display: none !important;
    }

    /* Once the columns wrap onto their own lines, a left rule points the wrong way. */
    .pw-field + .pw-field {
        border-left: 0;
        border-top: 1px solid var(--fd-line-2);
        padding-left: 0;
        padding-top: 10px;
    }
}
