/* =============================================================================
   amazonSalePricing.css — Amazon Sale Pricing (.asp-*)

   VISUAL LANGUAGE: the teal-blue Family A shared with Evri Claims (.ec-),
   Evri Claim Generator (.ecg-), Message Templates (.mt-), Support Cases (.sc-)
   and Listing Photos (.alp-) — soft cards, teal->blue gradient, 1.5px borders,
   10-16px radii, #0588b6 primary. The tokens below are the prototype's own
   :root block, value for value, renamed with an --asp- prefix.

   WHY THE TOKENS ARE PREFIXED AND SCOPED. The prototype declares --p, --line,
   --ink and friends on :root, which in this app would leak into every other
   screen and quietly restyle modules that use the same short names. They are
   scoped to .asp-page here instead, so this file cannot affect a pixel outside
   its own tab.

   ── S3 CORRECTIONS, AND WHAT EACH ONE WAS ───────────────────────────────────

   A1  THE MODULE IS CAPPED AND CENTRED at 1240px. Without it the screen
       stretches to the monitor width and the table columns drift apart from
       each other. The prototype's own comment on .wrap says "this is not
       decoration — build it", and S2 did not.

   A2  THREE CONTROLS, THREE SHAPES. S2 built the account switcher and the row
       filters as the same rounded pill, under a third pill bar, so three
       different jobs wore one shape:
         account switcher -> .asp-aseg  underline tabs (was a segmented control; see
                                        the note on .asp-aseg for why it changed)
         row filters      -> .asp-tabs  underline tabs, PLAIN count, no bubble
         view switcher    -> deleted (a one-item switcher switches nothing)
       The old .asp-chip / .asp-chips / .asp-nav rules are gone with it.

   A5  ONE TOOLBAR ROW, and the freshness moved into the footer. S2 stacked
       five full-width bands before the first row of data. .asp-tb carries the
       controls on one line; .asp-foot carries the counts, both freshness facts
       and the pager. The old .asp-fresh and .asp-pager rules are gone.

   A6  No Channel column — see the note in amazonSalePricing.js.

   ── THREE TRAPS THIS FILE IS STILL BUILT AROUND ─────────────────────────────

   1. THE GLOBAL INPUT MINIMUM. public/css/style.css line 1 sets
      min-width:170px on `input, select, textarea` UNSCOPED, and it beats any
      max-width. Every input here declares min-width:0 explicitly, or the search
      box overflows its toolbar.

   2. THE MOBILE TABLE REWRITE. Four global rules rewrite any table under
      1180px. This screen uses the DUAL-RENDER mechanism instead of fighting
      them (responsive.css:1267-1287): the desktop table carries .rk-deskonly
      and a hand-built .rk-cardlist twin renders the same fields as cards.
      .rk-deskonly is also one of the two classes mobileEnhance.js's cardifier
      checks for, so the table is exempt from the sweep AND hidden on mobile.
      NOTE .rk-ownmobile is a DIFFERENT opt-out, for a screen that keeps its own
      table on mobile. This screen does not; do not mix the two.

   3. DARK MODE LIVES IN THIS FILE, per the newer house pattern (VCE, Store
      Builder) rather than in the shared dark.css.
   ============================================================================= */

.asp-page{
  --asp-p:#0588b6; --asp-pd:#03658e; --asp-pl:#e6f4fa; --asp-pl2:#cfe9f4;
  --asp-card:#fff; --asp-line:#d7e4ec; --asp-ink:#17303d; --asp-mut:#6b8291;
  --asp-ok:#1f9d55; --asp-okl:#e5f6ec;
  --asp-warn:#b6791a; --asp-warnl:#fff4e0;
  --asp-bad:#c9403f; --asp-badl:#fdeceb;
  --asp-grey:#eef2f5; --asp-greyt:#5c6b78;
  --asp-r:16px; --asp-rs:10px;
  color:var(--asp-ink);

  /* A1 — capped and centred. Scoped to this module's own root: no other screen
     is touched, and the container this sits inside keeps whatever width it had. */
  max-width:1240px;
  margin:0 auto;
  width:100%;
}

/* ---- page header: eyebrow -> h2 -> sub -> right-aligned primary ----------- */
.asp-hd{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;margin:4px 0 14px;flex-wrap:wrap}
.asp-eyebrow{font-size:11px;font-weight:800;letter-spacing:.6px;text-transform:uppercase;color:var(--asp-p)}
.asp-page h2.asp-title{font-size:23px;margin:2px 0;font-weight:800;letter-spacing:-.2px;color:var(--asp-ink)}
.asp-sub{color:var(--asp-mut);font-size:13px}
.asp-hd .asp-acts{display:flex;gap:8px;align-items:center;flex-wrap:wrap}

/* ══════════════════════════ RESET THE APP'S BUTTON STYLING ══════════════════
 * MEASURED, NOT ASSUMED. Four global rules reach every <button> in this module:
 *
 *   style.css:1    button{background:#03658e;color:white;border:0;padding:13px 17px;
 *                         border-radius:13px;font-weight:900;margin:3px;
 *                         box-shadow:0 8px 18px rgba(3,101,142,.16)}
 *   style.css:1    button:hover{background:#064e6a;transform:translateY(-1px)}
 *   polish.css     button{background:var(--rms-primary)}
 *   polish.css     button:hover{transform:translateY(-1px);box-shadow:var(--rms-shadow-md)}
 *
 * The module's own rules already re-declared background, colour, padding and
 * font-weight — so THOSE looked right — but never margin, box-shadow, radius or
 * the hover transform, and an undeclared property is not a reset. Every control
 * in the module was therefore carrying a 3px margin, a drop shadow and a 12px
 * radius it never asked for, which is what made underline tabs read as boxes and
 * a segmented control read as two separate buttons.
 *
 * ONE rule that zeroes exactly what the globals inject, and then each control
 * below states what it actually wants. That is why there is no !important here:
 * .asp-page button (0,0,1,1) ties with .asp-aseg button / .asp-tabs button, so
 * IT MUST STAY ABOVE THEM IN THIS FILE — the tie is broken by source order.
 * .asp-page .asp-btn (0,0,2,0) outranks it outright.
 *
 * SCOPED TO .asp-page, which is set on this module's root element and on nothing
 * else in RMS, so none of it can reach another screen.
 * ═══════════════════════════════════════════════════════════════════════════ */
.asp-page button{background:none;color:inherit;border:0;border-radius:0;padding:0;margin:0;
  box-shadow:none;font:inherit;cursor:pointer}
/* The hover lift and shadow, which no per-control rule below re-declares.
   .asp-page button:hover (0,0,2,1) beats both global button:hover rules (0,0,1,1). */
.asp-page button:hover,.asp-page button:active{transform:none;box-shadow:none}

/* ---- buttons -------------------------------------------------------------- */
/* ══════════════════ ONE TYPE SCALE, AND WHY font:inherit IS NOT IT ══════════
 * MEASURED, not guessed. Every control in this module that carried `font:inherit` computed to
 * 16px, because that is RMS's page font — while the module's own scale runs 11.5px (column
 * headers, listing rows) to 14px (section headings, the view switcher), with body copy at 13px.
 * So a settings row put a 16px label and a 16px input beside a 12px hint, and the editor put
 * 16px fields beside 12px labels. Reported from a real screen as "font sizes seem off, too big".
 *
 * The prototype writes `font:inherit` throughout and is RIGHT to — its own body is 14px, so
 * inherit lands inside its scale. Copied verbatim into a 16px app it does not, which is the
 * same trap already recorded on the view switcher.
 *
 * So the size is pinned wherever a control would otherwise inherit the page. `font:inherit`
 * stays for the family and line-height; only the size is stated.
 *
 * THIS DELIBERATELY CHANGES DESKTOP. It is a correction, not mobile work, so the usual "new
 * CSS is gated at 1180px and desktop stays byte-for-byte identical" does not apply here — the
 * desktop rendering is the thing being corrected.
 * ═══════════════════════════════════════════════════════════════════════════ */
/* P3-B — THE SAME RULE SERVES AN <a>. "Put on sale" and "Open schedule" are anchors now (a real
   href, so right-click / middle-click / copy-link work) and must look exactly like the buttons
   they replace. The three declarations at the end are what an anchor lacks and a <button>
   already has from the browser — display:inline-block, no underline, line-height:normal — so
   they change nothing about any button and there is no second rule to drift. */
.asp-page .asp-btn{border:1.5px solid var(--asp-line);background:#fff;border-radius:var(--asp-rs);
  padding:8px 14px;font:inherit;font-size:14px;font-weight:600;cursor:pointer;color:var(--asp-ink);
  white-space:nowrap;display:inline-block;text-decoration:none;line-height:normal}
.asp-page .asp-btn:hover{border-color:#b9cdd9;background:#fbfdfe}
.asp-page .asp-btn.primary{background:linear-gradient(135deg,var(--asp-p),#1467a8);border-color:transparent;color:#fff}
.asp-page .asp-btn.primary:hover{filter:brightness(1.05)}
.asp-page .asp-btn.small{padding:5px 10px;font-size:12.5px;border-radius:8px}
.asp-page .asp-btn:disabled{opacity:.45;cursor:not-allowed}
.asp-page .asp-btn:focus-visible,
.asp-page .asp-search:focus-visible,
.asp-page .asp-aseg button:focus-visible,
.asp-page .asp-tabs button:focus-visible{outline:2px solid var(--asp-p);outline-offset:2px}

/* ---- cards, pills --------------------------------------------------------- */
.asp-card{background:var(--asp-card);border:1.5px solid var(--asp-line);border-radius:var(--asp-r);
  box-shadow:0 2px 10px rgba(3,101,142,.05)}
.asp-sample{display:inline-flex;align-items:center;gap:6px;background:var(--asp-warnl);color:var(--asp-warn);
  border:1.5px solid #f0d9a8;border-radius:999px;padding:3px 10px;font-size:12px;font-weight:800}
.asp-sample .d{width:8px;height:8px;border-radius:50%;background:var(--asp-warn)}
.asp-badge{display:inline-block;padding:2px 9px;border-radius:6px;font-size:11px;font-weight:800;white-space:nowrap}
.asp-badge.b-ok{background:var(--asp-okl);color:var(--asp-ok)}
.asp-badge.b-grey{background:var(--asp-grey);color:var(--asp-greyt)}

/* ---- status panel --------------------------------------------------------- */
.asp-status{margin-bottom:14px;overflow:hidden}
.asp-status .asp-stop{display:flex;justify-content:space-between;align-items:center;padding:10px 16px;
  cursor:pointer;gap:10px;flex-wrap:wrap;width:100%;background:none;border:0;font:inherit;text-align:left;color:inherit}
.asp-status .asp-stop b{font-size:13.5px}
.asp-status .asp-sdots{display:flex;gap:14px;align-items:center;flex-wrap:wrap;color:var(--asp-mut);font-size:12.5px}
.asp-dot{width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:5px;vertical-align:middle}
.asp-dot.ok{background:var(--asp-ok)}
.asp-dot.warn{background:var(--asp-warn)}
.asp-dot.bad{background:var(--asp-bad)}
.asp-dot.grey{background:#b9c6cf}
.asp-sbody{border-top:1.5px solid var(--asp-line);padding:14px 16px;display:grid;grid-template-columns:1fr 1fr;gap:14px}
.asp-sbody .asp-col h4{margin:0 0 8px;font-size:13px}
.asp-kv{display:grid;grid-template-columns:150px 1fr;gap:3px 10px;font-size:12.8px}
.asp-kv .k{color:var(--asp-mut)}
.asp-comps{grid-column:1/-1;display:flex;gap:10px;flex-wrap:wrap;border-top:1px dashed var(--asp-line);padding-top:12px;align-items:center}
.asp-comp{background:var(--asp-grey);border-radius:8px;padding:6px 10px;font-size:12px}
.asp-comp b{font-weight:700}

/* ---- A5: ONE toolbar row -------------------------------------------------- */
/* No bottom padding: the underline tabs stretch to the bottom edge so their own
   underline meets the toolbar's border, which is what makes them read as tabs. */
.asp-tb{display:flex;gap:14px;align-items:center;flex-wrap:wrap;padding:13px 16px 0;
  border-bottom:1.5px solid var(--asp-line)}

/* ---- A2: the view switcher is a PILL BAR ---------------------------------
 * Restored in this pass. S3 removed .asp-nav with the one-item switcher ("the old
 * .asp-chip / .asp-chips / .asp-nav rules are gone with it", above) and S4 brought
 * the markup back without the CSS, so all four buttons fell through to the global
 * blue pill and the active one was indistinguishable from the other three.
 * Values are the prototype's .nav block, unchanged. */
.asp-nav{display:flex;gap:4px;background:#e9f1f6;border-radius:12px;padding:4px;margin:0 0 14px;
  width:max-content;max-width:100%;overflow:auto}
/* FONT-SIZE IS SET EXPLICITLY HERE, AND THE PROTOTYPE'S font:inherit IS NOT CARRIED ACROSS
   LITERALLY. The prototype's body is 14px, so `font:inherit` there means 14px; RMS's page font
   is 16px, so copying the declaration verbatim gives a control two points larger than every
   other control in this module — the row filters are 13px and .btn.small is 12.5px, so these
   two shouted. `font:inherit` still does the family and the line-height; only the size is
   pinned. 14px, which is what the prototype actually renders. */
.asp-nav button{border:0;background:transparent;border-radius:9px;padding:7px 14px;font:inherit;
  font-size:14px;font-weight:700;color:var(--asp-greyt);cursor:pointer;white-space:nowrap}
/* Only ONE of the four is ever raised — that is what makes it a switcher. */
.asp-nav button.on{background:#fff;color:var(--asp-pd);box-shadow:0 1px 4px rgba(3,101,142,.12)}
.asp-nav button .n{font-size:11px;background:var(--asp-pl2);color:var(--asp-pd);border-radius:6px;
  padding:1px 6px;margin-left:5px}

/* ---- the account switcher wears the ROW FILTERS' shape -------------------
 * ABDUL'S CALL, 4 SEPTEMBER, TAKEN OVER THE PROTOTYPE. The prototype makes this a joined
 * segmented control (.aseg) precisely so it does not look like the row filters a few pixels
 * away, and S3's A2 correction was about exactly that separation. He has seen both on a real
 * screen and wants one shape, so this is now underline tabs, matched to .asp-tabs declaration
 * for declaration. The class name is kept because the module and the tests reference it; only
 * the shape changed.
 *
 * The two controls now sit at opposite ends of one toolbar row wearing the same shape. If they
 * start reading as a single strip of tabs, a divider between them is the fix — NOT quietly
 * putting the box back. */
.asp-aseg{display:flex;gap:2px;background:none;border:0;border-radius:0;overflow:auto;flex:none}
/* 13px, NOT the 14px used on the view switcher, and that is deliberate. This control is locked
   to the ROW FILTERS' shape, and the filters are 13px — matching the view switcher instead
   would break the thing the lock exists to hold. It was never part of the 16px fault: it has
   been explicitly sized since the shape changed. */
.asp-aseg button{border:0;background:none;padding:8px 12px;font:inherit;font-weight:700;font-size:13px;
  color:var(--asp-greyt);cursor:pointer;border-bottom:2.5px solid transparent;white-space:nowrap}
.asp-aseg button.on{background:none;color:var(--asp-pd);border-bottom-color:var(--asp-p)}
.asp-aseg .sm{font-size:9.5px;font-weight:800;color:var(--asp-warn);margin-left:5px;letter-spacing:.3px}

/* ---- A2: the row filters are UNDERLINE TABS, counts PLAIN ----------------- */
.asp-tabs{display:flex;gap:2px;overflow:auto;align-self:stretch}
.asp-tabs button{border:0;background:none;padding:8px 12px;font:inherit;font-weight:700;
  color:var(--asp-greyt);cursor:pointer;border-bottom:2.5px solid transparent;white-space:nowrap;font-size:13px}
.asp-tabs button.on{color:var(--asp-pd);border-bottom-color:var(--asp-p)}
.asp-tabs button:disabled{opacity:.55;cursor:not-allowed}
.asp-tabs button .n{color:var(--asp-mut);font-weight:600;margin-left:5px}
.asp-tabs button.on .n{color:var(--asp-pd)}

/* min-width:0 is REQUIRED — see trap 1 in the header. */
.asp-page .asp-search{border:1.5px solid var(--asp-line);border-radius:var(--asp-rs);padding:7px 11px;
  font:inherit;font-size:13px;min-width:0;width:280px;max-width:100%}
.asp-grow{flex:1}

/* ---- A5: the footer carries the counts, both freshness facts and the pager - */
.asp-foot{display:flex;gap:12px;align-items:center;justify-content:space-between;padding:9px 16px;
  font-size:12.5px;color:var(--asp-mut);border-top:1.5px solid var(--asp-line);flex-wrap:wrap}
.asp-foot .asp-pg{display:flex;gap:8px;align-items:center}
.asp-stale{display:inline-flex;align-items:center;gap:6px;background:var(--asp-warnl);color:var(--asp-warn);
  border-radius:6px;padding:2px 8px;font-weight:700}

/* ---- the table (desktop) -------------------------------------------------- */
.asp-table{width:100%;border-collapse:collapse}
/* THE RULE UNDER THE HEADERS NEEDS AIR ON BOTH SIDES. Header text is not welded to
   its own underline, and the first row does not start on top of it — the rule is a
   divider, not a box edge. 16 above the text, 14 between text and rule, 12 before
   the first row. */
.asp-table th{font-size:11.5px;text-transform:uppercase;letter-spacing:.4px;color:var(--asp-mut);
  text-align:left;padding:16px 12px 14px;border-bottom:1px solid var(--asp-line);font-weight:700;white-space:nowrap}
.asp-table tbody tr:first-child td{padding-top:12px}
.asp-table td{padding:8px 12px;border-bottom:1px solid #edf2f6;vertical-align:top;font-size:13px}
.asp-table tr:last-child td{border-bottom:0}
/* A problem row is NOT an error — it is a listing this module cannot act on.
   Warning tone, never red: red is for something that failed. */
.asp-table tr.asp-problem td{background:#fffaf1;color:var(--asp-greyt)}
.asp-table th.asp-num,.asp-table td.asp-num{text-align:right}
.asp-table th.asp-help{cursor:help}
/* P3-B — A SORTABLE HEADER. The <th> is untouched — same class, same title, same rules above.
   The clickable part is a SPAN inside it, so these rules apply to an element nothing else
   styles: a pointer, no accidental text selection on a double click, and the arrow — faint on
   every sortable column so the affordance is visible, full strength on the one that is the
   current sort. It keeps the header's own size and colour. No property here is declared by
   .asp-table th or th.asp-help, so nothing is overridden — a test reads the rules and checks. */
.asp-table th .asp-sort{cursor:pointer;user-select:none}
.asp-table th .asp-sort .asp-sarr{margin-left:5px;opacity:.35}
.asp-table th .asp-sort.on .asp-sarr{opacity:1}
/* THE SKU WRAPS, AND THAT IS NOT COSMETIC.
   nowrap came from the prototype, whose sample SKUs were fifteen characters. Real ones are
   thirty-plus — "100packA4punchpockets-…", "5 roll yellow base food labels 50x75mm" — and once
   the column tidy-up narrowed the SKU column, a nowrap span simply overflowed its cell and
   drew straight through the ASIN beside it. Two different listings' identifiers overlapping is
   worse than either being cut off.
   So it gets what Title already has: clamp to two lines, the whole SKU in the title attribute
   for hovering, and a max-height for browsers without -webkit-line-clamp. overflow-wrap:anywhere
   is the part that does the work — a thirty-character SKU with no spaces in it has nowhere to
   break otherwise, and word-break alone leaves it overflowing. The monospace and the blue stay:
   they are how a SKU is recognised as a SKU everywhere else in the app. */
.asp-sku{font-family:Consolas,Menlo,monospace;color:#2c5cc5;font-weight:600;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  max-height:2.9em;line-height:1.45;overflow-wrap:anywhere;word-break:break-word}
.asp-asin{font-family:Consolas,Menlo,monospace;color:var(--asp-mut);font-size:12px}
/* THE TITLE COLUMN. Real Amazon titles run 150-200 characters — the prototype's fixture
   titles were 40-60, so this only showed up against live data: every row became five or six
   lines tall and four listings filled a screen that should hold a dozen.
   Clamped to TWO lines, not one: several of these SKUs differ only in the middle of the title
   ("6 Brown + 6 Clear + 6 Fragile" vs "6 Fragile + 6 Brown + 6 Clear"), and one line cuts
   before the part that tells them apart. The full title is in the cell's title attribute, so
   hovering still gives all of it. -webkit-line-clamp is the only cross-browser way to clamp by
   LINE; the max-height fallback beside it bounds the cell even where that is unsupported. */
/* WIDTH, NOT JUST MAX-WIDTH. Measured at 1440px: with max-width alone the table's auto
   layout gave Title 266px; asking for 380 moves it to 302px and takes the slack from the
   "Last full-price sale" column, which had 190px for content that needs 155px. It SATURATES
   at 302 — 380, 420 and 500 all produce 302, because the other columns will not compress past
   their content. 302px is about 40 characters a line, so two lines hold ~80: enough to reach
   the part where these titles actually differ ("6 Brown + 6 Clear + 6 Fragile" against
   "6 Fragile + 6 Brown + 6 Clear"), which is why the clamp is two lines and not one. */
.asp-ttl{width:380px;max-width:380px}
.asp-ttl .asp-clamp{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;max-height:2.9em;line-height:1.45}
.asp-mut{color:var(--asp-mut)}
.asp-small{font-size:12px}
/* THE CHIP NEVER BREAKS ACROSS LINES. It was wrapping "price" above "match", inside its own
   border, on all 3,394 rows — a two-line box where a one-line label was meant. The prototype
   omits this too; the sample's column happened to be wide enough to hide it.
   nowrap ALONE is not the fix: without room the cell just gets wider and takes it from Title.
   The column is rebalanced below, out of the SKU column, which was visibly over-wide. */
.asp-basis{font-size:10.5px;font-weight:700;color:var(--asp-mut);border:1px solid var(--asp-line);
  border-radius:5px;padding:0 5px;margin-left:5px;cursor:help;white-space:nowrap}

/* SKU is a short code in a monospace font — it does not need 174px, and that is where the
   pixels for the chip come from. Title keeps its own width:380px declaration and must not
   lose room; measured before and after at 1440 and 1180. */
.asp-table th.asp-csku,.asp-table td.asp-csku{max-width:156px}
/* S10 — the SAME trap the Vendor Listing Builder's table hit (FIX-24): an auto-layout table's
   column width is the MAX of header AND every body cell, so capping only the body cell left the
   header's own text as the new floor and the row still grew past the action buttons. Both get
   the cap here, additive — this rule does not touch .asp-csku or anything else above it. */
.asp-table th.asp-ctpl,.asp-table td.asp-ctpl{max-width:110px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* S13 — MEASURED, NOT GUESSED: a real headless-browser pass (localhost:4100, logged-in pane)
   showed the Template cap alone was not enough. With a realistic row (long SKU/title, a
   "price match" chip, and the longest real sale-status label, "Waiting for a full-price sale")
   the table's scrollWidth was 1287px against the card's 1238px at 1920 — 49px of overflow —
   and the uncapped floor was NOT Template (110px, already capped) but Sale status, whose badge
   had no cap at all and rendered 190.77px wide. Capping it to 140px (header AND cell, the same
   FIX-24/S10 pattern) brought scrollWidth to exactly 1238px — zero overflow — confirmed again
   at 1440 (identical, the card's own max-width is the binding constraint from 1440 up). Below
   the rk-deskonly breakpoint (measured at 1180) the table is display:none and the card list
   takes over, so this column cap only matters at desktop widths, same as .asp-ctpl above it. */
.asp-table th.asp-cstat,.asp-table td.asp-cstat{max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.asp-table td.asp-cstat .asp-badge{max-width:100%;overflow:hidden;text-overflow:ellipsis;display:inline-block;vertical-align:bottom}
/* S13 — the catch-up bar: same row shape as .asp-applybar, which already sits in this card. */
.asp-catchup{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:10px 16px;
  border-bottom:1px solid var(--asp-line);font-size:13px}
/* THE CELL IS DELIBERATELY NOT nowrap, AND THAT IS A JUDGEMENT WITH NUMBERS BEHIND IT.
   The reported fault was the chip breaking mid-label — "price" above "match" inside its own
   border — and nowrap on the chip fixes exactly that. Forcing the whole CELL onto one line as
   well was tried and measured: the column takes 212px, and at 1440 the table only has 1238 to
   share, so Title collapses from 326px to 224px. The brief for this column says Title must not
   drop below the 302px it had. Both cannot be true at once at this width.
   So the chip never breaks, and the date sits above it when the column is narrow — which is
   legible and is what it did before. Written up as the one thing in this pass that could not
   be fully satisfied. */

/* ---- banners, empty and loading ------------------------------------------ */
.asp-banner{margin:16px 16px 0;border-radius:12px;padding:12px 14px;font-size:13px;border:1.5px solid}
.asp-banner.bad{background:var(--asp-badl);border-color:#f1c7c6;color:#8a2b2a}
.asp-banner.warn{background:var(--asp-warnl);border-color:#f0d9a8;color:#7a4f0e}
.asp-banner.info{background:var(--asp-pl);border-color:var(--asp-pl2);color:var(--asp-pd)}
.asp-banner b{display:block;margin-bottom:2px}
.asp-banner .asp-acts{margin-top:8px;display:flex;gap:8px;flex-wrap:wrap}
.asp-tech{margin-top:8px;font-size:12px}
.asp-tech summary{cursor:pointer;color:var(--asp-mut)}
.asp-tech pre{margin:6px 0 0;background:#fff;border:1px solid var(--asp-line);border-radius:8px;
  padding:8px 10px;font-size:11.5px;white-space:pre-wrap;color:#3d4c58}
/* P2-I — Amazon's raw payload. Same skin as the technical-detail block, but it is a panel in
   its own right rather than a <details>, and it is CAPPED: a listing with fifty attributes
   would otherwise push the rest of the history off the screen. It scrolls in its own box —
   the page itself must never scroll sideways. */
/* LAYOUT 2 — the payload is BOUNDED and scrolls inside its own box, in both directions.
   max-width:100% is what stops it setting the width of everything above it (with the
   min-width:0 on its grid item, which is the half that lets the 100% mean anything); the
   scrollbars are the visible sign that there is more, sitting inside the panel where they can
   be seen rather than below the fold. max-height keeps a long payload from pushing the rest of
   the page down. */
.asp-tech-pre{margin:6px 0 0;background:#fff;border:1px solid var(--asp-line);border-radius:8px;
  padding:8px 10px;font-size:11px;white-space:pre;color:#3d4c58;
  max-height:280px;max-width:100%;overflow:auto;scrollbar-width:thin;overscroll-behavior:contain}
html[data-theme="dark"] .asp-tech-pre{background:#0b1620;color:#c6d5e1;border-color:var(--asp-line)}
.asp-empty{padding:36px 20px;text-align:center;color:var(--asp-mut)}
.asp-empty b{display:block;color:var(--asp-ink);margin-bottom:4px;font-size:14px}
.asp-skel{padding:20px 16px 16px}
.asp-skel div{height:14px;border-radius:6px;background:linear-gradient(90deg,#eef2f5,#f7f9fb,#eef2f5);
  background-size:200% 100%;animation:asp-sh 1.2s infinite;margin:10px 0}
@keyframes asp-sh{0%{background-position:200% 0}100%{background-position:-200% 0}}
@media (prefers-reduced-motion:reduce){.asp-skel div{animation:none}}

/* ---- the mobile twin (dual-render, see trap 2) ---------------------------- */
.asp-cards{padding:10px 12px}
.asp-mcard{border:1.5px solid var(--asp-line);border-radius:12px;padding:12px;margin:0 0 10px;background:#fff}
.asp-mcard.asp-problem{background:#fffaf1}
.asp-mcard .asp-mtop{display:flex;justify-content:space-between;gap:10px;align-items:flex-start;flex-wrap:wrap}
.asp-mcard .asp-mtitle{font-size:13px;margin:4px 0 8px}
.asp-mrow{display:grid;grid-template-columns:130px 1fr;gap:2px 10px;font-size:12.5px}
.asp-mrow .k{color:var(--asp-mut)}

@media (max-width:1180px){
  .asp-sbody{grid-template-columns:1fr}
  .asp-kv{grid-template-columns:120px 1fr}
  .asp-page .asp-search{width:100%}
  .asp-ttl{max-width:none}
  /* The segmented control goes full width and splits evenly — a two-item control
     hugging the left edge of a phone reads as a stray pair of buttons. */
  /* No width:100% / flex:1 here any more — see the note on .asp-aseg. It scrolls like the
     row filters instead, which is what "the same shape" has to mean at every width. */
  .asp-foot{justify-content:flex-start}
}

/* ---- dark mode, in this file (see trap 3) -------------------------------- */
html[data-theme="dark"] .asp-page{
  --asp-card:#101c26; --asp-line:#24384a; --asp-ink:#e6eef4; --asp-mut:#93a8b8;
  --asp-pl:#0d2836; --asp-pl2:#17475e; --asp-grey:#182734; --asp-greyt:#a9bccb;
  --asp-okl:#10281c; --asp-warnl:#2c2313; --asp-badl:#2c1615;
}
html[data-theme="dark"] .asp-page .asp-btn{background:#152430;color:var(--asp-ink);border-color:var(--asp-line)}
html[data-theme="dark"] .asp-page .asp-btn:hover{background:#1b2f3e;border-color:#31506a}
html[data-theme="dark"] .asp-page .asp-btn.primary{color:#fff}
html[data-theme="dark"] .asp-page .asp-search{background:#152430;color:var(--asp-ink);border-color:var(--asp-line)}
/* Dark mode follows the same shape — a background here would put the box back after dark. */
html[data-theme="dark"] .asp-aseg{background:none;border:0}
html[data-theme="dark"] .asp-aseg button{background:none;color:var(--asp-greyt)}
html[data-theme="dark"] .asp-aseg button.on{background:none;color:#8fd2ee;border-bottom-color:var(--asp-p)}
html[data-theme="dark"] .asp-table td{border-bottom-color:#1d2f3d}
html[data-theme="dark"] .asp-table th{border-bottom-color:var(--asp-line)}
html[data-theme="dark"] .asp-table tr.asp-problem td{background:#241d10;color:#cbb98f}
html[data-theme="dark"] .asp-mcard{background:#101c26;border-color:var(--asp-line)}
html[data-theme="dark"] .asp-page .asp-thumb{background:#152430}
html[data-theme="dark"] .asp-mcard.asp-problem{background:#241d10}
html[data-theme="dark"] .asp-sku{color:#89b4ff}
html[data-theme="dark"] .asp-tech pre{background:#0b1620;color:#c6d5e1;border-color:var(--asp-line)}
html[data-theme="dark"] .asp-banner.bad{background:#2c1615;color:#f0b3b1;border-color:#5b2b29}
html[data-theme="dark"] .asp-banner.warn{background:#2c2313;color:#e8c88a;border-color:#5b4a22}
html[data-theme="dark"] .asp-banner.info{background:#0d2836;color:#8fd2ee;border-color:#17475e}
html[data-theme="dark"] .asp-skel div{background:linear-gradient(90deg,#152430,#1b2f3e,#152430);background-size:200% 100%}

/* =============================================================================
   S4 — SCHEDULES, THE EDITOR, ACTIVITY AND SETTINGS

   Same tokens, same prefix. Values copied from the prototype's own rules rather
   than reinterpreted, because three controls that must stay visually distinct
   (pill bar / segmented control / underline tabs) only stay distinct if their
   rules do.

   THE MODAL Z-INDEX, STATED HERE BECAUSE IT HAS BITTEN TWICE ELSEWHERE:
   .ui-modal-ov (the shared kit confirm) is 4100 and module modals in this app
   are 6000, so a kit confirm raised from inside an open module modal renders
   BEHIND it — the screen darkens and nothing responds. This module does not use
   the kit's confirm at all: it has its own confirm overlay at 6100, ABOVE its
   own editor at 6000, and the two are never nested anyway (confirms are raised
   from the Schedules table, never from inside the editor). If that ever has to
   change, close the editor first rather than adding a third copy of the
   workaround the other two modules carry.
   ============================================================================= */

/* ---- toolbar variant without stretched tabs ------------------------------- */
.asp-tb.plain{padding:12px 16px}

/* ---- selection + bulk bar ------------------------------------------------- */
.asp-table td.asp-tick,.asp-table th.asp-tick{width:34px;padding-right:0}
.asp-page .asp-table input[type="checkbox"]{min-width:0;width:16px;height:16px;cursor:pointer}
.asp-table tr.asp-sel td{background:#f4fbfe}
.asp-bulk{display:flex;gap:10px;align-items:center;padding:11px 16px;background:var(--asp-pl);
  border-bottom:1.5px solid var(--asp-pl2);font-weight:600;color:var(--asp-pd);flex-wrap:wrap}

/* ---- badges (the sale-status vocabulary) --------------------------------- */
.asp-badge.b-live{background:var(--asp-okl);color:var(--asp-ok)}
.asp-badge.b-sched{background:var(--asp-pl);color:var(--asp-pd)}
.asp-badge.b-draft{background:var(--asp-grey);color:var(--asp-greyt)}
.asp-badge.b-paused{background:#eceff3;color:#4d5d6b}
.asp-badge.b-att{background:var(--asp-warnl);color:var(--asp-warn)}
.asp-badge.b-ended{background:var(--asp-grey);color:var(--asp-greyt)}
.asp-badge.b-wait{background:#eef3ff;color:#3557b7}
.asp-badge.b-fail{background:var(--asp-badl);color:var(--asp-bad)}
.asp-badge.b-unk{background:#f1efe6;color:#7a6a2f}
/* P2-F. b-prep is its own colour and not b-sched, because "Preparing · lowering minimum" is
   the one state where RMS is writing to the listing and the sale is NOT on Amazon yet. */
.asp-badge.b-prep{background:#eaf1ff;color:#3557b7}
.asp-badge.b-badgeok{background:var(--asp-pl);color:var(--asp-pd)}

/* ---- row actions and expanded rows --------------------------------------- */
.asp-rowacts{display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end}
.asp-table tr.asp-exp td{background:#f8fbfd;border-top:1px dashed var(--asp-line);padding:12px 16px 14px}
.asp-page .asp-btn.ghostred{color:var(--asp-bad);border-color:#efc9c8}
.asp-page .asp-btn.ghostred:hover{background:var(--asp-badl)}
.asp-page .asp-btn.link{border-color:transparent;background:transparent;color:var(--asp-p);padding:4px 6px}

/* ---- the module's own modals --------------------------------------------- */
.asp-ovl{position:fixed;inset:0;background:rgba(18,28,44,.45);display:none;align-items:flex-start;
  justify-content:center;padding:26px 14px;overflow:auto;z-index:6000}
.asp-ovl.open{display:flex}
.asp-ovl.asp-confirm{z-index:6100}
.asp-panel{width:min(820px,100%);background:var(--asp-card);border-radius:18px;
  box-shadow:0 18px 50px rgba(10,25,50,.25);overflow:hidden;color:var(--asp-ink)}
.asp-panel.asp-cbox{width:min(560px,100%)}
.asp-ptop{display:flex;justify-content:space-between;align-items:flex-start;gap:10px;padding:18px 20px 0}
.asp-ptitle{font-size:17px;font-weight:800}
.asp-x{cursor:pointer;color:var(--asp-mut);font-size:18px;padding:2px 6px;background:none;border:0}
.asp-pbody{padding:14px 20px 18px}
.asp-pbody p{margin:6px 0}
.asp-pfoot{display:flex;justify-content:space-between;align-items:center;gap:10px;padding:12px 20px;
  border-top:1.5px solid var(--asp-line);background:#fbfdfe;flex-wrap:wrap}
.asp-fgrid{display:grid;grid-template-columns:1fr 1fr;gap:12px 16px;margin-top:12px}
.asp-fld label{display:block;font-size:12px;font-weight:700;color:var(--asp-greyt);margin-bottom:4px}
/* min-width:0 — style.css line 1 puts 170px on every input, unscoped. */
.asp-page .asp-fld input,.asp-page .asp-fld select{border:1.5px solid var(--asp-line);
  border-radius:var(--asp-rs);padding:8px 10px;font:inherit;font-size:13px;width:100%;min-width:0}
/* THE HINT IS A HINT WHEREVER IT IS. This was scoped to `.asp-fld .asp-hint`, so the two
   hints that live inside a field were small and grey and the one under "Next sale starts
   when" — which sits straight after its select, with no field wrapper — inherited the body
   size and colour and read as a second paragraph of the form rather than a note under it. */
.asp-hint{font-size:11.5px;color:var(--asp-mut);margin-top:3px}
.asp-seg{display:inline-flex;border:1.5px solid var(--asp-line);border-radius:var(--asp-rs);overflow:hidden}
.asp-seg button{border:0;background:#fff;padding:7px 12px;font:inherit;font-size:13px;font-weight:700;
  color:var(--asp-greyt);cursor:pointer}
.asp-seg button.on{background:var(--asp-pl);color:var(--asp-pd)}
.asp-lsel{border:1.5px solid var(--asp-line);border-radius:12px;overflow:hidden;margin-top:10px}
.asp-lsel .asp-lr{display:grid;grid-template-columns:1fr 110px 130px;gap:10px;padding:8px 12px;
  border-top:1px solid #edf2f6;font-size:12.8px;align-items:center}
.asp-lsel .asp-lr:first-child{border-top:0;background:#f8fbfd;font-weight:700;color:var(--asp-greyt);
  font-size:11.5px;text-transform:uppercase;letter-spacing:.3px}
.asp-prev{margin-top:14px;border:1.5px solid var(--asp-pl2);background:#f7fcfe;border-radius:12px;padding:12px 14px}
.asp-prev h4{margin:0 0 6px;font-size:13px;color:var(--asp-pd)}
.asp-win{display:grid;grid-template-columns:110px 1fr;gap:4px 10px;font-size:12.8px}
.asp-win .g{color:var(--asp-mut)}
.asp-warns{margin-top:10px;display:flex;flex-direction:column;gap:6px}
.asp-warnline{background:var(--asp-warnl);color:#7a4f0e;border-radius:8px;padding:7px 10px;font-size:12.5px}
.asp-badline{background:var(--asp-badl);color:#8a2b2a;border-radius:8px;padding:7px 10px;font-size:12.5px}
.asp-fact{display:grid;grid-template-columns:130px 1fr;gap:3px 10px;font-size:13px;margin:10px 0;
  background:#f8fbfd;border-radius:10px;padding:10px 12px}
.asp-fact .k{color:var(--asp-mut)}

/* ---- settings ------------------------------------------------------------- */
.asp-sform{padding:16px}
.asp-sform h4{margin:0 0 4px;font-size:14px}
.asp-sform .asp-sub{margin-bottom:12px}
/* THE MIDDLE COLUMN HOLDS THE WIDEST CONTROL, WHICH IS A SELECT, NOT A NUMBER. At 160px the
   "next sale starts when" options truncated mid-word — "Gap passed AND a fu…". The track is
   sized for the select; the number inputs are capped separately below so they stay compact
   rather than stretching to match it. */
.asp-srow{display:grid;grid-template-columns:260px 280px 1fr;gap:10px;align-items:center;
  padding:9px 0;border-top:1px solid #edf2f6}
.asp-srow:first-of-type{border-top:0}
.asp-srow .l{font-weight:600;font-size:13px}
.asp-srow .h{font-size:12px;color:var(--asp-mut)}
.asp-page .asp-srow input,.asp-page .asp-srow select{border:1.5px solid var(--asp-line);
  border-radius:8px;padding:6px 9px;font:inherit;font-size:13px;width:100%;min-width:0}
/* A number field does not need the select's width. */
.asp-page .asp-srow input{max-width:160px}
.asp-ovr{margin-top:14px;border-top:1.5px dashed var(--asp-line);padding-top:12px}

/* ---- the two links out to Amazon ---------------------------------------- *
   ANCHORS, NOT BUTTONS, AND THAT CUTS BOTH WAYS. The control reset at the top of this file
   is scoped to `.asp-page button`, so an <a> gets none of it; and style.css carries no
   unscoped `a` rule, so what these would otherwise inherit is the plain browser default —
   underlined link blue, which shouted next to a real action. Everything below is therefore
   stated outright rather than corrected. Quiet on purpose: they sit beside "Put on sale"
   and must not compete with it, so they hold the muted text colour until hovered.
   A FIXED 26px BOX so a row with links is exactly as tall as a row without them. */
.asp-page .asp-ext{display:inline-flex;align-items:center;justify-content:center;
  width:26px;height:26px;flex:0 0 auto;border:1.5px solid transparent;border-radius:8px;
  color:var(--asp-mut);text-decoration:none;vertical-align:middle;margin:0 0 0 2px}
.asp-page .asp-ext:hover{color:var(--asp-pd);background:var(--asp-pl);border-color:var(--asp-pl2)}
.asp-page .asp-ext:focus-visible{outline:2px solid var(--asp-p);outline-offset:1px}
/* The picture, the SKU and its links travel together — in the schedules cell, and inside
   the cards, whose heads are space-between and would otherwise spread three children. */
.asp-page .asp-idcell{display:inline-flex;align-items:center;gap:4px;flex-wrap:nowrap;min-width:0}

/* ---- the listing thumbnail ---------------------------------------------- *
   NO width/height HERE, ON PURPOSE. The <img> carries them as ATTRIBUTES — 40 in the
   listings table and the cards, 32 in the schedules cell — so one CSS rule serves both
   sizes, and the attributes also reserve the box BEFORE the picture has loaded. That is
   what stops the table reflowing line by line as a backfill lands under it: an image still
   in flight, one that 404s, and one that is simply absent all occupy the same square.
   object-fit:cover because Amazon returns squares and near-squares and a letterboxed
   thumbnail at 40px is unreadable. */
.asp-page .asp-thumb{display:block;flex:0 0 auto;object-fit:cover;border-radius:6px;
  border:1px solid var(--asp-line);background:#f8fbfd}
/* The column is the picture plus the cell padding, and no wider — every pixel here is one
   the Title column does not get. Header is blank; there is nothing to call it. */
.asp-table th.asp-cimg,.asp-table td.asp-cimg{width:56px;min-width:56px;max-width:56px;
  padding-left:8px;padding-right:8px}


/* ══════════════════════════════════════════════════════════════════════════════════════
 * P2-E — THE PLAN EDITOR AND TEMPLATES
 * ══════════════════════════════════════════════════════════════════════════════════════
 * Every control group below has a row in the CSS-exists regression test. The view switcher
 * once matched ZERO rules and every test still passed, which is why that test exists and
 * why nothing new goes in here without one.
 *
 * Scoped to .asp-page throughout, because the control reset at the top of this file is and
 * because style.css puts min-width:170px on every input unscoped — anything in a narrow
 * cell needs min-width:0 or it computes to 170px and lands on its neighbour.
 */

/* ---- the plan: step rows ---- */
.asp-steps{border:1.5px solid var(--asp-line);border-radius:12px;overflow:hidden}
.asp-step{display:grid;grid-template-columns:28px 120px 1fr auto;gap:10px;align-items:center;
  padding:8px 12px;border-top:1px solid #edf2f6;background:#fff}
.asp-step:first-child{border-top:0}
.asp-step.sale{background:#f7fcfe}
.asp-step .n{font-size:11px;font-weight:800;color:var(--asp-mut)}
.asp-page .asp-step select,.asp-page .asp-step input{border:1.5px solid var(--asp-line);
  border-radius:8px;padding:6px 9px;font:inherit;font-size:13px;min-width:0}
.asp-step .mid{display:flex;gap:8px;align-items:center;flex-wrap:wrap;font-size:13px}
.asp-page .asp-step .mid input{width:70px}
.asp-page .asp-step .mid input.price{width:96px}
/* P3-C — the date box of a sale step measured to a date. The same shape as .price above: one
   class, one width, for a box the 70px default cannot hold (a date input needs ~140px). */
.asp-step .ops{display:flex;gap:4px}
.asp-page .asp-step .ops button{border:1px solid var(--asp-line);background:#fff;
  border-radius:7px;width:26px;height:26px;font:inherit;font-size:12px;cursor:pointer;
  color:var(--asp-greyt)}
.asp-page .asp-step .ops button:hover{color:var(--asp-pd);border-color:#b9cdd9}
.asp-page .asp-step .ops button:disabled{opacity:.3;cursor:default}
/* P3-C — ↻ marks the step the cycle returns to. The same 26px box as ↑ ↓ ✕ beside it; `on` is
   the hover colouring held, plus the module's light blue, so the settled step reads at a
   glance. A new state on an existing control, not a new control. */
.asp-page .asp-step .ops button.on{color:var(--asp-pd);border-color:var(--asp-p);background:var(--asp-pl)}
.asp-addstep{display:flex;gap:8px;padding:10px 12px;background:#f8fbfd;
  border-top:1px solid #edf2f6;flex-wrap:wrap;align-items:center}
.asp-presets{display:flex;gap:6px;flex-wrap:wrap}
.asp-page .asp-presets button{border:1.5px solid var(--asp-line);background:#fff;
  border-radius:999px;padding:4px 11px;font:inherit;font-size:12px;font-weight:700;
  color:var(--asp-greyt);cursor:pointer}
.asp-page .asp-presets button:hover{border-color:var(--asp-p);color:var(--asp-pd)}

/* P2-H — the unit toggle inside a step row. It sits between the number and the price, so it
   must not grow: a select that stretches pushes the price box onto a second line at 375px. */
.asp-page .asp-step .asp-unit{min-width:0;width:auto;padding:2px 4px;font-size:12.5px}

/* ---- days off ---- */
.asp-dow{display:flex;gap:6px;flex-wrap:wrap}
.asp-page .asp-dow button{border:1.5px solid var(--asp-line);background:#fff;border-radius:8px;
  padding:6px 0;width:52px;font:inherit;font-size:12.5px;font-weight:700;
  color:var(--asp-greyt);cursor:pointer}
.asp-page .asp-dow button.off{background:#f1efe6;border-color:#e2dcc4;color:#7a6a2f;
  text-decoration:line-through}

/* ---- the two-column sections and the two panels ---- */
/* ---- LAYOUT 1+2: THE HISTORY PANEL'S ONE ROOT CAUSE -------------------------
   A grid track's default minimum is `auto`, which is its content's MIN-CONTENT width. The
   "What Amazon returned" block inside this grid is white-space:pre, so its min-content is its
   longest JSON line — several thousand pixels. That track therefore refused to shrink, this
   grid grew to fit it, the expanded <td> grew with it, the table grew past its container, and
   the global `table{overflow:hidden}` clipped the result. THAT is why the minimum sentence
   ended "...It goes back to £9.09 whe" and why the JSON looked truncated rather than
   scrollable: one cause, three symptoms.
   minmax(0,1fr) lets each track shrink; min-width:0 on the ITEMS is the other half, because a
   grid item carries the same auto minimum as its track (the same pair P2-H needed for the
   editor's listing table). No !important anywhere: this is the cascade working, not fighting. */
.asp-twocol{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px 16px}
.asp-twocol>*{min-width:0}
.asp-panelbox{border:1.5px solid var(--asp-line);border-radius:12px;padding:10px 12px;background:#fff}
.asp-panelbox h6{margin:0 0 6px;font-size:12px;font-weight:800;color:var(--asp-ink)}
.asp-panelbox .row{display:flex;gap:8px;align-items:center;flex-wrap:wrap;font-size:13px;
  margin-bottom:6px}
.asp-page .asp-panelbox input,.asp-page .asp-panelbox select{border:1.5px solid var(--asp-line);
  border-radius:8px;padding:6px 9px;font:inherit;font-size:13px;min-width:0}
.asp-sect{margin-top:14px}
.asp-sect h5{margin:0 0 6px;font-size:13px;color:var(--asp-pd)}
.asp-why{font-size:12.5px;color:var(--asp-mut);margin-bottom:8px}
.asp-page .asp-twocol select{border:1.5px solid var(--asp-line);border-radius:8px;
  padding:6px 9px;font:inherit;font-size:13px;min-width:0;width:100%}
.asp-page .asp-twocol input[type="number"],.asp-page .asp-twocol input[type="date"]{
  border:1.5px solid var(--asp-line);border-radius:8px;padding:6px 9px;font:inherit;
  font-size:13px;min-width:0}
/* P3-C — "repeating from ▾" in the Repeat row: the label and its dropdown are ONE unit that
   wraps together, so the words never strand at the end of a line with the select below. */
.asp-fromgrp{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}

/* ---- the calendar ---- */
.asp-cal{margin-top:8px}
.asp-legend{display:flex;gap:12px;font-size:11.5px;color:var(--asp-mut);margin-bottom:6px;
  flex-wrap:wrap}
.asp-legend i{display:inline-block;width:10px;height:10px;border-radius:3px;margin-right:4px;
  vertical-align:middle}
.asp-legend i.k-sale{background:#e6f4fa;border:1px solid #cfe9f4}
.asp-legend i.k-full{background:#f4f6f8}
.asp-legend i.k-off{background:#f1efe6}
.asp-legend i.k-done{background:#fff;border:1px solid var(--asp-line)}
/* P3-J — THE FIFTH KEY, for the day a sale resumes after a buffer. Same 10px swatch as the
   four above (the .asp-legend i rule does all of that); only the fill differs, which is what
   every one of them does. The gradient is the cell's, below, so the key and the cell cannot
   drift apart. */
.asp-legend i.k-buf{background:linear-gradient(105deg,#f4f6f8 0 45%,#e6f4fa 45% 100%);
  border:1px solid #cfe9f4}
.asp-calgrid{display:grid;grid-template-columns:repeat(7,1fr);gap:3px}
.asp-calgrid .dh{font-size:10.5px;font-weight:800;color:var(--asp-mut);text-align:center;
  text-transform:uppercase;letter-spacing:.3px;padding:2px 0}
.asp-d{border-radius:6px;padding:5px 4px;min-height:44px;font-size:10.5px;line-height:1.25;
  border:1px solid transparent}
.asp-d .dn{font-weight:700;color:var(--asp-mut);font-size:10px}
.asp-d .pr{font-weight:800;font-size:11px;margin-top:2px}
.asp-d.sale{background:#e6f4fa;border-color:#cfe9f4;color:var(--asp-pd)}
.asp-d.full{background:#f4f6f8;color:var(--asp-greyt)}
.asp-d.off{background:#f1efe6;color:#7a6a2f}
.asp-d.done{background:#fff;color:#c2ccd3}
.asp-d.past{opacity:.55}
.asp-d.today{outline:2px solid var(--asp-p);outline-offset:-2px}
.asp-d.wstart{border-left:3px solid var(--asp-p)}
/* P3-J — THE DAY THE SALE RESUMES AFTER A BUFFER, drawn opening at full price: the leading
   quarter of the cell is the full-price grey and the rest is the sale blue. A buffer takes no
   calendar day, so this is the ONLY place on the grid that can say the price went back at all.
   It has to be a rule and not an inline style because the two colours must stay the same ones
   .asp-d.full and .asp-d.sale use — they are read straight from those two rules above. Same
   specificity as .asp-d.sale and placed after it, so ordinary source order decides; no
   selector was widened to beat anything. The calendar has no dark-mode rules (the whole grid
   keeps its light palette), so this needs none either. */
.asp-d.hasbuf{background:linear-gradient(105deg,#f4f6f8 0 26%,#e6f4fa 26% 100%)}
.asp-winlist{margin-top:8px;font-size:12.5px}
.asp-winlist .w{display:grid;grid-template-columns:24px 1fr auto;gap:8px;padding:4px 0;
  border-top:1px dashed #e6edf2}
.asp-winlist .w:first-child{border-top:0}
/* A preview that failed replaces the calendar and NOTHING else — the plan above it is
   still editable and still saveable, which is the whole point of the shape. */
.asp-calerr{border:1.5px solid var(--asp-badl);background:#fdf6f6;border-radius:12px;
  padding:12px 14px;display:flex;flex-direction:column;gap:6px;align-items:flex-start}

/* ---- the per-listing table inside the editor ---- */
/* ══════════════════════════════════════════════════════════════════════════════════════
 * P2-H — THE STANDARD PRICE WAS DRAWN ON TOP OF THE TITLE
 * ══════════════════════════════════════════════════════════════════════════════════════
 * A grid column's default minimum width is `auto`, which means AS WIDE AS ITS CONTENT and not
 * one pixel less. So a long SKU beside a long title made the first column refuse to shrink,
 * and everything after it — Standard, First sale, Business, Minimum — was pushed out of the
 * row and over the top of the cell before it. Nothing was cut off; it was overlapping.
 *
 * minmax(0, 1fr) is the fix: it says the column MAY shrink below its content, and the content
 * inside it then has to say how it copes. It copes the way the Listings table already does —
 * two clamped lines with the whole title on hover — rather than by pushing its neighbours off.
 * min-width:0 on the cells themselves is the other half: a grid ITEM has the same auto minimum
 * as the track, and setting only the track leaves the item refusing to shrink inside it.
 */
.asp-lsel .asp-lr.asp-l5{grid-template-columns:minmax(0,1fr) 84px 92px 92px minmax(0,1fr)}
.asp-lsel .asp-lr > span{min-width:0}
/* TWO LINES, NOT ONE. Several of these listings differ only in the middle of the title, so a
   single line cuts before the part that tells them apart. The full title is on the cell. */
.asp-elip{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  max-height:2.9em;line-height:1.45;overflow-wrap:anywhere}
.asp-ok-t{color:var(--asp-ok)}
.asp-warn-t{color:var(--asp-warn)}
.asp-badge-ok{color:#1a4fb0}
.asp-infoline{background:var(--asp-pl);color:var(--asp-pd);border-radius:8px;padding:7px 10px;
  font-size:12.5px}
.asp-tplsave{display:flex;gap:6px;align-items:center}
.asp-page .asp-tplsave input[type="text"],.asp-page .asp-tplsave input:not([type="checkbox"]){
  border:1.5px solid var(--asp-line);border-radius:8px;padding:5px 8px;font:inherit;
  font-size:12.5px;width:180px;min-width:0}
.asp-page .asp-fld input,.asp-page .asp-fld select{min-width:0}

/* ---- templates ---- */
.asp-plansum{font-size:12.5px}
.asp-plansum b{color:var(--asp-pd)}
/* The apply banner: the Listings screen is a picker while this is up, and it says so. */
.asp-applybar{display:flex;gap:10px;align-items:center;flex-wrap:wrap;background:var(--asp-pl);
  border:1.5px solid var(--asp-pl2);color:var(--asp-pd);border-radius:12px;
  padding:9px 12px;margin-bottom:10px;font-size:13px}


/* ══════════════════════════════════════════════════════════════════════════════════════
 * P2-F — SCHEDULES, SETTINGS, ACTIVITY
 * ══════════════════════════════════════════════════════════════════════════════════════ */

/* ---- the row ---- */
/* Two lines of title and then an ellipsis. A schedules row carries a plan, four dates and a
   sentence from Amazon; a full product title would push all of it off the screen. */
.asp-clamp2{max-width:220px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden}
.asp-tag{display:inline-block;background:var(--asp-grey);color:var(--asp-greyt);
  border-radius:5px;padding:0 5px;font-size:11.5px}
/* The one blue line on the row: the minimum has been written and Amazon has not caught up. */
.asp-prep-t{color:#3557b7}

/* ---- the restore sentences ---- */
.asp-restore{line-height:1.5}
.asp-restore-ok{color:var(--asp-ok)}
.asp-restore-warn{color:var(--asp-warn)}
.asp-restore-bad{color:var(--asp-bad)}

/* ---- the plan block under the history ---- */
/* LAYOUT 1 — the value column wraps and takes the width it needs inside the panel. The
   minimum sentence is the longest thing in this module and it must be readable in full at
   every width; overflow-wrap:anywhere is for the values that are one long token (a URL, a
   SKU) rather than a sentence. */
.asp-flow{display:grid;grid-template-columns:132px minmax(0,1fr);gap:3px 10px;font-size:12.8px;
  margin-top:6px;align-items:start}
.asp-flow>span{min-width:0;overflow-wrap:anywhere}
.asp-flow .k{color:var(--asp-mut);overflow-wrap:normal}

/* ---- settings section headings ---- */
.asp-sechead{margin:16px 0 2px;text-transform:uppercase;letter-spacing:.4px;font-size:11.5px;
  color:var(--asp-greyt);font-weight:700}
.asp-sform .asp-sechead:first-of-type{margin-top:8px}
/* The three sections put a select in the value column where there used to be only numbers. */
.asp-page .asp-srow select{min-width:0;width:100%;max-width:320px}

/* ---- the mobile twins for the two new tables ----------------------------- */
.asp-mcard .asp-mhead{display:flex;justify-content:space-between;gap:8px;align-items:flex-start;
  flex-wrap:wrap;margin-bottom:6px}
.asp-mcard .asp-macts{display:flex;gap:6px;flex-wrap:wrap;margin-top:8px}

/* 1180 is the app's mobile-skin threshold and it is the right measure for things sized by the
   PAGE — the view switcher spans it, so it goes full width. It is the WRONG measure for the
   editor: .asp-panel is width:min(820px,100%), so at 1180 the panel is still 820px and
   collapsing its two-column form there produced a 780px-wide box to type "7" into. Those grids
   are keyed to the width they actually live in, which is reached around 760. */
@media (max-width:1180px){
  /* THE CARD'S SKU WAS THE LAST 16px IN THE MODULE. In the desktop table .asp-sku inherits
     13px from the cell and in the editor's listing list it inherits 11.5px, so it never needed
     a size of its own — but a card has no sized ancestor, so it landed on RMS's 16px page font
     and every card was headed by a SKU two points larger than anything near it.
     PINNED HERE, INSIDE THE MOBILE BLOCK, so the desktop table and the editor are untouched. */
  .asp-mcard .asp-sku{font-size:13.5px}

  .asp-nav{width:100%}
  .asp-nav button{flex:1;white-space:nowrap}
}
@media (max-width:760px){
  /* ---- P2-F: the schedule history and the settings sections at a phone width --- *
   * The history is two columns of dense text on a desktop; at this width they stack, and the
   * plan block's label column shrinks so a value is never squeezed to one word per line. */
  .asp-flow{grid-template-columns:104px 1fr}
  .asp-win{grid-template-columns:1fr;gap:2px}
  .asp-win .g{margin-top:6px}
  .asp-clamp2{max-width:none}
  .asp-page .asp-srow select{max-width:none}

  /* ---- P2-E: the editor at a phone width -------------------------------------- *
     The panel is width:min(820px,100%), so on a 375px screen every one of these grids is
     being asked to fit in about 350px. The step row is the one that breaks first: four
     columns at 28/120/1fr/auto cannot hold a select, two number inputs and three buttons,
     so it becomes two rows. The calendar KEEPS its seven columns — a month that wraps is
     not a month — and gives up cell padding instead. */
  .asp-step{grid-template-columns:22px 1fr;gap:6px 8px}
  .asp-step .mid{grid-column:1/-1}
  .asp-step .ops{grid-column:1/-1;justify-content:flex-end}
  .asp-twocol{grid-template-columns:1fr}
  .asp-dow button{width:44px;padding:5px 0;font-size:12px}
  .asp-calgrid{gap:2px}
  .asp-d{min-height:38px;padding:3px 2px;font-size:9.5px}
  .asp-d .pr{font-size:10px}
  .asp-calgrid .dh{font-size:9px}
  .asp-lsel .asp-lr.asp-l5{grid-template-columns:1fr}
  .asp-elip{max-width:100%;-webkit-line-clamp:3;max-height:4.35em}
  .asp-page .asp-tplsave input:not([type="checkbox"]){width:100%}
  .asp-fgrid{grid-template-columns:1fr}
  .asp-srow{grid-template-columns:1fr;align-items:start}
  .asp-lsel .asp-lr{grid-template-columns:1fr}
  /* Collapsed, a settings row is full width — the CONTROL in it must not be. The SELECT is
     exempt: its longest option needs about 280px and clipping it is the fault being fixed. */
  .asp-page .asp-srow input{max-width:160px}
  .asp-page .asp-srow select{max-width:100%}
}

/* ---- dark mode for everything above -------------------------------------- */
html[data-theme="dark"] .asp-panel{background:#101c26}
html[data-theme="dark"] .asp-pfoot{background:#0b1620;border-top-color:var(--asp-line)}
html[data-theme="dark"] .asp-page .asp-fld input,
html[data-theme="dark"] .asp-page .asp-fld select,
html[data-theme="dark"] .asp-page .asp-srow input,
html[data-theme="dark"] .asp-page .asp-srow select{background:#152430;color:var(--asp-ink);border-color:var(--asp-line)}
html[data-theme="dark"] .asp-seg button{background:#152430;color:var(--asp-greyt)}
html[data-theme="dark"] .asp-seg button.on{background:var(--asp-pl);color:#8fd2ee}
html[data-theme="dark"] .asp-lsel .asp-lr:first-child{background:#152430}
html[data-theme="dark"] .asp-prev{background:#0d2836;border-color:#17475e}
html[data-theme="dark"] .asp-fact{background:#152430}
html[data-theme="dark"] .asp-table tr.asp-exp td{background:#0d1a24}
html[data-theme="dark"] .asp-table tr.asp-sel td{background:#12303f}
html[data-theme="dark"] .asp-bulk{background:var(--asp-pl);color:#8fd2ee;border-bottom-color:#17475e}
html[data-theme="dark"] .asp-badge.b-paused{background:#1d242b;color:#9fb0bf}
html[data-theme="dark"] .asp-badge.b-wait{background:#141c33;color:#8fa6ea}
html[data-theme="dark"] .asp-badge.b-unk{background:#241f14;color:#cbb98f}
html[data-theme="dark"] .asp-warnline{background:#2c2313;color:#e8c88a}
html[data-theme="dark"] .asp-badline{background:#2c1615;color:#f0b3b1}

/* ---- BS: bulk selection, both scopes --------------------------------------
   The tri-state header box, the "select all N matching this filter" line, the
   filter-selected bulk bar, the mobile select-all row, the confirm's SKU chips
   and refusal list, and the Schedules batch bar. New control groups, each with a
   CSS-exists row in tests/amazon-sale-pricing-bulk-select.test.js. Mobile-only
   adjustments are inside the 1180 block below, never loose in the cascade. */
.asp-page .asp-table input.asp-selall{accent-color:var(--asp-p)}
.asp-selline{display:flex;gap:6px;align-items:center;flex-wrap:wrap;padding:8px 16px;
  background:#f4fbfe;border-bottom:1.5px solid var(--asp-pl2);font-size:12.5px;color:var(--asp-pd)}
.asp-page .asp-selline button{border:0;background:none;padding:0;font:inherit;font-weight:700;
  color:var(--asp-p);cursor:pointer;text-decoration:underline;text-underline-offset:2px}
.asp-page .asp-selline button:hover{color:var(--asp-pd)}
/* The FILTER selection's bar is a different colour on purpose: it is the one that leads to a
   bulk write, and it must never read as the ordinary page bar with a bigger number in it. */
.asp-bulk.asp-bulk-all{background:#fff7e6;border-bottom-color:#f1d9a6;color:#7a5a12}
.asp-mselall{display:flex;align-items:center;gap:8px;padding:6px 4px 10px;font-size:13px;
  font-weight:600;color:var(--asp-pd);cursor:pointer}
.asp-page .asp-mselall input.asp-selall{min-width:0;width:16px;height:16px;accent-color:var(--asp-p)}
.asp-bulkskus{display:flex;flex-wrap:wrap;gap:4px 6px;margin-top:4px}
.asp-bulkskus span{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:11.5px;
  background:var(--asp-grey);color:var(--asp-greyt);border-radius:6px;padding:1px 6px;max-width:100%;
  overflow-wrap:anywhere}
.asp-bulkskus span.warn{background:var(--asp-warnl);color:var(--asp-warn)}
/* P3-I — THE ✕ THAT TAKES ONE LISTING OUT OF THE SELECTION. The chip itself is the rule
   above, unchanged and shared with the bulk preview's SKU lists. This adds the remove
   control inside it, which nothing in this file had: every other ✕-shaped control here is a
   whole .asp-btn, which at 13px of padding would be three times the height of the chip it
   sits in. It OVERRIDES NOTHING — no rule in this stylesheet matches a button inside
   .asp-bulkskus — and it exists because style.css line 1 styles every bare <button> as a
   solid blue block with white text, so an unstyled ✕ here is invisible on a grey chip.
   Colour and size are inherited from the chip, so it follows the theme with it. */
.asp-page .asp-bulkskus span button{border:0;background:none;padding:0 0 0 5px;margin:0;
  font:inherit;line-height:1;color:inherit;opacity:.55;cursor:pointer;width:auto;box-shadow:none}
.asp-page .asp-bulkskus span button:hover{opacity:1;color:var(--asp-bad)}
.asp-bulkres{margin-top:4px;display:flex;flex-direction:column;gap:4px}
.asp-batchbar{display:flex;gap:10px;align-items:center;flex-wrap:wrap;padding:10px 16px;
  background:var(--asp-pl);border-bottom:1.5px solid var(--asp-pl2);font-size:13px;color:var(--asp-pd)}
.asp-batchchip{display:inline-block;font-size:11px;font-weight:700;background:var(--asp-pl2);
  color:var(--asp-pd);border-radius:6px;padding:0 6px;cursor:help;vertical-align:middle}
@media (max-width:1180px){
  .asp-selline{padding:8px 12px}
  .asp-bulk.asp-bulk-all{flex-direction:column;align-items:stretch}
  .asp-bulk.asp-bulk-all .asp-btn{width:100%}
  .asp-batchbar{flex-direction:column;align-items:flex-start}
}
html[data-theme="dark"] .asp-selline{background:#0d2836;color:#8fd2ee;border-bottom-color:#17475e}
html[data-theme="dark"] .asp-bulk.asp-bulk-all{background:#2c2313;color:#e8c88a;border-bottom-color:#4a3c1c}
html[data-theme="dark"] .asp-batchbar{background:var(--asp-pl);color:#8fd2ee;border-bottom-color:#17475e}
html[data-theme="dark"] .asp-bulkskus span{background:#182734;color:#a9bccb}
html[data-theme="dark"] .asp-bulkskus span.warn{background:#2c2313;color:#e8c88a}

/* ---- TP2: Performance — three small honest lists and a fourth, unranked ---------
   New control groups, each with a CSS-exists row in
   tests/amazon-sale-pricing-performance-screen.test.js. Mobile rules inside the
   1180 block below. No new inputs on this screen. */
.asp-perfsum{padding:10px 16px;border-bottom:1.5px solid var(--asp-line);font-size:13px;color:var(--asp-mut)}
.asp-perfsum b{color:var(--asp-ink)}
.asp-perfsec{border-bottom:1.5px solid var(--asp-line)}
.asp-perfsec:last-child{border-bottom:0}
.asp-perfsec h4{margin:0;padding:14px 16px 2px;font-size:14.5px;color:var(--asp-ink);display:flex;align-items:center;gap:8px}
.asp-perfsec h4 .n{font-size:11px;background:var(--asp-pl2);color:var(--asp-pd);border-radius:6px;padding:1px 7px;font-weight:700}
.asp-perfrule{padding:0 16px 8px;font-size:12.5px;color:var(--asp-mut)}
.asp-perfnone{padding:6px 16px 14px}
.asp-perfhead b{font-size:14px;color:var(--asp-ink)}
.asp-perfnum{white-space:nowrap}
.asp-perfctx{font-size:12.5px;line-height:1.5}
.asp-perfctx>div{margin-top:4px}
.asp-runtag{display:inline-block;font-size:11px;font-weight:700;background:var(--asp-pl2);color:var(--asp-pd);border-radius:6px;padding:0 6px;cursor:help;vertical-align:middle}
.asp-mcard .asp-perfhead{text-align:right}
.asp-mcard .asp-perfctx{margin-top:8px;padding:8px 10px;background:#f8fbfd;border-radius:8px}
@media (max-width:1180px){
  .asp-perfsec h4{padding-top:12px}
  .asp-perfnum{white-space:normal}
  .asp-mcard .asp-perfhead{text-align:left}
}
html[data-theme="dark"] .asp-perfsum{border-bottom-color:var(--asp-line)}
html[data-theme="dark"] .asp-perfsec{border-bottom-color:var(--asp-line)}
html[data-theme="dark"] .asp-mcard .asp-perfctx{background:#0d1a24}

/* ═══════════════════════════════════════════════════════════════════════════════
   R — RESPONSIVENESS: THE SPINNER, THE PULSE, AND WHAT EACH ONE MEANS
   ═══════════════════════════════════════════════════════════════════════════════
   .asp-spin  WAITING ON OUR OWN SERVER. A second or two, on the control that was pressed,
              which is disabled while it turns. If one of these ever runs for minutes, the
              thing it is on is talking to Amazon and has the wrong indicator.
   .asp-pulse WAITING ON AMAZON. Amazon takes hours — the measured wait on this account is
              5h49m — and a spinner running for hours reads as broken in exactly the way a
              dead button does. But no motion at all reads as frozen, so: a slow pulse, a
              sentence, and an age.
   Both stop entirely under prefers-reduced-motion, where the sentence and the age carry the
   whole meaning on their own — which is why the wording was never allowed to depend on them. */
.asp-spin{width:12px;height:12px;border:2px solid currentColor;border-top-color:transparent;
  border-radius:50%;display:inline-block;margin-right:7px;vertical-align:-1px;flex:none;
  opacity:.75;animation:asp-spin .7s linear infinite}
@keyframes asp-spin{to{transform:rotate(360deg)}}
.asp-pulse{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--asp-p);
  margin-right:7px;vertical-align:middle;flex:none;animation:asp-pl 1.8s ease-in-out infinite}
@keyframes asp-pl{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.3;transform:scale(.8)}}
@media (prefers-reduced-motion:reduce){
  .asp-spin,.asp-pulse{animation:none}
}
/* The sentence + age that goes with the pulse. It is a block, not a chip: it carries a
   sentence and the sentence is the point. */
.asp-wait{font-size:12px;color:var(--asp-pd);background:var(--asp-pl);border-radius:8px;
  padding:6px 9px;margin-top:6px;line-height:1.45}
.asp-wait.bad{background:var(--asp-badl);color:var(--asp-bad)}
.asp-wait b{font-weight:700}
/* The search says so beside itself — never on itself. */
.asp-searching{display:inline-flex;align-items:center;font-size:12.5px;color:var(--asp-mut);
  white-space:nowrap}
/* A refusal stays on the row, in the server's own three parts. */
.asp-acterr{margin-top:6px;flex-basis:100%;font-size:12px;line-height:1.5;text-align:left}
/* A relative time is hoverable for the clock time, and says so quietly. */
.asp-ago{border-bottom:1px dotted var(--asp-line);cursor:help}

/* ---- LAYOUT 3: "What RMS reads" is a set of facts, so it is laid out as one ----
   Seven flowing divs in a narrow column wrapped inside their own labels ("Price a shopper /
   sees: £12.99"), which reads as broken rather than as narrow. A definition list: labels left
   and never wrapping, values right, one pair per line. Same content, no new fields.
   The columns are auto-sized so the left one takes exactly what its longest label needs — the
   split that was 1:10 by accident is now decided by the content on purpose. */
.asp-amzcols{display:grid;grid-template-columns:minmax(0,auto) minmax(0,1fr);gap:12px 16px;
  align-items:start}
.asp-amzcols>*{min-width:0}
.asp-reads{display:grid;grid-template-columns:auto auto;gap:2px 14px;margin:4px 0 0;
  font-size:12.5px;align-items:baseline}
.asp-reads dt{color:var(--asp-mut);white-space:nowrap}
.asp-reads dd{margin:0;text-align:right;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
@media (max-width:1180px){
  /* Two columns of facts beside a JSON block is a desktop shape. At a tablet width the JSON
     goes underneath, where it has the full panel to scroll in. */
  .asp-amzcols{grid-template-columns:1fr}
  .asp-wait{font-size:12.5px}
}
@media (max-width:760px){
  /* At a phone width the pairs stack: two columns in 340px is how the labels came to wrap
     inside themselves in the first place. */
  .asp-reads{grid-template-columns:1fr;gap:0}
  .asp-reads dt{margin-top:6px}
  .asp-reads dd{text-align:left;font-weight:700}
  .asp-acterr{font-size:12.5px}
}
html[data-theme="dark"] .asp-wait{background:var(--asp-pl);color:#8fd2ee}
html[data-theme="dark"] .asp-wait.bad{background:#2c1615;color:#f0b3b1}
html[data-theme="dark"] .asp-ago{border-bottom-color:#24384a}
/* The phone frame for the History panel. Same body as the desktop row, in a card. */
.asp-mexp{margin-top:10px;padding-top:10px;border-top:1px dashed var(--asp-line)}
html[data-theme="dark"] .asp-mexp{border-top-color:var(--asp-line)}
