.library {
  display: flex;
  flex-direction: column;
  height: 100%;
  /* Size-query container so the Create CTA can respond to the pane's own width.
     `inline-size` (not `size`) leaves block-size uncontained, so the metadata
     panel's percentage max-height and the list's flex height still resolve. */
  container-type: inline-size;
}

/* Library toolbar — heading + date-format settings gear (spec §02 / §07). */
.toolbar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  height: 40px;
  padding: 0 var(--space-2) 0 var(--space-4);
  border-bottom: var(--border-width) solid var(--border);
}

.heading {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

/* The creation surface: primary Build Chart beside the ghost New-JSON action
   (spec §02). One row, the primary takes the slack. */
.createRow {
  flex: 0 0 auto;
  display: flex;
  gap: var(--space-2);
  margin: var(--space-4);
}

/* Both creators are the shared Button primitive (primary / secondary, lg);
   locally they only divide the row's width. */
.createNew {
  flex: 1 1 auto;
}

.createGhost {
  flex: 0 1 auto;
}

/* Two-stage label collapse as the pane narrows: the long ghost label goes first
   (its icon + title still name it), then below the tight threshold the primary's
   label too — both buttons stay side by side with large targets. The lower
   threshold sits comfortably above the 216px pane minimum. */
@container (max-width: 340px) {
  .createGhost .createNewLabel {
    display: none;
  }
}

@container (max-width: 250px) {
  .createNewLabel {
    display: none;
  }
}

/* Search + Sort row, pinned above the list (spec §02). */
.controls {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0 var(--space-4) var(--space-4);
}

/* Carbon active-search: leading magnifier, optional trailing clear (council). */
.search {
  flex: 1 1 auto;
  min-width: 0;
  position: relative;
  display: flex;
  align-items: center;
}

.searchIcon {
  position: absolute;
  left: var(--space-3);
  color: var(--text-secondary);
  pointer-events: none;
}

.searchInput {
  width: 100%;
  /* Let the input shrink with its flex slot: an <input>'s default min-width is its
     intrinsic content width (~20ch), which otherwise overflowed the slot and slid
     over the Sort trigger at the pane minimum. */
  min-width: 0;
  height: var(--control-height);
  /* Room for the leading magnifier and the trailing clear button. */
  padding: 0 32px 0 32px;
  font-size: 13px;
}

/* Hide the browser's native search clear so we control the affordance. */
.searchInput::-webkit-search-cancel-button {
  appearance: none;
}

/* The clear affordance is a shared IconButton (sm — nested inside the 32px
   field); locally it is only pinned to the input's trailing edge. */
.searchClear {
  position: absolute;
  right: var(--space-2);
}

/* Visually-hidden live region for the search result count (council SEARCH). */
.srOnly {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.list {
  list-style: none;
  margin: 0;
  padding: 0;
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  border-top: var(--border-width) solid var(--border);
}

/* Empty states (spec §02; council EMPTY STATES) — a title + a one-line hint,
   positive and concise. Two variants share this layout: an empty library and a
   search with no matches. */
.empty {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  color: var(--text-secondary);
  font-size: 13px;
  padding: var(--space-5) var(--space-4);
}

.emptyTitle {
  font-weight: 600;
  color: var(--text);
}

.emptyHint {
  color: var(--text-secondary);
}

.item {
  display: flex;
  align-items: stretch;
  gap: var(--space-3);
  padding: 0 var(--space-4);
  border-left: 2px solid transparent;
  transition: background var(--dur-fast) var(--ease);
}

.item + .item {
  border-top: var(--border-width) solid var(--border);
}

.item:hover {
  background: var(--layer-01);
}

.active {
  background: var(--layer-01);
  border-left-color: var(--accent);
}

.itemMain {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-1);
  /* A real <button> for keyboard selection — strip the native chrome and let
     the row's own padding live here so the click target fills the row height. */
  appearance: none;
  border: none;
  background: none;
  padding: var(--space-3) 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

.name {
  display: block;
  max-width: 100%;
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Secondary metadata line (spec §02): status indicator · relative date · size. */
.sub {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* Fixed-width leading slot for the status indicator. Always present (even when a
   snippet is published and shows no dot) so the date never shifts and rows stay
   aligned with one another. */
.indicator {
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
}

/* Unpublished-draft indicator (spec §02 status; arch/10 §6 + council). The accent
   hue — not a warning colour, since unpublished work is a normal state — and the
   meaning rides on presence/absence + the accessible label, never colour alone. */
.draftDot {
  /* display:block so the 6px box applies — an inline span with no text content
     would ignore width/height and collapse to nothing. */
  display: block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}

.date {
  min-width: 0;
  font-size: 11px;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Linked-datasets indicator (spec §02): icon + count, meaning carried by the
   icon + accessible label, not colour. Sits inline with the date as one grouped
   metadata run, separated by a middot, rather than orphaned at the row's edge. */
.datasets {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: 12px;
  color: var(--text-secondary);
}

.datasets::before {
  content: '·';
  margin-right: var(--space-2);
  color: var(--text-placeholder);
}

/* Row trash — a shared IconButton (sm); locally it only handles the row-hover
   reveal and the destructive hover colour. */
.delete {
  align-self: center;
  opacity: 0;
  transition:
    opacity var(--dur-fast) var(--ease),
    background var(--dur-fast) var(--ease),
    color var(--dur-fast) var(--ease);
}

.item:hover .delete,
.item .delete:focus-visible {
  opacity: 1;
}

/* Destructive intent reddens on hover AND keyboard focus, not colour-by-mouse-only
   (arch 10 — destructive controls signal danger on hover/focus). The .item prefix
   outranks the IconButton primitive's own hover colour. */
.item .delete:hover,
.item .delete:focus-visible {
  color: var(--support-error);
}

/* Selected-Snippet Metadata Panel (spec §02) — pinned below the list, the active
   snippet's editable Name/Comment, read-only timestamps, linked datasets, and
   Duplicate/Delete. Capped height with its own scroll so a long comment never
   pushes the list away entirely. */
.meta {
  flex: 0 0 auto;
  max-height: 45%;
  overflow: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  border-top: var(--border-width) solid var(--border);
  background: var(--layer-01);
  /* The panel sits on --layer-01, so its controls' hover fill and its fields'
     fill both step off this surface, not the canvas. */
  --control-hover-fill: var(--layer-02);
  --field: var(--field-02);
  --field-hover: var(--field-hover-02);
}

.metaField {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.metaLabel {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

.metaName,
.metaComment {
  width: 100%;
  padding: var(--space-2) var(--space-3);
  font-size: 13px;
}

.metaName {
  height: var(--control-height);
  padding: 0 var(--space-3);
  font-weight: 500;
}

.metaComment {
  resize: vertical;
  min-height: 2.4em;
  line-height: 1.4;
}

/* Read-only Created / Modified, as compact label→value rows. */
.metaTimes {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.metaTimes > div {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  font-size: 11px;
}

.metaTimes dt {
  color: var(--text-secondary);
}

.metaTimes dd {
  margin: 0;
  color: var(--text);
  white-space: nowrap;
}

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

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

.linkedItem {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: 12px;
  color: var(--text-secondary);
}

.linkedName {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.metaActions {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-1);
}

/* Shared Buttons (secondary / danger-outline); locally they only split the row. */
.metaAction {
  flex: 1 1 auto;
}
