/* ============================================================
   TRILLIONS — buyer workspace
   ------------------------------------------------------------
   Loads after tokens.css and buyer-identity.css.

   buyer-dashboard.js creates nodes with the class names
   .buyer-open-rfq, .buyer-quote-card, .quote-price, .timeline-item,
   .timeline-item.is-empty, .identity-muted and .identity-status; it
   drives step visibility through [data-rfq-step],
   [data-rfq-step-indicator] and .buyer-rfq-next / .buyer-rfq-back.
   Every one of those is styled here and none may be renamed without
   changing the script in step.
   ============================================================ */

.dashboard-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s4);
  margin-block-end: var(--s5);
}

/* No eyebrow above the view heading. It only ever restated the heading
   one size smaller — "Billing" over "Invoices" — and the rail already
   says which view you are in. */

.dashboard-head h1 {
  font-size: clamp(24px, 3vw, 34px);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.1;
}

/* The three stages of the buyer flow, always visible so the page
   answers "where am I" before it answers anything else. */
.dashboard-command {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s2);
  margin-block: var(--s4) var(--s5);
}

.dashboard-command span {
  padding: 10px var(--s4);
  border: 1px solid var(--line);
  border-radius: var(--r2);
  background: var(--surface);
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: -0.01em;
  color: var(--mute);
}

.dashboard-card {
  /* A grid item defaults to min-width:auto, which lets a wide table push the
     whole page sideways instead of scrolling inside its own card. */
  min-width: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r4);
  padding: var(--s5);
}

.dashboard-section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  margin-block-end: var(--s4);
  padding-block-end: var(--s3);
  border-bottom: 1px solid var(--line);
}

.dashboard-section-head .eyebrow {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--mute);
}

.dashboard-section-head h2 {
  margin-block-start: 3px;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.015em;
}

.stage-pill {
  display: inline-flex;
  align-items: center;
  padding: 4px 12px;
  border: 1px solid var(--nil-line);
  border-radius: var(--pill);
  background: var(--nil-bg);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink-3);
}

/* ------------------------------------------------------------
   Overview

   The cards are the shared .metric from tokens.css. What belongs
   to this page is only the list under them: whatever is actually
   waiting on the buyer, each line the door to the view that
   clears it.
   ------------------------------------------------------------ */

.buyer-task-list {
  display: grid;
  gap: var(--s2);
}

.buyer-task-list li {
  display: flex;
  align-items: center;
  gap: var(--s2);
  font-size: 14px;
}

/* A dash rather than a bullet: the list is short and never nested,
   and a bullet at this size reads as noise. */
.buyer-task-list li::before {
  content: "";
  flex: none;
  width: 10px;
  border-top: 1.5px solid var(--miss);
}

/* ------------------------------------------------------------
   Request wizard
   ------------------------------------------------------------ */

.buyer-rfq-steps {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s4);
  margin-block-end: var(--s5);
}

.buyer-rfq-steps li {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  color: var(--mute);
}

.buyer-rfq-steps li span {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--wash);
  font-family: var(--mono);
  font-size: 11px;
}

.buyer-rfq-steps li.is-active {
  color: var(--ink);
}

.buyer-rfq-steps li.is-active span {
  background: var(--ink);
  color: #fff;
  border-color: var(--ink);
}

.buyer-rfq-steps li.is-active strong {
  font-weight: 600;
}

#rfqForm .form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s4);
}

#rfqForm .form-grid .field-full {
  grid-column: 1 / -1;
}

/* The form is groups now, and a group is the width of the card: the pairing
   that used to be done here is done inside each fieldset, where it can be
   pairing of things that belong together rather than of whatever happened to be
   adjacent. .field-full still marks a full-width child, because the token layer
   styles the groups and this is the page saying how they are laid out. */
#supplierProductForm {
  grid-template-columns: minmax(0, 1fr);
}

#supplierProductForm .field-full,
#supplierProductForm > button {
  grid-column: 1 / -1;
}

/* A file input is a control the browser draws, so it is left alone rather than
   given the 42px box the text fields wear: the box would be a border around a
   button that already has one. */
#supplierProductForm input[type="file"] {
  height: auto;
  padding: 9px 0;
  border: 0;
  font-size: 13px;
}

#supplierProductPhotoNote {
  margin-block-start: -6px;
}

.wizard-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s3);
  margin-block-start: var(--s5);
  padding-block-start: var(--s4);
  border-top: 1px solid var(--line);
  font-size: 12px;
  color: var(--mute);
}

/* Label and value on one row, told apart by the space between them. Without
   this the pairs render as "Request typeRFQ / sourcing" — every character
   present and two fields read as one. */
.rfq-review-summary > div {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s2) var(--s4);
}

.rfq-review-summary strong {
  color: var(--ink);
}

.rfq-review-summary {
  display: grid;
  gap: var(--s2);
  padding: var(--s4);
  border: 1px solid var(--line);
  border-radius: var(--r3);
  background: var(--wash);
  font-size: 13px;
  color: var(--mute);
}

/* Where a request goes after it is sent. Four states, in order. */
.status-ladder {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin-block-start: var(--s4);
}

.status-ladder span {
  padding: 5px 12px;
  border: 1px solid var(--line);
  border-radius: var(--pill);
  background: var(--surface);
  font-size: 11.5px;
  color: var(--mute);
}

/* ------------------------------------------------------------
   Workspace shell
   The bar and the rail are the operations shell, from the token
   layer. What belongs here is where they sit: the wrap that holds
   the page to its measure, and the bar reaching back out to the
   edges of it so the rule under it runs the full width.

   The four sections are views of this one page rather than four
   pages: they share a session, a message banner and a request the
   buyer has selected, and reloading all of that to move between
   them would be slower and would lose the selection.
   ------------------------------------------------------------ */

.buyer-wrap,
.supplier-wrap {
  width: 100%;
  max-width: var(--measure);
  margin-inline: auto;
  padding: 0 var(--page-margin) var(--s8);
}

.buyer-wrap .app-topbar,
.supplier-wrap .app-topbar {
  margin-inline: calc(var(--page-margin) * -1);
  padding-inline: var(--page-margin);
}

.workspace-view {
  display: grid;
  gap: var(--s4);
  align-content: start;
}

/* A supplier account with no company on file yet. There is nothing behind any
   of the rail's destinations, so the rail goes and the one column left takes
   the width — the shell is two columns and the rail is the first of them, so
   without this the panel reads in a strip down the page's left edge. */
.supplier-wrap.is-unregistered .app-shell {
  grid-template-columns: minmax(0, 1fr);
}

/* The account, opened from the profile menu rather than from the rail — it is
   not a destination a buyer works in, it is one they check. */
.workspace-view[data-view-panel="account"] .dashboard-card {
  max-width: 640px;
}

/* ------------------------------------------------------------
   History
   ------------------------------------------------------------ */

/*
 * The toolbar. Search takes the room it needs and the rest of the controls sit
 * together at the end of the row, so the two things a buyer changes most are
 * next to each other rather than at opposite ends of the card.
 */
.buyer-list-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--s3);
  margin-block-end: var(--s4);
  padding-block-end: var(--s4);
  border-bottom: 1px solid var(--line);
}

.buyer-list-filters label {
  display: grid;
  gap: 6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--mute);
}

.buyer-list-filters label:first-of-type {
  flex: 1 1 260px;
}

.buyer-list-filters input,
.buyer-list-filters select {
  width: 100%;
  height: 38px;
  padding-inline: var(--s3);
  border: 1px solid var(--line-strong);
  border-radius: var(--r2);
  background: var(--surface);
  font-size: 13px;
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
  color: var(--ink);
  /* Typed values resolve their own direction; see .input in tokens.css. */
  unicode-bidi: plaintext;
}

/* A request row carries seven columns and none of them can be dropped, so on
   a narrow screen the table scrolls inside its card rather than pushing the
   page sideways. */
.table-scroll {
  overflow-x: auto;
  margin-inline: calc(var(--s4) * -1);
  padding-inline: var(--s4);
}

.dashboard-table table {
  width: 100%;
  min-width: 640px;
  border-collapse: collapse;
}

.dashboard-table th {
  padding: 10px var(--s3);
  border-bottom: 1px solid var(--line-strong);
  background: var(--nil-bg);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--mute);
  text-align: start;
  white-space: nowrap;
}

.dashboard-table td {
  padding: 14px var(--s3);
  border-bottom: 1px solid var(--line);
  font-size: 13px;
  vertical-align: middle;
}

/*
 * Telling one row from the next.
 *
 * Seven columns of the same grey ran together, and the row a buyer had actually
 * selected was marked with a class nothing styled. Four things separate them
 * now, and each carries a different part of the job: the banding gives the eye a
 * rhythm to follow across a wide row, the reference is the row's name in mono so
 * two references never look alike, the status is the chip every verdict on this
 * platform wears, and the accent on the inline-start edge says which row is
 * under the pointer and which one is open.
 */
.dashboard-table tbody tr {
  transition: background var(--fast) var(--ease);
}

/* Every other row carries the field colour, so a row is a band the eye can
   follow across six columns rather than a line of text between two hairlines.
   Alternating rather than one colour per row: colour on this platform carries a
   verdict, and a row is not a verdict — the banding is the field, and the only
   hue in the table is the one the status chip brings with it. */
.dashboard-table tbody tr:nth-child(even) {
  background: var(--wash);
}

.dashboard-table tbody tr:nth-child(odd) {
  background: var(--surface);
}

/* The accent is drawn as an inset shadow rather than a border, so a row does not
   change width when it lights up and the columns stay in line. */
.dashboard-table tbody tr:hover {
  background: var(--nil-bg);
  box-shadow: inset 3px 0 0 0 var(--line-strong);
}

[dir="rtl"] .dashboard-table tbody tr:hover,
[dir="rtl"] .dashboard-table tbody tr.is-selected {
  box-shadow: inset -3px 0 0 0 var(--line-strong);
}

/* The request the offers view is showing. It is the one row on the page that
   means something elsewhere, so it holds its mark whether the pointer is on it
   or not. */
.dashboard-table tbody tr.is-selected {
  background: var(--nil-bg);
  box-shadow: inset 3px 0 0 0 var(--ink);
}

[dir="rtl"] .dashboard-table tbody tr.is-selected {
  box-shadow: inset -3px 0 0 0 var(--ink);
}

.dashboard-table tbody tr.is-selected .table-link {
  color: var(--ink);
}

.dashboard-table tr:last-child td {
  border-bottom: 0;
}

/* A reference is a machine string: mono, and never broken across two lines. */
.buyer-cell-ref .table-link {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: -0.02em;
  white-space: nowrap;
}

/* The controls on a row are one control each, side by side. .row would wrap them
   under column pressure -- and this column is the last of seven in a table with
   a 640px floor, so it is the one under pressure -- which read as two stacked
   buttons rather than as the pair they are. The cell keeps its own width instead. */
.buyer-cell-actions {
  white-space: nowrap;
}

.buyer-cell-actions .row {
  flex-wrap: nowrap;
}

.buyer-cell-title {
  font-weight: 600;
  color: var(--ink);
}

.buyer-cell-mute {
  color: var(--mute);
}

/* A quantity and a UTC stamp are left-to-right runs whatever the page reads
   like. Left to the table's own direction on the Arabic workspace, "2026-07-31
   15:41:00" renders with its time first — every character present, and not the
   moment it says. */
.buyer-cell-num,
.buyer-cell-when {
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--mute);
  white-space: nowrap;
  direction: ltr;
  unicode-bidi: isolate;
}

[dir="rtl"] .buyer-cell-num,
[dir="rtl"] .buyer-cell-when {
  text-align: right;
}

.buyer-load-more {
  margin-block-start: var(--s4);
}

/* ------------------------------------------------------------
   Released offers
   ------------------------------------------------------------ */

.buyer-status-timeline {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin-block-end: var(--s4);
}

/* Where the request has got to, as the rail the operations desk reads. The
   component itself is in the token layer because both surfaces draw it; what
   belongs here is only where it sits on this page and how it scrolls when a
   buyer's column is too narrow to hold ten stages. */
.buyer-stage-rail {
  overflow-x: auto;
  margin-block-end: var(--s4);
}

.buyer-stage-rail .status-rail {
  /* A buyer's card is narrower than a record page, so the floor is lower and
     the stage names take a second line before the rail starts scrolling. */
  grid-auto-columns: minmax(88px, 1fr);
}

.buyer-stage-summary {
  margin-block-start: var(--s4);
}

.timeline-item {
  padding: 5px 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--pill);
  background: var(--surface);
  font-size: 11.5px;
  color: var(--ink-3);
}

.timeline-item.is-empty {
  border-style: dashed;
  border-color: var(--line);
  color: var(--mute-2);
}

.buyer-quote-list {
  display: grid;
  gap: var(--s3);
}

.buyer-quote-card {
  display: grid;
  gap: 6px;
  padding: var(--s4);
  border: 1px solid var(--line);
  border-radius: var(--r3);
  background: var(--surface);
  font-size: 13px;
  color: var(--mute);
}

.buyer-quote-card strong {
  font-size: 13.5px;
  color: var(--ink);
}

.quote-price {
  font-family: var(--mono);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
}

@media (max-width: 620px) {
  .dashboard-command {
    grid-template-columns: 1fr;
  }

  #rfqForm .form-grid,
  #supplierProductForm {
    grid-template-columns: 1fr;
  }

  .dashboard-card {
    padding: var(--s4);
  }
}

/* ------------------------------------------------------------
   Depth
   The system's rule is that depth is structural, not decorative:
   one elevation step, and it means "this sits above that". The
   workspace has three planes and now says so — the field the page
   is on, the cards laid on it, and the two things that float over
   both. Nothing here invents a colour; the shadows are the
   system's own --e1 and --e2, and the lift on hover is 1px.
   ------------------------------------------------------------ */

.workspace-view .dashboard-card {
  box-shadow: var(--e1);
  transition: box-shadow var(--base) var(--ease), transform var(--base) var(--ease);
}

/* A card that answers to a pointer says so by rising, once, by a pixel. A card
   that only holds text does not move: motion that means nothing is noise. */
.workspace-view .dashboard-card:has(.buyer-open-rfq):hover,
.workspace-view .dashboard-card:has(table):hover {
  box-shadow: var(--e2);
}

.buyer-quote-card,
.rfq-review-summary {
  box-shadow: var(--e1);
}

.buyer-quote-card {
  transition: box-shadow var(--base) var(--ease), transform var(--base) var(--ease);
}

.buyer-quote-card:hover {
  box-shadow: var(--e2);
  transform: translateY(-1px);
}

/* The two planes above the page: the bar the workspace hangs from, and the
   rail's drawer when it is over the content rather than beside it. */
.buyer-wrap .app-topbar,
.supplier-wrap .app-topbar {
  box-shadow: var(--e1);
}

/* The journey's own surfaces. The card the questions sit in is the page's
   subject, so it carries the deeper of the two steps; the answer tiles and the
   upload cards lift under a pointer because both are things to press. */
.rq-card {
  box-shadow: var(--e2);
}

.rq-card .choice,
.rq-card .supplier-upload-card {
  transition: box-shadow var(--fast) var(--ease), transform var(--fast) var(--ease);
}

.rq-card .choice:hover,
.rq-card .supplier-upload-card:hover {
  box-shadow: var(--e1);
  transform: translateY(-1px);
}

@media (prefers-reduced-motion: reduce) {
  .workspace-view .dashboard-card,
  .buyer-quote-card,
  .rq-card .choice,
  .rq-card .supplier-upload-card {
    transform: none;
  }
}
