/*
 * Threads application glue
 * ------------------------
 * `/up` and the production family inside Threads own every shared visual
 * element. This deliberately small file contains only route composition and
 * server-rendered states that are specific to this PHP application.
 */

/* Keep assistive labels available without adding visible duplicate headings. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* The shared PHP shell supplies `<main>`; native page components own width. */
.application-main {
  width: 100%;
}

/* Let the live-themed wordmark sit directly on the linen wall while retaining
   just enough dimensional separation for its white lettering and emblem. */
.homepage-wordmark {
  filter: drop-shadow(0 12px 24px rgb(0 0 0 / 36%)) drop-shadow(0 0 20px rgb(var(--accent-rgb) / 10%));
}

/* Present the product table as the page's one deliberately raised object. */
.homepage-product-panel {
  width: min(100%, 500px);
  margin: 42px auto 0;
  padding: 22px;
}

/* The containing management surface provides the outer glass box, while this
   wrapper retains the native table's own fine boundary. */
.homepage-product-table {
  width: 100%;
  margin: 0;
}

/* The shared production table permits wider business datasets. Keep this
   one-column list full-width so its heading, rows and dividers fill the inner
   panel instead of collapsing to the width of the product names. */
.homepage-product-table .user-table {
  width: 100%;
  min-width: 100%;
}

/* Give the garment artwork enough presence to become the table's visual focus
   without turning the five-row list into oversized dashboard cards. */
.homepage-product-table .product-table-glyph {
  width: 56px;
  height: 56px;
  flex-basis: 56px;
}

/* Keep supporting user text below its stronger account name. */
.table-primary,
.table-secondary {
  display: block;
}

.table-primary {
  color: var(--ink);
  font-weight: 700;
}

.table-secondary {
  margin-top: 3px;
  color: var(--muted);
  font-size: 11px;
}

/* Highlighting belongs to search semantics, not the permanent row surface. */
mark {
  padding: 0 1px;
  border-radius: 2px;
  background: rgb(var(--accent-rgb) / 28%);
  color: var(--ink);
}

.user-dialog-danger-icon {
  display: inline-grid;
  place-items: center;
  width: 34px;
  height: 34px;
  flex: 0 0 34px;
  border-radius: 999px;
  background: rgb(195 55 80 / 18%);
  color: #ef7184;
  font-weight: 700;
}

/* Preferences adds one existing account route beside the native save action. */
.preferences-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

.preferences-password-button {
  text-decoration: none;
}

.password-page {
  width: min(100%, 520px);
}

/* Public setup retains a small local-only masthead and uses the native login card. */
.setup-page {
  min-height: 100vh;
}

.application-header__content {
  width: min(100%, 1120px);
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

.application-logo {
  width: 138px;
  height: auto;
}

.status-pill {
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.setup-shell {
  width: min(100%, 560px);
  margin: 7vh auto 0;
}

.setup-card__heading {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-bottom: 24px;
}

.setup-emblem {
  width: 64px;
  height: 64px;
  flex: 0 0 64px;
  object-fit: contain;
}

.setup-card h1,
.public-auth-card h1 {
  margin: 0;
}

.eyebrow {
  margin: 0 0 7px;
  color: var(--success);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.intro__copy {
  margin: 8px 0 0;
  color: var(--muted);
  line-height: 1.55;
}

.setup-form {
  display: grid;
  gap: 18px;
}

/* Legacy PHP field wrappers receive native production form geometry only on
   setup/password pages; ordinary production controls use `.form-field`. */
.setup-form .field {
  display: grid;
  gap: 8px;
}

.setup-form .field__label {
  color: var(--ink);
  font-size: 13px;
  font-weight: 500;
}

.setup-form .field__control {
  width: 100%;
  min-height: 44px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: rgb(20 22 27 / 72%);
  color: var(--ink);
  font: inherit;
}

.setup-form .field__control:focus {
  outline: none;
  border-color: var(--accent-hover);
  box-shadow: 0 0 0 3px var(--accent-focus);
}

.field__help {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.45;
}

.setup-actions {
  display: flex;
  justify-content: flex-end;
}

.status-message {
  display: grid;
  gap: 3px;
  margin: 0 0 20px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: rgb(15 17 21 / 58%);
  color: var(--muted);
  font-size: 13px;
}

.status-message strong { color: var(--ink); }
.status-message--success { border-color: rgb(90 173 112 / 40%); }
.status-message--danger { border-color: rgb(195 55 80 / 48%); }
.status-message--info { border-color: rgb(var(--accent-rgb) / 38%); }

.public-auth-card {
  margin: 0 auto;
}

/* Requirements deliberately keeps eleven business columns and uses the full
   management canvas before the shared responsive-detail controller condenses
   lower-priority values. */
.application-page--shirt-requirements .management-page {
  width: 100%;
}

/* Give the expanded Requirement scan more of its existing card width without
   reducing the shared vertical spacing or widening the document. */
.application-page--shirt-requirements .management-card {
  padding-inline: clamp(20px, 2.5vw, 32px);
}

/* Jeans Requirements has eleven directly visible columns. Use the full
   management canvas so the table is comfortably readable on wide screens. */
.application-page--jeans-requirements .management-page {
  width: 100%;
}

.application-page--jeans-requirements .management-card {
  padding-inline: clamp(20px, 2.5vw, 32px);
}

/* Sleeves and Cuts carry five usage and ordering columns beside their row
   actions. Give both dimension masters the broad desktop canvas they need,
   while the 100% cap and shared table scroller preserve the system-wide
   overflow boundary. */
.application-page--shirt-sleeves .management-page,
.application-page--shirt-cuts .management-page {
  width: min(1500px, 100%);
}

@media (max-width: 620px) {
  .preferences-actions,
  .setup-card__heading {
    align-items: stretch;
    flex-direction: column;
  }

  .preferences-actions .button {
    width: 100%;
    text-align: center;
  }

  .setup-shell {
    margin-top: 24px;
  }
}

/* Keep every PPC surface inside the available application canvas. */
.application-page--shirt-ppc-rules .management-page,
.application-page--shirt-ppc-custom .management-page,
.application-page--shirt-ppc-default .management-page {
  /* The shared management wrapper normally sizes from table content. PPC is a
     stateful grid, so its outer width must not be recalculated when the Pieces
     panel swaps empty guidance for its compact form. */
  width: min(1500px, 100%);
}

.ppc-rule-card {
  width: min(1500px, 100%);
}

.ppc-panel-browser {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  margin-top: 18px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--line);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}

/* Default rules omit the Fabric axis but retain the exact dimensions and type
   scale of Custom, so moving between the sibling pages feels stable. */
.ppc-panel-browser--default {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  --ppc-panel-height: 390px;
}

.ppc-default-rounding {
  display: grid;
  grid-template-columns: minmax(230px, 360px) auto minmax(220px, 1fr);
  align-items: end;
  gap: 12px;
  margin-top: 18px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: #1f2228;
}

.ppc-default-rounding small {
  align-self: center;
  color: var(--muted);
  font-size: 10px;
  line-height: 1.45;
}

/* Reuse the complete available PPC card width. The shared table wrapper still
   owns any unavoidable narrow-screen overflow, so this section must not
   shrink-wrap itself back to the table's smallest intrinsic contribution. */
.ppc-saved-rules {
  width: 100%;
  min-width: 0;
  max-width: 100%;
  margin: 24px auto 0;
}

.ppc-saved-rules__heading {
  margin-bottom: 12px;
}

.ppc-saved-rules__heading h2,
.ppc-saved-rules__heading p {
  margin: 0;
}

.ppc-saved-rules__heading h2 {
  color: var(--ink);
  font-size: 18px;
}

.ppc-saved-rules__heading p {
  margin-top: 5px;
  color: var(--muted);
  font-size: 11px;
}

/* Nested PPC navigation opens beside Shirts using the submenu system's
   existing animation and stacking behaviour. */
.navigation-submenu--nested > summary.navigation-submenu__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.navigation-submenu--nested > summary.has-current-child {
  color: var(--accent-readable);
}

@media (max-width: 760px) {
  .ppc-default-rounding {
    grid-template-columns: 1fr;
    align-items: stretch;
  }
}

/* Give report selection a calm, bounded workspace before the wide result
   table is introduced; every field still uses the shared production controls. */
.management-page--report-builder {
  width: min(1800px, 100%);
}

.dispatch-report-card {
  display: grid;
  gap: 20px;
  padding-inline: clamp(20px, 2.5vw, 32px);
}

.dispatch-report-form,
.dispatch-report-section {
  display: grid;
  gap: 14px;
}

.dispatch-report-section {
  min-width: 0;
  margin: 0;
  padding: 16px;
  border: 1px solid var(--line);
  border-radius: 10px;
}

.dispatch-report-section legend {
  padding: 0 8px;
  color: var(--ink);
  font-weight: 700;
}

.dispatch-report-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
}

/* Let every report field shrink to its assigned grid track. A long multi-select
   must scroll its pills inside the trigger instead of widening the Shop column
   and pushing the complete report card beyond the viewport. */
.dispatch-report-grid > .form-field {
  min-width: 0;
}

.dispatch-report-grid--dates {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  max-width: 560px;
}

.dispatch-quick-scope {
  background: rgb(var(--accent-rgb) / 5%);
}

.dispatch-quick-scope__entry {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: 10px;
}

.dispatch-quick-scope__buttons {
  display: flex;
  gap: 8px;
}

.dispatch-quick-scope__buttons .button {
  min-height: 38px;
}

.dispatch-quick-scope__field-label {
  color: var(--muted);
  font-size: 13px;
  font-weight: 600;
}

.dispatch-quick-scope__composer {
  display: flex;
  min-height: 38px;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  background: var(--surface-input, #181b20);
  cursor: text;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}

.dispatch-quick-scope__composer:focus-within {
  border-color: var(--accent-readable);
  box-shadow: 0 0 0 3px rgb(var(--accent-rgb) / 14%);
}

.dispatch-quick-scope__composer input {
  min-width: 180px;
  min-height: 28px;
  flex: 1 1 220px;
  padding: 0 2px;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  color: var(--ink);
  outline: 0;
}

.dispatch-quick-scope__help,
.dispatch-quick-scope__status {
  margin: 0;
  color: var(--muted);
  font-size: 12px;
}

.dispatch-quick-scope__status:not(:empty) {
  color: var(--accent-readable);
}

.dispatch-quick-scope__status.is-error {
  color: #ef7184;
}

.dispatch-quick-scope__pills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.dispatch-quick-scope__pills:empty {
  display: none;
}

.dispatch-quick-scope__pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 28px;
  padding: 4px 9px;
  border: 1px solid rgb(var(--accent-rgb) / 52%);
  border-radius: 999px;
  background: rgb(var(--accent-rgb) / 18%);
  color: var(--accent-readable);
  font-size: 12px;
  font-weight: 700;
  cursor: default;
}

.dispatch-quick-scope__pill--all {
  border-color: var(--line-strong);
  background: rgb(255 255 255 / 4%);
  color: var(--muted);
  font-weight: 600;
}

.dispatch-quick-scope__pill-label {
  color: var(--muted);
  font-size: 10px;
  letter-spacing: .03em;
  text-transform: uppercase;
}

.dispatch-quick-scope__pill-remove {
  display: grid;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  cursor: pointer;
  font: inherit;
  line-height: 1;
  place-items: center;
}

.dispatch-quick-scope__pill-remove:hover,
.dispatch-quick-scope__pill-remove:focus-visible {
  background: rgb(var(--accent-rgb) / 24%);
  outline: none;
}

.dispatch-report-actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

/* Order to Supplier builds its own stack of tables straight into the card rather
   than into a report preview frame, so nothing declared the gap that frame would
   have given it and the Positive Total row sat hard against the View Report
   button. The empty-state paragraph takes the same gap, so the two states do not
   start in different places. */
.supplier-order-results,
.application-page--jeans-supplier-order-report .dispatch-report-placeholder {
  margin-top: 28px;
}

.dispatch-report-preview {
  min-height: 120px;
  display: grid;
  place-items: center;
  padding: 22px;
  border: 1px dashed var(--line-strong);
  border-radius: 10px;
}

.dispatch-report-preview__empty {
  max-width: 660px;
  margin: 0;
  color: var(--muted);
  text-align: center;
}

.dispatch-report-preview--results {
  display: block;
  min-height: 0;
  padding: 0;
  overflow: hidden;
  border-style: solid;

  /* Release the centring the empty state uses. Blink honours justify-self in
     block layout, so a report left with it shrink-wraps to its own content and
     floats in the middle of the card instead of filling it. */
  place-items: normal;
}

/* Replacing one report with another is a content change rather than a
   navigation, so it borrows the page transition's own movement: the finished
   report withdraws downward and its replacement rises into place. Only opacity
   and transform move here — the card's height is animated separately by the
   structural layout controller, which already owns that motion. */
.dispatch-report-preview.is-report-leaving,
.dispatch-report-preview.is-report-entering {
  /* Keep the rising and withdrawing content inside the report's own frame. */
  overflow: hidden;
}

.dispatch-report-preview.is-report-leaving > * {
  animation:
    threads-page-content-leave 360ms ease-in both,
    dispatch-report-content-leave 360ms ease-in both;
}

.dispatch-report-preview.is-report-entering > * {
  animation:
    threads-page-content-enter 720ms ease-out both,
    dispatch-report-content-enter 720ms ease-out both;
}

/* The shared page keyframes move content without fading it, because a full
   navigation fades the whole canvas instead. A report swap has no canvas fade
   of its own, so it carries its own. */
@keyframes dispatch-report-content-leave {
  /* Begin at the settled, fully readable report. */
  from {
    opacity: 1;
  }

  /* Finish transparent so the replacement arrives against an empty frame. */
  to {
    opacity: 0;
  }
}

@keyframes dispatch-report-content-enter {
  /* Begin transparent so a partly measured table never flashes first. */
  from {
    opacity: 0;
  }

  /* Finish at the ordinary fully readable report. */
  to {
    opacity: 1;
  }
}

/* Hold the frame open at its previous size while the next report is fetched,
   so the card never collapses to a single line and spring back. */
.dispatch-report-preview__loading {
  display: grid;
  place-items: center;
  height: 100%;
  min-height: 120px;
  margin: 0 auto;
  padding: 22px;
}

/* Respect visitors who request little or no interface motion. */
@media (prefers-reduced-motion: reduce) {
  /* Present each new report immediately, without movement or fading. */
  .dispatch-report-preview.is-report-leaving > *,
  .dispatch-report-preview.is-report-entering > * {
    animation: none;
  }
}

.dispatch-report-table-wrapper {
  width: 100%;
  margin: 0;
}

.dispatch-report-table {
  width: 100%;
  min-width: 100%;
  table-layout: fixed;
}

@media (max-width: 1000px) {
  .dispatch-report-table {
    min-width: 1100px;
    table-layout: auto;
  }
}

.dispatch-report-table caption {
  padding: 14px 16px;
  color: var(--muted);
  font-weight: 700;
  text-align: left;
}

.dispatch-report-table th,
.dispatch-report-table td {
  padding-block: 10px;
  transition: background-color 120ms ease, color 120ms ease;
}

/* Let compact report headings use a second line instead of widening their
   complete column. Body values keep their existing single-value layout. */
.dispatch-report-table thead th {
  white-space: normal;
  overflow-wrap: break-word;
  line-height: 1.25;
  vertical-align: middle;
}

.dispatch-report-table tbody tr:hover {
  animation: user-table-row-glow 2.4s ease-in-out infinite;
}

.dispatch-report-table tbody tr:hover > * {
  animation: user-table-row-surface 2.4s ease-in-out infinite;
}

.dispatch-report-table .is-column-hovered {
  background-color: rgb(255 255 255 / 4%);
}

@media (prefers-reduced-motion: reduce) {
  .dispatch-report-table tbody tr:hover {
    animation: none;
    filter: drop-shadow(0 0 6px rgb(var(--accent-readable-rgb) / 16%));
  }

  .dispatch-report-table tbody tr:hover > * {
    animation: none;
    background-color: rgb(var(--accent-rgb) / 32%);
  }
}

.dispatch-report-table .dispatch-report-number {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.dispatch-report-total-row > * {
  border-top: 1px solid var(--line);
  background: rgb(255 255 255 / 3%);
  font-weight: 700;
}

.dispatch-report-total-row--negative > * {
  color: #ef7184;
}

.dispatch-report-total-row--net > * {
  background: rgb(var(--accent-rgb) / 12%);
  color: var(--ink);
}

/* Card Working reuses the complete Dispatch report scope resolver, then shows
   the planning result as one compact Size table per Item + Sleeve + Cut. */
.card-working-reserve-option {
  display: inline-flex;
  width: fit-content;
  min-height: 38px;
  align-items: center;
  gap: 9px;
  color: var(--ink);
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}

.card-working-reserve-option input {
  width: 18px;
  height: 18px;
  accent-color: var(--accent-readable);
}

.card-working-preview-header {
  display: flex;
  min-height: 58px;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  background: rgb(255 255 255 / 3%);
}

.card-working-preview-header > div {
  display: grid;
  gap: 2px;
}

.card-working-preview-header strong { color: var(--ink); }
.card-working-preview-header span { color: var(--muted); font-size: 12px; }

.card-working-sections {
  display: grid;
  gap: 18px;
  padding: 18px;
}

.card-working-section {
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: rgb(255 255 255 / 2%);
}

.card-working-section__heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 15px;
  border-bottom: 1px solid var(--line);
  background: rgb(var(--accent-rgb) / 16%);
}

.card-working-section__heading strong {
  color: var(--ink);
  font-size: 16px;
  letter-spacing: .03em;
}

.card-working-section__heading span {
  color: var(--muted);
  font-size: 11px;
}

.card-working-section__context {
  display: grid;
  grid-template-columns: minmax(220px, 1fr) minmax(100px, .3fr) minmax(90px, .25fr);
  gap: 18px;
  padding: 12px 15px;
  border-bottom: 1px solid var(--line);
  background: rgb(var(--accent-rgb) / 8%);
}

.card-working-section__context > div {
  display: grid;
  align-content: start;
  gap: 2px;
}

.card-working-section__context span,
.card-working-section__context small {
  color: var(--muted);
  font-size: 10px;
}

.card-working-section__context span {
  letter-spacing: .04em;
  text-transform: uppercase;
}

.card-working-section__context strong {
  color: var(--ink);
  font-size: 13px;
}

.card-working-table th:first-child,
.card-working-table td:first-child {
  width: 54px;
  text-align: center;
}

.card-working-table th:nth-child(2) { width: 22%; }
.card-working-required-value {
  border-bottom: 1px dotted color-mix(in srgb, var(--muted) 72%, transparent);
  cursor: help;
  outline: none;
}
.card-working-required-value:focus-visible {
  border-radius: 3px;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 45%, transparent);
}
/* One red for a negative, wherever it is printed. The class is named after the
   report it was written for; every report family since has joined this rule
   rather than inventing a second colour for the same meaning. */
.card-working-table .card-working-negative,
.balance-summary-table .card-working-negative,
.dispatch-report-table .card-working-negative { color: #ef7184; }
.card-working-empty { padding: 28px; }

@media (max-width: 620px) {
  .card-working-preview-header {
    align-items: flex-start;
    flex-direction: column;
  }

  .card-working-section__context { grid-template-columns: 1fr; }
  .card-working-section__heading { align-items: flex-start; flex-direction: column; }
}

.report-multiselect__panel {
  min-width: 100%;
}

.report-multiselect .threads-select__value {
  display: flex;
  width: 0;
  max-width: 100%;
  flex: 1 1 auto;
  flex-wrap: nowrap;
  align-items: center;
  gap: 4px;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}

.report-multiselect .threads-select__value::-webkit-scrollbar {
  display: none;
}

.report-multiselect,
.report-multiselect .threads-select__trigger {
  min-width: 0;
  max-width: 100%;
}

.report-multiselect .threads-select__trigger {
  overflow: hidden;
}

.report-multiselect__pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex: 0 0 auto;
  min-width: 0;
  max-width: 112px;
  padding: 2px 7px;
  overflow: hidden;
  border: 1px solid rgb(var(--accent-rgb) / 52%);
  border-radius: 999px;
  background: rgb(var(--accent-rgb) / 18%);
  color: var(--accent-readable);
  font: inherit;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.35;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}

.report-multiselect__pill:hover,
.report-multiselect__pill:focus-visible {
  outline: 0;
  border-color: var(--accent-hover);
  background: rgb(var(--accent-rgb) / 26%);
  box-shadow: 0 0 0 2px var(--accent-focus);
}

.report-multiselect__pill-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.report-multiselect__pill-remove {
  flex: 0 0 auto;
  font-size: 13px;
  line-height: 1;
}

.report-multiselect__all {
  border-bottom: 1px solid var(--line);
  border-radius: 0;
}

.report-multiselect .threads-select__option:disabled {
  display: none;
}

/* Reports place several related selectors together, so use the compact form
   density seen in operational filtering without changing controls elsewhere. */
.management-page--report-builder .form-field {
  gap: 5px;
}

.management-page--report-builder .form-field > span {
  font-size: 13px;
}

.management-page--report-builder .threads-select__trigger,
.management-page--report-builder .threads-date__trigger {
  min-height: 38px;
  padding: 7px 10px;
  font-size: 13px;
}

.management-page--report-builder .report-multiselect .threads-select__trigger {
  height: auto;
}

.management-page--report-builder .threads-select__search {
  min-height: 32px;
  padding: 5px 8px;
  font-size: 12px;
}

.management-page--report-builder .threads-select__option {
  min-height: 32px;
  padding: 5px 9px;
  font-size: 13px;
}

.management-page--report-builder .dispatch-report-actions .button {
  min-height: 38px;
  padding: 7px 12px;
  font-size: 13px;
}

@media (max-width: 980px) {
  .dispatch-report-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 620px) {
  .dispatch-report-grid,
  .dispatch-report-grid--dates { grid-template-columns: 1fr; }
  .dispatch-quick-scope__entry { grid-template-columns: 1fr; }
  .dispatch-quick-scope__buttons .button { flex: 1; }
  .dispatch-report-actions { justify-content: stretch; }
  .dispatch-report-actions .button { flex: 1; }
}

.ppc-panel {
  display: flex;
  min-width: 0;
  height: var(--ppc-panel-height, 390px);
  min-height: var(--ppc-panel-height, 390px);
  max-height: var(--ppc-panel-height, 390px);
  flex-direction: column;
  background: #1f2228;
  transition: background-color 240ms ease, opacity 240ms ease;
}

.ppc-panel + .ppc-panel {
  border-left: 1px solid var(--line);
}

.ppc-panel.is-locked {
  background: #1b1e23;
}

.ppc-panel-header {
  display: flex;
  min-height: 64px;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 11px 12px;
  border-bottom: 1px solid var(--line);
  background: #252930;
}

.ppc-panel-header h2,
.ppc-panel-header p {
  margin: 0;
}

.ppc-panel-header h2 {
  color: var(--ink);
  font-size: 12px;
}

.ppc-panel-header p {
  overflow: hidden;
  margin-top: 4px;
  color: var(--muted);
  font-size: 9px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ppc-panel-search {
  position: relative;
  display: grid;
  min-height: 43px;
  align-items: center;
  padding: 7px 9px;
  border-bottom: 1px solid var(--line);
  background: #1f2228;
}

.ppc-panel-search__icon {
  position: absolute;
  left: 17px;
  color: var(--muted);
  font-size: 13px;
  pointer-events: none;
}

.ppc-panel-search input {
  width: 100%;
  min-width: 0;
  height: 29px;
  padding: 5px 8px 5px 27px;
  border: 1px solid var(--line);
  border-radius: 6px;
  outline: 0;
  background: #181b20;
  color: var(--ink);
  font: inherit;
  font-size: 9px;
}

.ppc-panel-search input::placeholder {
  color: var(--muted);
}

.ppc-panel-search input:focus {
  border-color: var(--accent-readable);
  box-shadow: 0 0 0 2px var(--accent-glow);
}

.ppc-panel-sort {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px 7px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #1f2228;
  color: var(--muted);
  font: inherit;
  font-size: 8px;
  cursor: pointer;
}

.ppc-panel-sort:hover,
.ppc-panel-sort:focus-visible {
  border-color: var(--accent-readable);
  color: var(--ink);
}

.ppc-panel-list {
  flex: 1;
  min-height: 0;
  overflow: auto;
  transition: opacity 260ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

.ppc-panel.is-locked .ppc-panel-list {
  opacity: .3;
  pointer-events: none;
}

.ppc-panel-row {
  position: relative;
  min-height: 49px;
  border-bottom: 1px solid #30343c;
}

.ppc-panel-row[hidden] {
  display: none;
}

/* Fabric pagination is deliberately compact and lives inside the height owned
   by the Fabric axis rather than adding an unrelated control below the grid. */
.ppc-panel-pagination {
  display: grid;
  min-height: 42px;
  grid-template-columns: 28px minmax(0, 1fr) 28px;
  align-items: center;
  gap: 6px;
  padding: 6px 8px;
  border-top: 1px solid var(--line);
  background: #252930;
  color: var(--muted);
  font-size: 8px;
  text-align: center;
}

.ppc-panel-pagination[hidden] {
  display: none;
}

.ppc-panel-pagination button {
  display: grid;
  width: 28px;
  height: 28px;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #1f2228;
  color: var(--ink);
  cursor: pointer;
}

.ppc-panel-pagination button:disabled {
  opacity: .35;
  cursor: default;
}

.ppc-panel-row::before {
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: transparent;
  content: "";
}

.ppc-panel-row:hover {
  background: var(--surface-hover);
}

.ppc-panel-row.is-selected {
  background: linear-gradient(90deg, var(--accent-soft), #252832 78%);
  box-shadow: inset 0 0 20px var(--accent-glow);
}

.ppc-panel-row.is-selected::before {
  background: var(--accent-readable);
}

.ppc-panel-option {
  display: grid;
  width: 100%;
  min-height: 48px;
  grid-template-columns: 28px minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
  padding: 7px 9px 7px 11px;
  border: 0;
  background: transparent;
  color: #e2e5ea;
  text-align: left;
  cursor: pointer;
}

.ppc-panel-option:focus-visible {
  outline: 2px solid var(--accent-readable);
  outline-offset: -2px;
}

.ppc-panel-option__glyph {
  display: grid;
  width: 26px;
  height: 26px;
  place-items: center;
  border: 1px solid color-mix(in srgb, var(--accent-readable) 48%, var(--line));
  border-radius: 7px;
  background: var(--accent-soft);
  color: var(--accent-readable);
  font-size: 12px;
  font-weight: 700;
}

.ppc-panel-option__label {
  overflow: hidden;
  font-size: 11px;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ppc-panel-option__status {
  color: var(--warning);
  font-size: 8px;
}

.ppc-panel-empty {
  display: grid;
  min-height: 260px;
  place-content: center;
  gap: 7px;
  padding: 22px;
  color: var(--muted);
  font-size: 10px;
  line-height: 1.45;
  text-align: center;
}

.ppc-panel-empty[hidden] {
  display: none;
}

.ppc-panel-empty--search {
  min-height: 100%;
}

.ppc-panel-empty strong {
  color: var(--ink);
}

.ppc-pieces-body {
  display: grid;
  flex: 1;
}

.ppc-pieces-form {
  align-content: start;
  gap: 10px;
  padding: 12px;
}

.ppc-pieces-form:not([hidden]) {
  display: grid;
  animation: ppc-pieces-content-enter 320ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

/* The final editor belongs to the compact panel family, not the larger dialog
   form family. Match its label and control rhythm to the 48px selector rows. */
.ppc-pieces-form .form-field {
  gap: 5px;
}

.ppc-pieces-form .form-field > span {
  color: #e2e5ea;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.25;
}

.ppc-pieces-form .form-field input {
  width: 100%;
  min-height: 36px;
  padding: 7px 9px;
  border-radius: 7px;
  font-size: 11px;
  line-height: 1.2;
}

@keyframes ppc-pieces-content-enter {
  from {
    opacity: 0;
    transform: translateY(8px) scale(.985);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

.ppc-combination-summary {
  margin: 0;
  color: var(--muted);
  font-size: 8px;
  line-height: 1.4;
}

.ppc-pieces-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* Use the same restrained control scale as panel sort and row actions so the
   Pieces panel never becomes the visual centre of the five-part workflow. */
.ppc-pieces-actions .button {
  min-height: 32px;
  padding: 6px 10px;
  border-radius: 7px;
  font-size: 10px;
  line-height: 1.2;
}

.ppc-fallback-form {
  display: grid;
  gap: 14px;
  margin-top: 18px;
}

@media (max-width: 1100px) {
  .ppc-panel-browser {
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }
}

@media (max-width: 700px) {
  .ppc-panel-browser {
    display: flex;
    flex-direction: column;
    overflow: visible;
  }

  .ppc-panel {
    height: 230px;
    min-height: 230px;
    max-height: 230px;
  }

  .ppc-panel + .ppc-panel {
    border-top: 1px solid var(--line);
    border-left: 0;
  }

  .ppc-panel-list {
    max-height: 280px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ppc-panel,
  .ppc-panel-list,
  .ppc-pieces-form:not([hidden]) {
    animation: none;
    transition: none;
  }
}

/* Keep Fabric lifecycle changes visible and immediate within every mapping row. */
.fabric-status-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 4px 2px;
  border: 0;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
}

.fabric-status-toggle__track {
  position: relative;
  width: 42px;
  height: 24px;
  flex: 0 0 42px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgb(255 255 255 / 8%);
  box-shadow: inset 0 0 0 0 rgb(var(--accent-rgb) / 0%);
  transition: border-color 220ms ease, background-color 220ms ease, box-shadow 220ms ease;
}

.fabric-status-toggle__thumb {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--muted);
  transform: translateX(0);
  transition: transform 220ms cubic-bezier(0.34, 1.56, 0.64, 1), background-color 180ms ease;
}

.fabric-status-toggle.is-active {
  color: var(--accent-hover);
}

.fabric-status-toggle.is-active .fabric-status-toggle__track {
  border-color: rgb(var(--accent-rgb) / 58%);
  background: rgb(var(--accent-rgb) / 25%);
  box-shadow: inset 0 0 0 1px rgb(var(--accent-rgb) / 12%);
}

.fabric-status-toggle.is-active .fabric-status-toggle__thumb {
  transform: translateX(18px);
  background: var(--accent-hover);
}

.fabric-status-toggle:focus-visible {
  outline: 2px solid var(--accent-hover);
  outline-offset: 3px;
  border-radius: 7px;
}

.fabric-status-toggle:disabled {
  cursor: not-allowed;
  opacity: 0.48;
}

.fabric-status-toggle.is-saving:disabled {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .fabric-status-toggle__track,
  .fabric-status-toggle__thumb {
    transition: none;
  }
}

/* Cards use the same lifecycle language in a compact, action-column switch. */
.card-status-toggle {
  display: inline-grid;
  place-items: center;
  width: 46px;
  height: 34px;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: 7px;
  background: transparent;
  cursor: pointer;
}

.card-status-toggle__track {
  position: relative;
  width: 36px;
  height: 20px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgb(255 255 255 / 8%);
  transition: border-color 180ms ease, background-color 180ms ease;
}

.card-status-toggle__thumb {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--muted);
  transform: translateX(0);
  transition: transform 180ms cubic-bezier(0.34, 1.56, 0.64, 1), background-color 180ms ease;
}

.card-status-toggle.is-active .card-status-toggle__track {
  border-color: rgb(var(--accent-rgb) / 58%);
  background: rgb(var(--accent-rgb) / 25%);
}

.card-status-toggle.is-active .card-status-toggle__thumb {
  transform: translateX(16px);
  background: var(--accent-hover);
}

.card-status-toggle:hover,
.card-status-toggle:focus-visible {
  border-color: var(--accent-hover);
}

.card-status-toggle:focus-visible {
  outline: 2px solid var(--accent-hover);
  outline-offset: 2px;
}

.card-status-toggle:disabled {
  cursor: default;
  opacity: 0.62;
}

.card-status-toggle.is-saving:disabled {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .card-status-toggle__track,
  .card-status-toggle__thumb {
    transition: none;
  }
}

/* Keep Card-first Dispatch entry readable without turning it into a wide grid.
   Size the native dialog layer itself so its surface remains truly centred. */
.user-dialog--dispatch-batch {
  width: min(940px, calc(100vw - 32px));
  max-width: min(940px, calc(100vw - 32px));
}

.dispatch-batch-form {
  display: grid;
  gap: 18px;
}

.dispatch-card-context,
.dispatch-line-builder {
  display: grid;
  grid-template-columns: minmax(150px, 0.45fr) minmax(280px, 1.55fr);
  gap: 14px;
  align-items: end;
}

.dispatch-card-summary {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: rgb(255 255 255 / 4%);
}

.dispatch-card-summary span {
  display: grid;
  gap: 2px;
  color: var(--muted);
  font-size: 12px;
}

.dispatch-card-summary strong { color: var(--ink); }

.dispatch-line-builder {
  grid-template-columns: minmax(260px, 1fr) minmax(130px, 0.35fr) auto;
}

.dispatch-line-add { min-height: 44px; }

@media (max-width: 760px) {
  .dispatch-card-context,
  .dispatch-line-builder,
  .dispatch-card-summary { grid-template-columns: 1fr; }
  .dispatch-card-summary { grid-column: auto; }
}

/* ==========================================================================
   Product dashboards
   --------------------------------------------------------------------------
   The Shirts and Jeans landing pages. These reuse Threads's real design
   tokens rather than inventing their own: the same glass treatment, corner
   radius, ambient theme shadow and accent family as `.management-card`, so a
   dashboard reads as part of the application and follows the six accent
   themes without any per-theme code here.
   ========================================================================== */

.product-dashboard {
  display: flex;
  flex-direction: column;
  gap: clamp(24px, 4vw, 38px);
  max-width: 1180px;
  margin: 0 auto;
  padding: 8px 0 56px;
}

/* --- Page heading ------------------------------------------------------- */

.product-dashboard__header {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.product-dashboard__header h1 {
  margin: 0;
  font-size: clamp(30px, 4vw, 42px);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.05;
  color: var(--ink);
}

/* Underline the heading with the live accent so each product page is
   immediately identifiable as themed rather than generic. */
.product-dashboard__header h1::after {
  content: "";
  display: block;
  width: 54px;
  height: 3px;
  margin-top: 14px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--accent-readable), rgb(var(--accent-rgb) / 25%));
}

.product-dashboard__subtitle {
  margin: 0;
  max-width: 62ch;
  font-size: 13px;
  line-height: 1.5;
  color: var(--muted);
}

/* --- Sections ----------------------------------------------------------- */

.product-dashboard__section {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.product-dashboard__section-title {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-readable);
}

/* A hairline carries the eye across to the far edge without adding a border
   that would compete with the tiles beneath it. */
.product-dashboard__section-title::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, rgb(var(--accent-readable-rgb) / 22%), transparent);
}

.product-dashboard__grid {
  display: grid;
  /* Tiles size themselves. A three-figure Jeans panel and a four-figure
     Shirts panel both read as deliberate rather than one looking unfinished. */
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: clamp(12px, 1.6vw, 18px);
}

/* --- Tiles -------------------------------------------------------------- */

.product-dashboard__tile {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 6px;
  box-sizing: border-box;
  min-width: 0;
  padding: 22px 24px 20px;
  overflow: hidden;

  /* The same glass as `.management-card`, one step lighter so a dashboard of
     many tiles does not read as heavier than a page holding one table. */
  border: 1px solid rgb(255 255 255 / 10%);
  border-radius: 16px;

  /* No `backdrop-filter` here, deliberately. A backdrop-filtered tile samples
     and blurs everything behind it — including the accent glow thrown by its
     own and its neighbours' box-shadows, and the shadow of the navigation
     submenu passing overhead. Where the 16px corner mask thins to nothing that
     blurred brightness surfaced as white specks along the top edge, every time
     a menu dropped. The linen behind these tiles is a static texture, so the
     blur was buying almost nothing; a slightly more opaque surface reads the
     same and cannot pick up a shadow that is not its own. */
  background: rgb(25 27 32 / 58%);

  /* Keep the depth shadow, drop the 42px accent glow that was the bright
     source. The tiles still lift off the page; they no longer light each
     other's corners. */
  box-shadow: 0 18px 48px rgb(0 0 0 / 34%);

  color: inherit;
  text-decoration: none;
  transition:
    transform 180ms cubic-bezier(0.22, 0.61, 0.36, 1),
    border-color 180ms ease,
    box-shadow 180ms ease;
}

/* A theme-coloured edge light along the top of every tile. */
.product-dashboard__tile::before {
  content: "";
  position: absolute;
  /* Stop the hairline short of the 16px corner curve. Run to the very edge and
     its end pixels sit where the radius has already clipped the tile away,
     which is the second way a stray light pixel reaches the corner. */
  inset: 0 16px auto;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgb(var(--accent-readable-rgb) / 38%), transparent);
}

/* Only a tile that actually goes somewhere responds to the pointer; an inert
   figure must not promise a destination it does not have. */
a.product-dashboard__tile::after {
  content: "→";
  position: absolute;
  top: 18px;
  right: 20px;
  font-size: 15px;
  line-height: 1;
  color: var(--accent-readable);
  opacity: 0;
  transform: translateX(-6px);
  transition: opacity 180ms ease, transform 180ms ease;
}

a.product-dashboard__tile:hover,
a.product-dashboard__tile:focus-visible {
  transform: translateY(-3px);
  border-color: rgb(var(--accent-readable-rgb) / 34%);

  /* The hover glow is safe: one tile at a time, and nothing is blurring it. */
  box-shadow: 0 26px 60px rgb(0 0 0 / 42%), 0 0 58px rgb(var(--accent-rgb) / 16%);
}

a.product-dashboard__tile:hover::after,
a.product-dashboard__tile:focus-visible::after {
  opacity: 1;
  transform: translateX(0);
}

a.product-dashboard__tile:focus-visible {
  outline: 3px solid var(--accent-focus);
  outline-offset: 2px;
}

.product-dashboard__label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
}

.product-dashboard__value {
  /* Tabular figures so a column of numbers aligns on its digits. */
  font-variant-numeric: tabular-nums;
  font-size: clamp(28px, 3.4vw, 38px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.05;
  color: var(--ink);
}

/* Reserved for figures that can legitimately be negative, such as an
   over-dispatched Balance. An ordinary count of zero never receives it. */
.product-dashboard__value--negative {
  color: var(--error);
}

.product-dashboard__hint {
  margin-top: 2px;
  font-size: 12px;
  line-height: 1.45;
  color: var(--muted);
  opacity: 0.85;
}

@media (max-width: 720px) {
  .product-dashboard__grid { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
  .product-dashboard__tile { padding: 18px 18px 16px; }
}

/* ==========================================================================
   Homepage product links
   --------------------------------------------------------------------------
   Shirts and Jeans have dashboards; the other three families do not. An
   accent chevron marks the difference, so clickability is visible before the
   pointer arrives rather than only on hover.
   ========================================================================== */

/* The cell gives up its own padding so the anchor can fill it edge to edge.
   Anywhere in the cell is then the click and hover target, not just the text. */
.product-table-cell--link {
  padding: 0 !important;
}

.product-table-link {
  display: flex;
  align-items: center;
  gap: 12px;
  box-sizing: border-box;

  /* Exactly the padding the cell just gave up, so the row height is unchanged. */
  width: 100%;
  padding: 13px 10px;

  color: inherit;
  text-decoration: none;
  transition: background-color 160ms ease, color 160ms ease;
}

/* A quiet accent wash confirms the whole row is live. */
.product-table-link:hover,
.product-table-link:focus-visible {
  background: rgb(var(--accent-readable-rgb) / 7%);
}

.product-table-link .product-table-glyph {
  transition: transform 200ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* The chevron belongs to the link, not the row, so an unlinked family simply
   has no arrow rather than a greyed-out one. */
/* Sit the chevron against the far edge so it reads as "this row leads
   somewhere" rather than as punctuation after the product name. */
.product-table-link__arrow {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: rgb(var(--accent-readable-rgb) / 12%);
  color: var(--accent-readable);
  font-size: 12px;
  line-height: 1;
  transition:
    transform 200ms cubic-bezier(0.22, 0.61, 0.36, 1),
    background-color 200ms ease;
}

.product-table-link:hover .product-table-link__arrow,
.product-table-link:focus-visible .product-table-link__arrow {
  transform: translateX(4px);
  background: rgb(var(--accent-readable-rgb) / 24%);
}

.product-table-link:hover .product-table-glyph,
.product-table-link:focus-visible .product-table-glyph {
  transform: scale(1.06);
}

.product-table-link:hover strong,
.product-table-link:focus-visible strong {
  color: var(--accent-readable);
}

.product-table-link:focus-visible {
  outline: 3px solid var(--accent-focus);
  outline-offset: 3px;
}

/*
 * Multi Card Working column headings
 * ----------------------------------
 * Every other report labels its number columns Req, Reserve, Tot, UP and Bal.
 * This one names four of them after the Territories and Job Workers that were
 * chosen, so those headings carry real words - and the shared report table is
 * `table-layout: fixed` with `overflow-wrap: break-word`, which split
 * "Maharashtra" across two lines as MAHARAS / HTRA.
 *
 * A fixed layout shares out whatever it is not told, so widening only the named
 * columns took that width from Total Req and Reserve and broke those instead.
 * Every column is therefore given its own width here, and words are allowed to
 * wrap only at spaces - "Total Req" over two lines is a heading, "TOTA L REQ"
 * is a defect. A group of names too long even for this is cut with an ellipsis
 * in PHP before it arrives, and keeps its full text in a tooltip.
 *
 * All of it is scoped to `[data-multi-card-working]`, so the Card Working
 * report's own table keeps the proportions it has today.
 */
.card-working-table[data-multi-card-working] th[scope="col"] {
    overflow-wrap: normal;
    word-break: keep-all;
}

.card-working-table[data-multi-card-working] th[scope="col"]:first-child {
    width: 2.5rem;
}

.card-working-table[data-multi-card-working] th[scope="col"]:nth-child(2) {
    width: 5.5rem;
}

.card-working-table[data-multi-card-working] th.card-working-column--name {
    width: 7rem;
}

.card-working-table[data-multi-card-working] th.card-working-column--label {
    width: 5rem;
}

/*
 * Balance-Pieces tooltip
 * ----------------------
 * The Card Working reports put the Shops behind a Req figure into the tooltip
 * it already carried, one per line. The shared tooltip sets `textContent`, so
 * the newlines are real text and only need honouring; without this they collapse
 * into one unreadable run. Left aligned and width-capped so a fifteen-Shop list
 * reads as a list rather than as a paragraph.
 *
 * Scoped to the tooltip's own class rather than to a report, because it is one
 * shared floating surface - and every other tooltip is a single line, which
 * `pre-line` leaves exactly as it is.
 *
 * The width cap is deliberately left to threads-ui, which already sets a
 * viewport-aware `min(280px, ...)`. Restating it here as a fixed width would
 * overflow a narrow screen to buy room this list does not need.
 */
.table-action-tooltip {
    white-space: pre-line;
    text-align: left;
}

/*
 * Balance Summary grid
 * --------------------
 * A cross-tab that is deliberately wide - one band of Sizes per Item, repeating
 * across - so it scrolls inside its wrapper rather than squeezing every column
 * to nothing. `table-layout: auto` is the point: the shared report tables share
 * their width out equally, which would give a two-Size Item the same room as a
 * six-Size one.
 *
 * The Shop column sticks to the left edge, because a figure forty columns along
 * means nothing if you cannot see whose row it is.
 */
/*
 * The shared report table is `table-layout: fixed`, which shares the width out
 * equally and would give a two-Size Item the same room as a six-Size one. Here
 * the columns must size to their contents, so this overrides it - the class is
 * doubled up only to outrank `.dispatch-report-table` on specificity.
 */
.balance-summary-table.dispatch-report-table {
    table-layout: auto;
    width: max-content;
    min-width: 100%;
}

/* Figures never wrap; the headings above them still may, which is how a long
   Size name like "08 X 14 + 12 X 14" stays inside a sensible column. */
.balance-summary-table tbody td,
.balance-summary-table tbody th,
.balance-summary-table tfoot th {
    white-space: nowrap;
}

.balance-summary-table .balance-summary-shop-heading {
    position: sticky;
    left: 0;
    z-index: 2;
    text-align: left;
    background-color: var(--surface-raised, #1b1d22);
}

/* The cell beneath Shop and All Items exists only to keep the two header rows
   aligned column for column; it should read as part of the heading above it. */
.balance-summary-table .balance-summary-band-filler {
    border-top: 0;
}

/* The band naming each Item sits centred over the Sizes it covers, with a rule
   down each side so one Item's block is visibly separate from the next. */
.balance-summary-table .balance-summary-band {
    text-align: center;
    border-left: 1px solid rgb(255 255 255 / 14%);
}

.balance-summary-table .balance-summary-item-total {
    border-right: 1px solid rgb(255 255 255 / 14%);
    font-weight: 600;
}

.balance-summary-table .balance-summary-band--grand,
.balance-summary-table td.balance-summary-item-total:last-child {
    border-left: 2px solid rgb(255 255 255 / 22%);
}

/*
 * Jeans dispatch dialogs
 * ----------------------
 * A Chart is six short fields and a list of Shop allocations. Stacked one per
 * row the dialog became a tall column that scrolled; the Shirt dispatch batch
 * dialog solved the same problem by going wide, so these follow it.
 *
 * The allocation fieldset spans the full width because its rows are the widest
 * thing in the dialog, and a Shop line reads as one row - Shop, Pieces, Remove -
 * rather than three stacked fields.
 */
.user-dialog--jeans-dispatch {
  width: min(940px, calc(100vw - 32px));
  max-width: min(940px, calc(100vw - 32px));

  /* Sit above centre rather than in it. A Chart with ten Shops is a tall
     dialog, and centring one leaves it starting low and running off the
     bottom; anchoring the top gives the allocations room to grow downwards. */
  margin-block: 5vh auto;
}

.jeans-dispatch-form {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px 16px;
  align-items: end;
}

.jeans-dispatch-form > .form-fieldset,
.jeans-dispatch-form > .form-hint { grid-column: 1 / -1; }

/* The builder row and the staged table both span the full dialog width. */
.jeans-dispatch-form > .dispatch-line-builder,
.jeans-dispatch-form > .card-staging-wrap,
.jeans-dispatch-form > .staging-running-total,
.jeans-dispatch-form > .requirement-batch-error { grid-column: 1 / -1; }

@media (max-width: 760px) {
  .jeans-dispatch-form { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   Whole-filter selection banner
   --------------------------------------------------------------------------
   Appears inside the bulk-actions bar once a page is fully selected and the
   current filter matches more than the page holds. It is deliberately quiet
   until it matters: widening a selection from 25 to 250 should read as an
   offer, not as a warning, but the count must be impossible to miss because it
   is the number the next click acts on. */
.table-selection-scope {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-left: auto;
  padding-left: 0.75rem;
  font-size: 0.8125rem;
  color: var(--threads-muted-text, #9a94a6);
}

.table-selection-scope__action {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-weight: 600;
  color: var(--threads-accent, #b03052);
  text-decoration: underline;
  text-underline-offset: 0.2em;
  cursor: pointer;
}

.table-selection-scope__action:hover,
.table-selection-scope__action:focus-visible {
  text-decoration-thickness: 2px;
}
