/* portfolio.css — owned by WP5 (products / product detail / SDS pages). Only
 * page-specific chrome lives here: the search/filter toolbar, the product-status
 * pill tones, the completeness meter, the product-detail meta row, the SDS
 * "extracting…" card and the per-product SDS sub-list. Everything else (tables,
 * buttons, sections, skeleton/error/empty states) is reused from ui.css /
 * states.css. All colors come from tokens, so dark.css flips them for free; the
 * one literal-navy component (active filter chip) carries its own dark pin below
 * (build-plan §0.6). */

/* ═══════════════════════════ Search / filter toolbar ═══════════════════════════ */

.ct-portfolio-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
}

.ct-search-box {
  position: relative;
  flex: 1 1 240px;
  max-width: 360px;
  min-width: 0;
}
.ct-search-icon {
  position: absolute;
  left: 11px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-subtle);
  pointer-events: none;
}
.ct-search-input {
  width: 100%;
  padding: 9px 12px 9px 34px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: var(--text-base);
}
.ct-search-input::placeholder {
  color: var(--text-subtle);
}
.ct-search-input:focus {
  border-color: var(--focus);
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--focus) 22%, transparent);
}

/* Filter chips (SDS status). Pill toggle group; active chip = filled navy. */
.ct-filter-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.ct-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text-muted);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.ct-chip:hover {
  background: var(--surface-2);
  color: var(--text);
}
.ct-chip.is-active {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}
.ct-chip.is-active:hover {
  background: var(--primary-hover);
  color: #fff;
}

/* ═══════════════════════════ Product-status pill ═══════════════════════════ */

/* Reuses the .status-badge geometry (pill + currentColor dot) from ui.css; these
   classes only paint the tone for the product lifecycle status. */
.ct-status-active {
  background: var(--clear-tint);
  color: var(--clear);
  border-color: var(--clear-edge);
}
.ct-status-archived {
  background: var(--neutral-tint);
  color: var(--text-subtle);
}

/* ═══════════════════════════ Completeness meter ═══════════════════════════ */

.ct-completeness {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}
.ct-completeness-track {
  position: relative;
  flex: 0 0 auto;
  width: 64px;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--surface-3);
  overflow: hidden;
}
.ct-completeness-fill {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--indeterminate);
}
.ct-completeness-fill--complete {
  background: var(--clear);
}
.ct-completeness-fill--partial {
  background: var(--potential);
}
.ct-completeness-fill--unknown {
  background: var(--indeterminate);
}
.ct-completeness-label {
  font-size: var(--text-sm);
  color: var(--text-muted);
  white-space: nowrap;
}

/* ═══════════════════════════ Product-detail meta row ═══════════════════════════ */

.ct-meta-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-6);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.ct-meta-item {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 0;
}
.ct-meta-label {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-subtle);
}
.ct-meta-value {
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--text);
}

/* ═══════════════════════════ SDS "extracting…" card ═══════════════════════════ */

.ct-sds-extracting {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  font-weight: 600;
  color: var(--text-muted);
}

/* Per-product SDS sub-list keeps its skeleton/empty block comfortably inset. */
.ct-portfolio-list {
  min-height: 0;
}
.ct-portfolio-list .ct-skeleton-rows {
  padding: var(--space-3) 0;
}

/* ═══════════════════════════ Dark-mode pins ═══════════════════════════ */

/* The active chip is the only fixed-navy surface here; pin it so it stays a
   readable filled navy in dark mode instead of following the flipped --primary
   token (spec-theme §1.5 primary-inversion trap). */
body.dark-mode .ct-chip {
  background: transparent;
}
body.dark-mode .ct-chip.is-active {
  background: #1f3c54;
  border-color: #1f3c54;
  color: #fff;
}

/* ═══════════════════ Composition completeness (WP-loop) ═══════════════════
   While a product's composition is not `complete` it carries a standing
   indeterminate finding and can never be reported clear. That was previously
   invisible — the user saw "ασαφές" with no stated cause and no way out — so
   the panel names the consequence and, when it is actually permitted, offers
   the action. Deliberately quiet: it is an explanation, not an alarm. */
.ct-completeness-panel {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4);
  margin-bottom: var(--space-4);
  background: var(--potential-tint);
  border: 1px solid var(--potential-edge);
  border-radius: var(--radius-fluid-sm);
  flex-wrap: wrap;
}
.ct-completeness-panel.is-complete {
  background: var(--clear-tint);
  border-color: var(--clear-edge);
}
.ct-completeness-panel-icon {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: var(--radius-pill);
  display: grid;
  place-items: center;
  font-weight: 800;
  font-size: var(--text-sm);
  background: var(--potential);
  color: #fff;
}
.ct-completeness-panel.is-complete .ct-completeness-panel-icon {
  background: var(--clear);
}
.ct-completeness-panel-main {
  flex: 1 1 320px;
  min-width: 0;
}
.ct-completeness-panel-title {
  margin: 0 0 2px;
  font-weight: 700;
  color: var(--text);
}
.ct-completeness-panel-body {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--text-sm);
  max-width: 68ch;
}
.ct-completeness-panel-action {
  flex: 1 1 100%;
}
.ct-completeness-form {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin-top: var(--space-2);
}
.ct-completeness-form input {
  flex: 1 1 260px;
  min-width: 0;
}

/* Supplier cell: name over contact address, since the address is what a
   clarification campaign is actually sent to. */
.ct-meta-stack {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.ct-meta-sub {
  font-size: var(--text-xs);
  color: var(--text-subtle);
  overflow-wrap: anywhere;
}

/* ═══════════════════ Finding evidence ═══════════════════ */
.ct-evidence {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}
.ct-evidence-reason {
  margin: 0;
  color: var(--text);
  font-size: var(--text-sm);
  max-width: 62ch;
}
.ct-evidence-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}
.ct-evidence-chip,
.ct-hcode {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 8px;
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-muted);
  white-space: nowrap;
}
/* An H-code is the hazard itself, so it carries the hazard tone rather than
   sitting in the neutral ramp with the supporting facts. */
.ct-hcode {
  font-family: var(--font-mono);
  font-weight: 700;
  background: var(--confirmed-tint);
  border-color: var(--confirmed-edge);
  color: var(--confirmed);
}
.ct-evidence-chip.is-resolved {
  background: var(--clear-tint);
  border-color: var(--clear-edge);
  color: var(--clear);
}

/* Reference provenance: a "clear" rests on the substance being absent from the
   reference list, which is only sound if the list is the real one. */
.ct-reference-note {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-3);
  background: var(--indeterminate-tint);
  border: 1px solid var(--indeterminate-edge);
  border-radius: var(--radius-fluid-sm);
  font-size: var(--text-sm);
}
.ct-reference-note-title {
  font-weight: 700;
  color: var(--text);
}
.ct-reference-note-body {
  color: var(--text-muted);
  max-width: 70ch;
}
.ct-reference-note-why {
  /* Its own line: which list is provisional is a footnote to the sentence, and
     trailing it inline left it dangling mid-paragraph. */
  flex-basis: 100%;
  font-size: var(--text-xs);
  color: var(--text-subtle);
}

/* Withdrawn findings are history: available, not in the way. */
.ct-resolved-findings,
.ct-add-component {
  margin-top: var(--space-4);
}
.ct-resolved-findings > summary,
.ct-add-component > summary {
  cursor: pointer;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-muted);
  padding: var(--space-2) 0;
}
.ct-resolved-findings > summary:hover,
.ct-add-component > summary:hover {
  color: var(--text);
}

/* ═══════════════════════════ Faceted portfolio (Library WP) ═══════════════════════════
   The portfolio list gained server-side search, facets and sorting. The facet
   rail sits beside the table on wide screens and collapses above it on narrow
   ones, where a sidebar would cost more width than the table can spare. */

.ct-portfolio-layout {
  display: grid;
  grid-template-columns: minmax(190px, 230px) minmax(0, 1fr);
  gap: var(--space-5);
  align-items: start;
}
/* The portfolio page opts out of the shared 1120px column (layout.css keeps
   that default at :where() zero specificity for exactly this): the facet rail
   plus eight columns of real Greek data measure ~1570px, so inside 1120px
   three columns always hid behind the wrapper's scrollbar — even full-screen.
   1600px seats the rail and every column side by side on a wide window. */
.ct-shell .ct-main > #page-root:has(.ct-portfolio-layout) {
  max-width: 1600px;
}
/* The rail only earns its width when the table still has room for its columns
   beside it. Below ~1680px viewport the sidebar + the ~1310px eight-column
   table leave it no honest space, so the filters go above the table instead,
   where they cost height rather than legibility. */
@media (max-width: 1680px) {
  .ct-portfolio-layout {
    grid-template-columns: minmax(0, 1fr);
  }
  .ct-facets {
    /* Horizontal groups read better than a tall stack above a table. */
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--space-4) var(--space-5);
    align-items: flex-start;
  }
  .ct-facets .ct-facet-head {
    flex: 0 0 100%;
  }
  .ct-facet-group {
    min-width: 150px;
  }
  /* In the squeezed band it is the nowrap Greek headers ("ΠΛΗΡΟΤΗΤΑ
     ΣΥΣΤΑΣΗΣ") that force the horizontal scroll — let them wrap to a second
     line before any data column is pushed out of view. */
  .ct-portfolio-list .ct-table thead th {
    white-space: normal;
  }
}

.ct-facets {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 12px);
  background: var(--surface);
}
.ct-facet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}
.ct-facet-heading {
  margin: 0;
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.ct-facet-clear {
  padding: 2px 8px;
  font-size: var(--text-xs, 0.75rem);
}
.ct-facet-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.ct-facet-title {
  margin: 0;
  font-size: var(--text-xs, 0.75rem);
  font-weight: 700;
  color: var(--text-subtle);
}
.ct-facet-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
/* A facet states both its label and how many rows it leads to, so choosing one
   is never a guess that might land on an empty table. */
.ct-facet {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  width: 100%;
  padding: 5px 8px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm, 6px);
  background: transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: var(--text-sm);
  text-align: left;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.ct-facet:hover {
  background: var(--surface-2);
  color: var(--text);
}
.ct-facet.is-active {
  background: var(--primary-soft);
  border-color: var(--primary);
  color: var(--primary);
  font-weight: 700;
}
.ct-facet-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ct-facet-count {
  flex: none;
  font-variant-numeric: tabular-nums;
  color: var(--text-subtle);
}
.ct-facet.is-active .ct-facet-count {
  color: inherit;
}
.ct-facet-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-muted);
  cursor: pointer;
}

/* Sort / field / operator selects in the toolbar. */
.ct-select {
  padding: 8px 10px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm, 6px);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
}
.ct-select:focus-visible {
  outline: none;
  border-color: var(--focus);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--focus) 22%, transparent);
}

/* ═══════════════════════════ Identity + hazard cells ═══════════════════════════ */

.ct-idents {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
}
.ct-ident {
  padding: 2px 6px;
  border-radius: var(--radius-sm, 6px);
  background: var(--surface-2);
  border: 1px solid var(--border);
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: var(--text-xs, 0.75rem);
  color: var(--text-muted);
  white-space: nowrap;
}
/* The UFI is the strongest identity a product carries — tint it so it reads as
   the primary key it is, not as one code among several. */
.ct-ident--ufi {
  background: var(--primary-soft);
  border-color: var(--primary-soft);
  color: var(--primary);
}
.ct-chips {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
}
/* Non-interactive chips inside table cells: same pill, no button affordance. */
.ct-chips .ct-chip {
  padding: 2px 8px;
  font-size: var(--text-xs, 0.75rem);
  font-weight: 600;
  cursor: default;
}
.ct-chip--cmr {
  background: var(--confirmed-tint);
  border-color: var(--confirmed-edge);
  color: var(--confirmed);
}
.ct-chip--button {
  cursor: pointer;
}
.ct-hazard-chips {
  margin-bottom: var(--space-3);
}

/* ═══════════════════════════ Status tones added by the Library WP ═══════════════════════════ */

.ct-status-neutral {
  background: var(--neutral-tint);
  color: var(--text-subtle);
  border-color: var(--border);
}
/* A material change means the supplier moved something the verdict rests on. */
.ct-status-changed {
  background: var(--potential-tint);
  color: var(--potential);
  border-color: var(--potential-edge);
  text-decoration: none;
}
.ct-signal-danger {
  background: var(--confirmed-tint);
  color: var(--confirmed);
  border-color: var(--confirmed-edge);
}
.ct-signal-warning {
  background: var(--potential-tint);
  color: var(--potential);
  border-color: var(--potential-edge);
}
.ct-change-added {
  background: var(--clear-tint);
  color: var(--clear);
  border-color: var(--clear-edge);
}
.ct-change-removed {
  background: var(--confirmed-tint);
  color: var(--confirmed);
  border-color: var(--confirmed-edge);
}
.ct-change-changed {
  background: var(--potential-tint);
  color: var(--potential);
  border-color: var(--potential-edge);
}

/* ═══════════════════════════ Changes / hazards / archive pages ═══════════════════════════ */

.ct-inline-note {
  margin: 0 0 var(--space-3);
  font-size: var(--text-sm);
  color: var(--text-muted);
}
.ct-inline-note.is-ok {
  color: var(--clear);
  font-weight: 600;
}
.ct-inline-note.is-error {
  color: var(--confirmed);
  font-weight: 600;
}
.ct-change-value {
  font-size: var(--text-sm);
}
.ct-hash {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: var(--text-xs, 0.75rem);
  color: var(--text-muted);
}
.ct-coverage {
  margin-top: var(--space-6);
}
.ct-archive-status:empty,
.ct-changes-note:empty {
  display: none;
}

/* ═══════════════════════════ Dark-mode pins (Library WP) ═══════════════════════════ */

body.dark-mode .ct-facets {
  background: var(--surface);
}
body.dark-mode .ct-facet.is-active {
  background: #1f3c54;
  border-color: #2d5877;
  color: #eaf2f8;
}
body.dark-mode .ct-ident--ufi {
  background: #1f3c54;
  border-color: #2d5877;
  color: #cfe2f0;
}

/* The product name is the row's identifier and the thing people scan down, so
   it must not wrap: at nine columns beside the facet rail "Cleaning Agent
   CA-90" broke over three lines and tripled every row's height. The table
   already scrolls horizontally inside .ct-table-scroll. */
.ct-portfolio-list td:first-child,
.ct-portfolio-list th:first-child {
  white-space: nowrap;
}
.ct-portfolio-list .ct-ident {
  white-space: nowrap;
}

/* A row action ("Έλεγχος εξαγόμενων πεδίων") is a link, not prose: squeezed
   into the last column it broke over three cramped lines against the panel
   edge and read as a defect. Keep it on one line — the file-name column is
   the one that wraps. */
.ct-portfolio-list td:last-child > a {
  white-space: nowrap;
}
/* …and the file name genuinely can wrap: an SDS file name is one long
   unbreakable token ("sds_-_PUDRALAC_9663_ver.4_(GR).pdf"), so without a
   break license it dictates the table's minimum width and pushes the action
   column out of the panel instead. */
.ct-portfolio-list .ct-mono {
  overflow-wrap: anywhere;
}
