/* ==========================================================================
   ProjectManagementPro.ClientWASM — acceptance criteria
   The screen of the acceptance-criteria artefact — Features/AcceptanceCriteria/** — and the flat list of
   measurable conditions it is the first artefact of the slice to draw.

   It is a sheet of its own because it is the second screen of the archetype family, and the family's first
   sheet is not the same shape: the deliverable hangs from another one of its own rows (`AC-114`), so its list
   is a tree and its table folds; **a criterion has no parent and no level**, so nothing here is indented, no
   row folds and no column carries a depth. What this artefact carries where the neighbour carries a level is
   the two values the server publishes with every row — its category and the method that verifies it.

   Everything else is the family's already approved furniture — a 1px hairline around a white surface, a 12px
   corner, the muted colour for a label — and every value below is a token of tokens.css: nothing here states
   a colour, a size or a distance of its own.

   The classes are the ones these components render:
     * Features/AcceptanceCriteria/AcceptanceCriteriaPage.razor      (.criterion-page, .criterion-figure)
     * Features/AcceptanceCriteria/Components/AcceptanceCriterionList.razor (.criterion-list, .criterion-card)
     * Features/AcceptanceCriteria/Components/AcceptanceCriterionTable.razor (.criterion-table)
     * Features/AcceptanceCriteria/Components/AcceptanceCriterionScope.razor (.criterion-scope)
     * Features/AcceptanceCriteria/Components/AcceptanceCriterionEditorDialog.razor (.criterion-editor,
       .criterion-definition)
     * Features/AcceptanceCriteria/Components/DeleteAcceptanceCriterionDialog.razor (.criterion-delete)
     * Components/Suggestions/SuggestionsPanel.razor                 (.criterion-suggestions)
     * Components/Investments/InvestmentsPanel.razor                 (.criterion-investments)
   ========================================================================== */

/* ==========================================================================
   The page: the head, the figures of the artefact and the two columns
   ========================================================================== */

/* The anchor the page names as its own heading, through the `HeadingClass` it hands to the shared `PageHeader`.
   The head draws the heading; what this sheet owns of it is the margin the head's own title rule leaves, and
   the name the screen's automation addresses it by. El marco de la pagina —la leyenda y su contenido a 2 px— no se
   declara aqui: es el de los catorce artefactos y vive en `layout.css`. */
.criterion-page__title {
  margin: 0;
}

/* The write controls are absent because the server would refuse them, and this sentence says which of the two
   reasons it is: the phase, and the way out of it. */
.criterion-page__note {
  margin: 0 0 var(--space-md);
  color: var(--color-text-muted);
}

/* A failed read is never an empty list: it is a failure, with a way to ask again — the same recovery the three
   shared panels of this screen draw. */
.criterion-page__recovery {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-top: var(--space-sm);
}

.criterion-page__main {
  min-width: 0;
}

.criterion-page__scope {
  min-width: 0;
}

/* The list actions above the list: the action that adds a criterion, which `DEC-090` point 3 puts above the
   list and below the first section of the screen. */
.criterion-page__list-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-bottom: var(--space-md);
}

/* The line that says the project holds no criterion yet. Nothing is paged and nothing is hidden, so the count
   is never a «N of M» (`DEC-W20.3`) and the line states the whole truth. */
.criterion-page__summary {
  margin: 0 0 var(--space-sm);
  color: var(--color-text-muted);
}

/* The three figures the active screen draws in its own row of badges: how many criteria the project has, how
   many of them a test verifies, and how many still hold the phase open. */
.criterion-page__figures {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  margin: 0 0 var(--space-sm);
  padding: 0;
  list-style: none;
}

.criterion-figure {
  padding: var(--space-3xs) var(--space-xs);
  background: var(--color-primary-soft);
  border: var(--border-width) solid var(--color-primary-border);
  border-radius: var(--radius-sm);
  color: var(--color-primary-strong);
  font-size: var(--font-size-sm);
}

/* The item the server holds as complete: drawn plainly. */
.criterion-figure--settled {
  background: var(--color-surface-muted);
  border-color: var(--color-border-strong);
  color: var(--color-text-muted);
}

/* The figure that keeps the phase gate closed is the one emphasised. */
.criterion-figure--warning {
  background: var(--color-accent-soft);
  border-color: var(--color-accent-border);
  color: var(--color-accent);
}

/* The same truth the phase gate refuses the approval with, said where the person can act on it. The shared
   alert draws an outcome and has no warning variant, so this line is the screen's own. */
.criterion-page__incomplete {
  margin: 0 0 var(--space-md);
  padding: var(--space-xs) var(--space-sm);
  background: var(--color-accent-soft);
  border: var(--border-width) solid var(--color-accent-border);
  border-radius: var(--radius-sm);
}

/* ==========================================================================
   The card view — Features/AcceptanceCriteria/Components/AcceptanceCriterionList.razor
   ========================================================================== */

.criterion-list__item {
  display: flex;
  min-width: 0;
}

/* The delete of a table row is the ghost variant the markup chooses, so the danger role is applied by the surface
   that knows what the action does. A card needs no rule: its delete wears `button--danger`, the variant of the
   destructive action, which is what the eight artefacts that painted every ghost button of their card red were
   missing (`DEC-045`). The tables keep this rule until their own delete wears that variant too, and it is why the
   investigations toggle of a collapsed row is still painted with it (`HANDOFF-UI.md` §5.9). */
/* ==========================================================================
   The table view — Features/AcceptanceCriteria/Components/AcceptanceCriterionTable.razor
   ========================================================================== */

/* The table is the view the artefact opens on, and it draws six columns and no tree: the reference, the
   criterion, the two values it carries, the definition state and the actions. */
.criterion-table__wrapper {
  overflow-x: auto;
}

.criterion-table {
  width: 100%;
  border-collapse: collapse;
}

.criterion-table__caption {
  padding-bottom: var(--space-xs);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  text-align: left;
}

.criterion-table th,
.criterion-table td {
  padding: var(--space-sm);
  border-bottom: var(--border-default);
  text-align: left;
  vertical-align: top;
}

.criterion-table thead th {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

/* The two chip columns belong with the reference and the state: what they hold is one word and it must not
   wrap. The width is fixed only for the ref, the state and the actions column — the four widths the reference
   fixes are the same four minus the level, which this artefact does not have — and the criterion column takes
   whatever is left. */
.criterion-table__col-ref,
.criterion-table__col-category,
.criterion-table__col-method,
.criterion-table__col-state {
  white-space: nowrap;
}

.criterion-table__col-ref {
  width: 90px;
}

.criterion-table__col-state {
  width: 150px;
}

/* **The actions are two small buttons and nothing else.** They used to declare 340px, and that width is what left the
   criterion — the only elastic column of the row — as tight as it was: with the owner's rule of 2026-09-27, the small
   data keeps a declared width and **the text takes whatever is left**. */
.criterion-table__col-actions {
  width: 96px;
}

/* **And the text is the last column before the actions.** It is what the row is about, so it takes the room the small
   columns leave: the reference, the two chips and the state are `nowrap` and fixed, and this one wraps and grows. */
.criterion-table__text {
  width: 100%;
}

.criterion-table__row:hover {
  background: var(--color-surface-muted);
}

/* The criterion's own cell. The reference mutes the description because there the description sits under a bold
   name; here the criterion is the column the row is about, so only the wrap is carried over and the colour is
   the page's. */
.criterion-table__text {
  overflow-wrap: anywhere;
}

/* The two cells that carry a chip: they hold the server's own word and nothing of their own. */
.criterion-table__category,
.criterion-table__method {
  white-space: nowrap;
}

.criterion-table__state {
  white-space: nowrap;
}

.criterion-table__actions {
  display: flex;
  flex-wrap: nowrap;
  justify-content: flex-end;
  gap: var(--space-xs);
}

/* The row of investigations a table row opens in place. */
.criterion-table__investigations {
  background: var(--color-surface-muted);
}

/* ==========================================================================
   Section 1 — the suggestions and the decisions
   The shared panel of Components/Suggestions, named `criterion-suggestions` by this artefact
   ========================================================================== */
.criterion-suggestions {
  margin-bottom: var(--space-lg);
  padding: var(--space-md);
  background: var(--color-surface);
  border: var(--border-default);
  border-radius: var(--radius-lg);
}

.criterion-suggestions__title {
  margin: 0 0 var(--space-2xs);
  font-size: var(--font-size-lg);
}

.criterion-suggestions__subtitle {
  margin: var(--space-md) 0 var(--space-2xs);
  font-size: var(--font-size-base);
}

.criterion-suggestions__note {
  margin: 0 0 var(--space-sm);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.criterion-suggestions__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-bottom: var(--space-sm);
}

/* The body of the panel — the proposals and the refusals below them — is drawn inside one element by the shared
   section, so that the artefact that can close it hides it without taking anything out of the document.
   This artefact cannot close it, so the element is transparent to the layout: its children are laid out exactly
   as they were when the body had no wrapper at all. */
.criterion-suggestions__body {
  display: contents;
}

.criterion-suggestions__recovery {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-top: var(--space-sm);
}

.criterion-suggestions__list,
.criterion-suggestions__dismissed,
.criterion-suggestions__refs {
  margin: 0;
  padding: 0;
  list-style: none;
}

.criterion-suggestions__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.criterion-suggestions__item {
  padding: var(--space-sm);
  background: var(--color-surface-muted);
  border: var(--border-default);
  border-radius: var(--radius-sm);
}

/* The kind is the server's own word — `suggestion` or `contradiction` — drawn as it arrived. */
.criterion-suggestions__kind {
  margin: 0 0 var(--space-2xs);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  text-transform: lowercase;
  letter-spacing: 0.02em;
}

.criterion-suggestions__text {
  margin: 0;
  overflow-wrap: anywhere;
}

.criterion-suggestions__refs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  margin-top: var(--space-2xs);
}

.criterion-suggestions__ref {
  padding: 0 var(--space-2xs);
  background: var(--color-primary-soft);
  border: var(--border-width) solid var(--color-primary-border);
  border-radius: var(--radius-sm);
  color: var(--color-primary-strong);
  font-size: var(--font-size-sm);
}

.criterion-suggestions__dismissed {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.criterion-suggestions__dismissed-item {
  padding: var(--space-2xs) 0;
  border-bottom: var(--border-default);
}

/* The reason is the server's own value — who decided the refusal — shown as it arrives. */
.criterion-suggestions__reason {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

/* ==========================================================================
   Section 2 — the investment rows of the criterion the dialog has open
   The shared panel of Components/Investments, named `criterion-investments` by this artefact
   ========================================================================== */

/* The section of the dialog that holds the purchases that exist because of one criterion. It is drawn inside
   the tab the frame owns, so it carries no frame of its own. */
.criterion-investments {
  display: block;
}

.criterion-investments__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xs);
}

.criterion-investments__title {
  margin: 0;
  font-size: var(--font-size-base);
}

.criterion-investments__note {
  margin: var(--space-2xs) 0 var(--space-sm);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.criterion-investments__form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--space-sm);
  margin-bottom: var(--space-md);
  padding: var(--space-sm);
  background: var(--color-surface-muted);
  border: var(--border-default);
  border-radius: var(--radius-sm);
}

/* The description spans the row: it is the sentence of the purchase and it is drawn with the definition field. */
.criterion-investments__form-full {
  grid-column: 1 / -1;
}

.criterion-investments__form-actions {
  display: flex;
  flex-wrap: wrap;
  grid-column: 1 / -1;
  gap: var(--space-xs);
  justify-content: flex-end;
}

.criterion-investments__table-wrapper {
  overflow-x: auto;
}

.criterion-investments__table {
  width: 100%;
  border-collapse: collapse;
}

.criterion-investments__caption {
  padding-bottom: var(--space-xs);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  text-align: left;
}

.criterion-investments__table th,
.criterion-investments__table td {
  padding: var(--space-xs);
  border-bottom: var(--border-default);
  text-align: left;
  vertical-align: top;
}

.criterion-investments__table thead th {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.criterion-investments__row:hover {
  background: var(--color-surface-muted);
}

.criterion-investments__description {
  overflow-wrap: anywhere;
}

/* A row typed before the artefact exists belongs to no investment list yet, and the cell says so. */
.criterion-investments__pending {
  display: block;
  color: var(--color-accent);
  font-size: var(--font-size-sm);
}

.criterion-investments__category,
.criterion-investments__unit {
  white-space: nowrap;
}

.criterion-investments__total {
  white-space: nowrap;
}

/* The total of a row that has not been written yet is the server's to compute, and the cell says that instead of
   multiplying two numbers in the browser. */
.criterion-investments__computed {
  color: var(--color-text-subtle);
  font-size: var(--font-size-sm);
}

.criterion-investments__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-2xs);
}

/* ==========================================================================
   Section 3 — the Scope Builder of the artefact
   Features/AcceptanceCriteria/Components/AcceptanceCriterionScope.razor

/* ==========================================================================
   The dialog of the artefact
   Features/AcceptanceCriteria/Components/AcceptanceCriterionEditorDialog.razor and
   DeleteAcceptanceCriterionDialog.razor
   ========================================================================== */

/* The read of the artefact's published values failed, so nothing is invented and the two fields say so. */
.criterion-editor__recovery {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-top: var(--space-sm);
}

/* The lines the editor writes that are not a control: the save was pressed with a value the server does not
   declare, or the criterion on screen comes from a proposal. */
.criterion-editor__note {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

/* The dialog's own reading of the definition state: the badge and the sentence that explains it. */
.criterion-definition {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2xs);
}

.criterion-definition__badge {
  padding: var(--space-3xs) var(--space-xs);
  border: var(--border-width) solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  font-size: var(--font-size-sm);
  white-space: nowrap;
}

.criterion-definition__badge--warning {
  background: var(--color-accent-soft);
  border-color: var(--color-accent-border);
  color: var(--color-accent);
}

.criterion-definition__badge--settled {
  background: var(--color-success-soft);
  border-color: var(--color-success-border);
  color: var(--color-secondary-strong);
}

.criterion-definition__explanation {
  color: var(--color-text-muted);
}

/* The one notice of the state, in the words of the active screen's own tab. */
.criterion-definition__notice {
  margin: 0;
  padding: var(--space-xs) var(--space-sm);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
}

.criterion-definition__notice--open {
  background: var(--color-accent-soft);
  border-color: var(--color-accent-border);
  color: var(--color-text);
}

.criterion-definition__notice--settled {
  background: var(--color-success-soft);
  border-color: var(--color-success-border);
  color: var(--color-text);
}

/* What goes with the criterion when it is deleted: the server cascades the investigations and the scope
   proposal filed about it, and the row is one the phase gate counts while it is not Defined. */
.criterion-delete__cascade {
  margin: 0 0 var(--space-sm);
  padding: var(--space-xs) var(--space-sm);
  background: var(--color-accent-soft);
  border: var(--border-width) solid var(--color-accent-border);
  border-radius: var(--radius-sm);
}
