@charset "UTF-8";
/* widgets.css — Dashboard widgets, live search, report helpers for phones.
   Loaded in order by templates/partials/styles.html. */

/* ========================= 34. Dashboard ================================= */
/* Line chart drawn as inline SVG with the theme's own tokens — no chart
   library, nothing extra to load, and it follows light/dark automatically. */
.chart-wrap {
  display: flex;
  gap: var(--s-3);
  padding: var(--s-5) var(--s-5) 0;
}

/* y scale, so a point's height means a number */
.chart__scale {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 190px;
  padding-bottom: 22px;           /* clears the date ticks under the plot */
  font-size: var(--fs-xs);
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
  text-align: right;
  flex: 0 0 auto;
  min-width: 22px;
}

.chart {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  height: 190px;
  padding-bottom: 22px;
}

/* three reference lines behind the plot */
.chart__grid {
  position: absolute;
  inset: 0 0 22px 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  pointer-events: none;
}

.chart__grid i {
  height: 1px;
  background: var(--border);
  opacity: .7;
}

/* the daily average, so a point reads as above or below par */
.chart__avg {
  position: absolute;
  left: 0;
  right: 0;
  margin-bottom: 22px;
  border-top: 1px dashed var(--accent-500, var(--primary-500));
  opacity: .8;
  pointer-events: none;
  z-index: 2;
}

.chart__avg span {
  position: absolute;
  right: 0;
  top: -9px;
  padding: 0 4px;
  font-size: var(--fs-xs);
  color: var(--accent-600, var(--primary-600));
  background: var(--surface);
}

/* the plot itself */
.chart__svg {
  position: absolute;
  inset: 0 0 22px 0;
  width: 100%;
  height: calc(100% - 22px);
  overflow: visible;
}

.chart__area {
  fill: var(--primary-500);
  opacity: .12;
}

.chart__line {
  fill: none;
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.chart__line--total {
  stroke: var(--primary-500);
  opacity: .45;
  stroke-dasharray: 4 3;
}

.chart__line--placed {
  stroke: var(--primary-500);
}

/* dots sit in HTML so they stay round — an SVG circle would stretch into an
   ellipse under preserveAspectRatio="none" */
.chart__dots {
  position: absolute;
  inset: 0 0 22px 0;
  pointer-events: none;
}

.chart__dot {
  position: absolute;
  width: 7px;
  height: 7px;
  margin: 0 0 -3.5px -3.5px;      /* centre on its coordinate */
  border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--primary-500);
  pointer-events: auto;
  cursor: default;
  transition: transform var(--t-fast);
}

.chart__dot:hover {
  transform: scale(1.5);
}

.chart__dot.is-zero {
  border-color: var(--border-strong);
}

.chart__dot.is-today {
  background: var(--primary-500);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary-500) 25%, transparent);
}

/* date labels along the bottom */
.chart__ticks {
  position: absolute;
  inset: auto 0 0 0;
  height: 18px;
}

.chart__tick {
  position: absolute;
  transform: translateX(-50%);
  font-size: var(--fs-xs);
  color: var(--text-3);
  white-space: nowrap;
}

.chart__tick.is-today {
  color: var(--primary-600);
  font-weight: 700;
}

/* legend beside the panel title */
.chart__key {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--fs-xs);
  color: var(--text-3);
}

.chart__swatch {
  width: 14px;
  height: 0;
  border-top: 2px solid var(--primary-500);
}

.chart__swatch--total {
  opacity: .45;
  border-top-style: dashed;
}

/* two panels side by side, stacking when there is no room */
.dash-split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: var(--s-5);
}

.dash-split > .panel {
  margin: 0;
}

@media (max-width: 640px) {
  .chart-wrap {
    padding: var(--s-4) var(--s-3) 0;
  }

  .chart,
  .chart__scale {
    height: 150px;
  }

  /* fewer, smaller labels and no dots — they crowd at this width */
  .chart__tick {
    font-size: 9px;
  }

  .chart__dot {
    width: 5px;
    height: 5px;
    margin: 0 0 -2.5px -2.5px;
  }
}


/* ===================== 30. Live search & filtering ======================= */
/* A swapped-in region keeps the layout it replaced: the filter block sits in
   the toolbar's flex row, so it must not become a box of its own. */
.toolbar > [data-live-region] {
  display: contents;
}

/* while the server is answering — the delay keeps a fast reply from
   flickering the list */
[data-live].is-loading .table-wrap,
[data-live].is-loading .product-grid {
  opacity: 0.5;
  pointer-events: none;
  transition: opacity var(--t-fast) 150ms;
}

/* ---- topbar suggestions ---- */
.search__panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 600;
  max-height: min(70vh, 460px);
  overflow-y: auto;
  padding: var(--s-2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
}
.search__panel[hidden] {
  display: none;
}

.search__hit {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-2);
  border-radius: var(--r-md);
  color: var(--text);
  text-decoration: none;
}
.search__hit:hover,
.search__hit.is-active {
  background: var(--surface-3);
}

.search__hit img {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  object-fit: cover;
  background: var(--bg);
  border-radius: var(--r-sm);
}

/* min-width:0 so a long product name ellipsises instead of pushing the
   price and the badge off the edge of the panel */
.search__hit > div {
  min-width: 0;
  flex: 1 1 auto;
}
.search__hit strong,
.search__hit small {
  display: block;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.search__hit strong {
  font-weight: 600;
}
.search__hit small {
  font-size: var(--fs-sm);
}

.search__hit-side {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  font-size: var(--fs-sm);
  font-weight: 600;
}

.search__none {
  margin: 0;
  padding: var(--s-4);
  text-align: center;
  color: var(--text-3);
  font-size: var(--fs-sm);
}

.search__more {
  display: block;
  margin-top: var(--s-1);
  padding: var(--s-3);
  text-align: center;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--primary-600);
  text-decoration: none;
  border-top: 1px solid var(--border);
  border-radius: var(--r-md);
}
.search__more:hover,
.search__more.is-active {
  background: var(--surface-3);
}

/* the topbar search goes full width on phones, and so does its panel */
@media (max-width: 720px) {
  .search__hit-side {
    display: none;
  }
}

/* The UA's [hidden] rule is a bare attribute selector, so any class that sets
   display beats it and a filtered-out row stays on screen. These are the
   three the search and the segment filter hide. */
.table--stack tbody tr[hidden],
.product-grid[hidden],
.product-card[hidden] {
  display: none;
}

/* ===================== 35. Reports on a phone ===========================
   The reports carry more controls than any other page — a search box, a
   four-way period segment, a dealer picker, date boxes and an export menu —
   and on a narrow screen they had nowhere to go. Everything here is scoped
   to the reports, so the order and product toolbars are untouched. */

/* A segment is inline-flex with no wrap, so a row of chips — "All time /
   Monthly / Yearly / Custom range" on a report, "Today / Last 7 days / Last 30
   days / Last 90 days" on the dashboard — ran past the edge of the panel. Let
   the chips themselves wrap onto a second line and share the width.

   This used to be scoped to .toolbar--report and .toolbar--sub, which left the
   dashboard's own range segment out: its chips had to squeeze instead of wrap,
   and "Last 30 days" came apart into three overlapping lines. It applies to
   every full-size segment now. --sm is left alone: the "100 / page | Show all"
   switch in a table footer is two short chips that already fit. */
@media (max-width: 640px) {
  .segment:not(.segment--sm) {
    flex-wrap: wrap;
    width: 100%;
  }
  .segment:not(.segment--sm) a,
  .segment:not(.segment--sm) button {
    flex: 1 1 auto;
    justify-content: center;
    text-align: center;
  }
}

/* Tighter gutters, so the controls get the width instead of the padding. */
@media (max-width: 560px) {
  .toolbar--report,
  .toolbar--sub {
    padding: var(--s-3);
    gap: var(--s-2);
  }

  /* The export menu and the period badge each get their own line rather than
     being squeezed onto the end of the row. Descendant selectors, not child:
     both sit inside #reportFilters, which is display:contents — that makes
     them flex items of the toolbar, but they are not its DOM children. */
  .toolbar--report .export-menu,
  .toolbar--report .muted {
    flex: 1 1 100%;
  }
  .toolbar--report .export-menu > summary {
    justify-content: center;
  }

  /* the ageing strip above the due-count table */
  .age-strip {
    padding: var(--s-3);
    gap: var(--s-2);
  }

  /* one card per row, and less of the panel spent on padding */
  .report-grid {
    grid-template-columns: 1fr;
    gap: var(--s-3);
    padding: var(--s-3);
  }
  .report-card {
    padding: var(--s-3);
    gap: var(--s-3);
  }
}

/* A stacked table lays each cell out as its own full-width row, so the side
   padding belongs to the row, not the cell. The .table--fixed edge rules are
   more specific than .table--stack's, though, so the first cell of every row
   kept a 20px indent the others did not have. Put them back to zero. */
@media (max-width: 640px) {
  .table--stack.table--fixed th,
  .table--stack.table--fixed td,
  .table--stack.table--fixed th:first-child,
  .table--stack.table--fixed td:first-child,
  .table--stack.table--fixed th:last-child,
  .table--stack.table--fixed td:last-child {
    padding-left: 0;
    padding-right: 0;
  }

  /* a stacked row reads as a card, so it needs room down the sides again */
  .table--stack.table--fixed tr {
    padding: var(--s-3) var(--s-4);
  }

  /* the label and the value must not collide on a narrow screen */
  .table--stack.table--fixed td {
    gap: var(--s-3);
  }
}

/* ============== 36. Who a salesman is ordering for ======================
   A dealer never sees this bar: their own account is the answer. A salesman
   serves many dealers, so the one they are working for has to be on screen
   and changeable at any point. */
.acting-bar {
  padding: var(--s-4) var(--s-5);
}

.acting-bar__form {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin: 0;
}

.acting-bar__who {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding-right: var(--s-4);
  border-right: 1px solid var(--border);
  font-size: var(--fs-sm);
}
.acting-bar__who ion-icon {
  font-size: 1.6rem;
  color: var(--primary-600);
}
.acting-bar__who small {
  display: block;
}

.acting-bar__label {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text-2);
}

.acting-bar .select {
  flex: 1 1 220px;
  max-width: 340px;
  min-height: 34px;
}

@media (max-width: 560px) {
  .acting-bar {
    padding: var(--s-3);
  }
  .acting-bar__who {
    flex: 1 1 100%;
    padding-right: 0;
    border-right: 0;
  }
  .acting-bar .select {
    max-width: none;
  }
}

/* ================ 37. Drilling from one report into another =============
   A name that opens the rows behind it. The chevron is what says so — the
   text alone reads as a label, not a link. */
.drill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  color: inherit;
  text-decoration: none;
}

.drill strong {
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 2px;
  transition: color var(--t-fast), text-decoration-color var(--t-fast);
}

.drill ion-icon {
  flex: 0 0 auto;
  font-size: 0.9rem;
  color: var(--text-3);
  transition: color var(--t-fast), transform var(--t-fast);
}

.drill:hover strong,
.drill:focus-visible strong {
  color: var(--primary-600);
  text-decoration-color: currentColor;
}
.drill:hover ion-icon,
.drill:focus-visible ion-icon {
  color: var(--primary-600);
  transform: translateX(2px);
}

/* the code sits under the name, not beside the chevron */
.drill small {
  flex-basis: 100%;
}
