/* ==========================================================================
   .tp-list — P1.F2.T3 (added Wave 1b, orchestrator-assigned)
   ©2026 Vexstorm Studios – All Rights Reserved

   The stacked counterpart to .tp-table. Same data, different density: a table
   when the reader is comparing rows column by column, a list when each entry is
   read as a unit. The observation explorer uses the card form; the detail page
   uses the plain form for evidence and related records.

   Variants   --cards
   Elements   __item  __item--empty  __eyebrow  __title  __meta
   States     :hover  :focus-within  (cards variant only — a plain list is not
              interactive; only the links inside it are)

   Consumed by observations/explorer.html and observations/detail.html.

   THE LIST IS ALWAYS A <ul> OR <ol>. reset.css strips the markers from any list
   carrying a class, so the semantics have to be restored where they matter:
   the templates keep the element, and a screen reader still announces "list,
   N items", which is the whole reason this is not a stack of <div>s.
   ========================================================================== */

.tp-list {
  display: flex;
  flex-direction: column;
  gap: var(--tp-space-1);
  min-width: 0;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* --------------------------------------------------------------------------
   Items
   -------------------------------------------------------------------------- */

.tp-list__item {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--tp-space-2);
  min-width: 0;
  padding: var(--tp-space-3) 0;
  border-bottom: var(--tp-border-width-hairline) solid var(--tp-color-border-subtle);
  color: var(--tp-color-text-primary);
  /* `anywhere`, NOT `break-word`. The two look identical in a block container
     and are not: only `anywhere` reduces the element's MIN-CONTENT size, and a
     flex item is sized from its min-content width. An evidence URL is one
     unbroken token, so with `break-word` the item refuses to shrink below the
     full string — measured at 320px, a stored URL pushed its item to 634px.
     It produced no scrollbar either, because reset.css hides overflow on
     <html>: the text was simply clipped and unreachable, which is worse than a
     visible overflow because nothing looks wrong. */
  overflow-wrap: anywhere;
}

/* Flex items default to min-width:auto and will not shrink past their content.
   Required alongside the rule above — neither fixes this on its own. */
.tp-list__item > * {
  min-width: 0;
}

.tp-list__item:last-child {
  border-bottom: 0;
}

/* "No evidence attached." — rendered as a real item so the list keeps its
   structure and its accessible count rather than collapsing to nothing. Italic
   and muted, never removed: an empty result is information. */
.tp-list__item--empty {
  display: block;
  color: var(--tp-color-text-muted);
  font-style: italic;
}

/* --------------------------------------------------------------------------
   Item content
   -------------------------------------------------------------------------- */

/* The observation identifier above the subject. Monospace and tabular so a
   column of OBS-2026-000123 values aligns character for character down the
   list, which is what makes them scannable. */
.tp-list__eyebrow {
  flex-basis: 100%;
  color: var(--tp-color-text-muted);
  font-family: var(--tp-font-mono);
  font-size: var(--tp-text-xs);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

.tp-list__title {
  flex-basis: 100%;
  min-width: 0;
  color: var(--tp-color-text-primary);
  font-size: var(--tp-text-lg);
  font-weight: var(--tp-weight-bold);
  line-height: var(--tp-leading-tight);
  overflow-wrap: break-word;
}

/* Supporting facts: type, status, size, relation reason. Secondary weight, but
   never hidden and never truncated — this is where the type and status of a
   record live in the card view, and a moderator scans on exactly those. */
.tp-list__meta {
  min-width: 0;
  color: var(--tp-color-text-muted);
  font-size: var(--tp-text-sm);
  line-height: var(--tp-leading-normal);
}

/* --------------------------------------------------------------------------
   Cards variant — the explorer's result list
   -------------------------------------------------------------------------- */

.tp-list--cards {
  gap: var(--tp-space-3);
}

.tp-list--cards .tp-list__item {
  flex-direction: column;
  align-items: stretch;
  gap: var(--tp-space-2);
  padding: var(--tp-space-5);
  border: var(--tp-border-width-hairline) solid var(--tp-color-border-subtle);
  border-radius: var(--tp-radius-lg);
  background-color: var(--tp-color-surface-raised);
}

.tp-list--cards .tp-list__item:hover {
  border-color: var(--tp-color-border-default);
}

/* The card's only focusable element is the title link. Echoing its ring on the
   card edge shows which card the focus belongs to, which a 2px ring around a
   line of text inside a large card does not communicate on its own. */
.tp-list--cards .tp-list__item:focus-within {
  border-color: var(--tp-color-border-focus);
}

.tp-list--cards .tp-list__item--empty {
  border-style: dashed;
  background-color: transparent;
  text-align: center;
  padding: var(--tp-space-8) var(--tp-space-5);
}
