:root {
  --catalog-success: #24a36a;
  --catalog-success-bg: rgba(36, 163, 106, 0.12);
  --catalog-warning: #c47a12;
  --catalog-warning-bg: rgba(196, 122, 18, 0.12);
  --catalog-danger: #d64d55;
  --catalog-danger-bg: rgba(214, 77, 85, 0.12);
  --catalog-info-bg: rgba(74, 125, 255, 0.1);
  --catalog-row-hover: rgba(74, 125, 255, 0.06);
  --catalog-sticky: #191c26;
  --catalog-control: #202431;
}

[data-theme="light"] {
  --catalog-success: #14784a;
  --catalog-success-bg: #e8f7ef;
  --catalog-warning: #9a5b06;
  --catalog-warning-bg: #fff6df;
  --catalog-danger: #b4232c;
  --catalog-danger-bg: #fff0f1;
  --catalog-info-bg: #eef3ff;
  --catalog-row-hover: #f4f7ff;
  --catalog-sticky: #ffffff;
  --catalog-control: #ffffff;
}

html {
  scroll-padding-top: 112px;
}

body {
  min-width: 320px;
}

body.drawer-open {
  overflow: hidden;
}

button,
input,
select,
textarea {
  letter-spacing: 0;
}

button:focus-visible,
a:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* The header is the shared one from style.css, same as every other page.
   Catalog access lives with the catalog: at the end of its title row. */
.catalog-account {
  align-self: center;
  margin-inline-start: auto;
  padding: 8px 18px;
  white-space: nowrap;
}

.catalog-page {
  min-height: calc(100vh - 89px);
  padding: 12px 0 28px;
  border-bottom: 0;
}

.catalog-container {
  width: min(100%, 1600px);
  margin: 0 auto;
  padding: 0 24px;
}

.breadcrumbs {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 28px;
  margin-bottom: 20px;
  color: var(--text-muted);
  font-family: "IBM Plex Mono", monospace;
  font-size: 12px;
}

.text-button {
  border: 0;
  background: transparent;
  color: var(--accent);
  font: inherit;
  font-weight: 500;
  padding: 2px;
  cursor: pointer;
}

.text-button:hover {
  color: var(--accent-hover);
}

.catalog-title-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 32px;
}

.catalog-title-compact {
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: flex-start;
  column-gap: 16px;
  row-gap: 2px;
  margin-block: 6px 14px;
}

.catalog-title-row.catalog-title-compact h1 {
  margin: 0;
  font-size: 26px;
  font-weight: 600;
  line-height: 1.2;
}

.catalog-lead {
  margin: 0;
  color: var(--text-dim);
  font-size: 14px;
  line-height: 1.4;
}

.catalog-lead .is-stale {
  color: var(--catalog-warning);
  cursor: help;
}

.catalog-title-row h1 {
  max-width: 850px;
  margin: 0 0 10px;
  font-size: 38px;
  letter-spacing: 0;
}

.catalog-title-row p {
  max-width: 760px;
  margin: 0;
  font-size: 16px;
}

.catalog-title-row .eyebrow {
  margin-bottom: 10px;
}

.catalog-title-actions {
  display: flex;
  flex: 0 0 auto;
  gap: 10px;
  padding-bottom: 3px;
}

.catalog-title-actions .btn {
  min-height: 42px;
}

/* Server-side summary inserted by nginx SSI (spec 9.1): the text a crawler
   reads. It stays in the HTML but is collapsed under the table behind one
   quiet line, so a person sees the table and nothing else. */
.catalog-summary {
  max-width: 110ch;
  margin-block: 16px 0;
  color: var(--text-muted);
  font-size: 12.5px;
  line-height: 1.6;
}

.catalog-summary > summary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  list-style: none;
  transition: color 0.15s ease;
}

.catalog-summary > summary::-webkit-details-marker {
  display: none;
}

.catalog-summary > summary::before {
  content: "";
  inline-size: 5px;
  block-size: 5px;
  border-inline-end: 1.5px solid currentColor;
  border-block-end: 1.5px solid currentColor;
  transform: rotate(-45deg);
  transition: transform 0.15s ease;
}

.catalog-summary[open] > summary::before {
  transform: rotate(45deg);
}

.catalog-summary > summary:hover {
  color: var(--text);
}

.catalog-summary > :not(summary) {
  margin-block: 0;
}

.catalog-summary > p {
  margin-block-start: 8px;
}

.catalog-summary h3,
.catalog-summary ul,
.catalog-summary li {
  display: inline;
  margin: 0;
  padding: 0;
  font-size: inherit;
  font-weight: 400;
  list-style: none;
}

.catalog-summary h3 {
  color: var(--text);
}

.catalog-summary h3::after {
  content: ": ";
}

.catalog-summary li + li::before {
  content: "\00b7\00a0";
}

.catalog-summary ul::after {
  content: "\A";
  white-space: pre;
}

@media (prefers-reduced-motion: reduce) {
  .catalog-summary > summary,
  .catalog-summary > summary::before {
    transition: none;
  }
}

.catalog-toolbar {
  display: grid;
  grid-template-columns: minmax(280px, 1fr) auto auto;
  align-items: center;
  gap: 8px;
  margin-block: 0 10px;
}

.catalog-toolbar .search-control input {
  height: 38px;
}

.catalog-toolbar .search-mark {
  top: 11px;
}

.catalog-toolbar .preset-control {
  min-height: 38px;
}

.catalog-toolbar .preset-button {
  min-height: 30px;
  padding: 5px 10px;
}

.search-control {
  position: relative;
  display: block;
  min-width: 0;
}

.search-control input {
  width: 100%;
  height: 42px;
  padding: 9px 14px 9px 40px;
  background: var(--catalog-control);
}

.search-mark {
  position: absolute;
  top: 13px;
  left: 15px;
  z-index: 1;
  width: 13px;
  height: 13px;
  border: 1.5px solid var(--text-muted);
  border-radius: 50%;
  pointer-events: none;
}

.search-mark::after {
  content: "";
  position: absolute;
  right: -5px;
  bottom: -3px;
  width: 6px;
  height: 1.5px;
  background: var(--text-muted);
  transform: rotate(45deg);
  transform-origin: left center;
}

.preset-control,
.status-tabs {
  display: inline-flex;
  align-items: center;
  min-height: 42px;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--input-bg);
}

.preset-button,
.status-tab {
  min-height: 34px;
  padding: 7px 12px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--text-dim);
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
}

.preset-button:hover,
.status-tab:hover {
  color: var(--text);
}

.preset-button.active,
.status-tab.active {
  background: var(--bg-card);
  color: var(--text);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
}

[data-theme="light"] .preset-button.active,
[data-theme="light"] .status-tab.active {
  background: #ffffff;
}

.toolbar-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
}

.tool-button,
.page-button,
.icon-button,
.small-action {
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--catalog-control);
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
}

.tool-button {
  min-height: 42px;
  padding: 9px 13px;
  white-space: nowrap;
}

.catalog-toolbar .tool-button {
  min-height: 38px;
  padding: 7px 10px;
}

.primary-tool-button {
  border-color: var(--accent);
  background: var(--accent);
  color: #ffffff;
}

/* Two classes, so the generic .tool-button:hover below cannot repaint the
   label in the accent colour on top of the accent background. */
.tool-button.primary-tool-button:hover {
  border-color: var(--accent-hover);
  background: var(--accent-hover);
  color: #ffffff;
}

.tool-button:hover,
.page-button:hover,
.icon-button:hover,
.small-action:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.tool-button:disabled,
.page-button:disabled,
.small-action:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  border-color: var(--border);
  color: var(--text-muted);
}

.button-count {
  display: inline-flex;
  min-width: 18px;
  height: 18px;
  align-items: center;
  justify-content: center;
  margin-left: 4px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--code-bg);
  color: var(--accent);
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
}

.active-filter-row {
  display: flex;
  min-height: 30px;
  align-items: center;
  gap: 7px;
  overflow-x: auto;
  padding: 1px 0 6px;
}

.active-filter-row:empty {
  display: none;
}

.filter-chip {
  display: inline-flex;
  min-height: 28px;
  align-items: center;
  gap: 7px;
  flex: 0 0 auto;
  padding: 5px 9px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--input-bg);
  color: var(--text-dim);
  font-size: 12px;
}

.filter-chip strong {
  color: var(--text);
  font-weight: 500;
}

.filter-chip button {
  border: 0;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
}

.selection-bar {
  display: flex;
  min-height: 42px;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
  padding: 8px 12px;
  border: 1px solid var(--accent);
  border-radius: 6px;
  background: var(--catalog-info-bg);
  color: var(--text-dim);
  font-size: 13px;
}

.selection-bar[hidden] {
  display: none;
}

.selection-bar > div {
  display: flex;
  align-items: center;
  gap: 12px;
}

.selection-bar .tool-button {
  min-height: 32px;
  padding: 5px 12px;
}

.catalog-table-frame {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--dataset-bg);
}

.catalog-table-scroll {
  width: 100%;
  overflow: auto;
  overscroll-behavior: contain;
}

.catalog-table-scroll {
  min-height: 420px;
  /* The viewport minus the shared header, the title row, the toolbar and the footer. */
  max-height: calc(100svh - 241px);
}

.catalog-table {
  width: max-content;
  min-width: 100%;
  margin: 0;
  table-layout: fixed;
  border-collapse: separate;
  border-spacing: 0;
}

/* Rows are separated by hairlines only: vertical rules on every cell made the
   table read as a spreadsheet grid and pushed the values apart. */
.catalog-table th,
.catalog-table td {
  height: 42px;
  padding: 8px 14px;
  border-bottom: 1px solid var(--border);
  font-size: 14px;
  line-height: 1.35;
  vertical-align: middle;
}

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

.catalog-table th {
  position: sticky;
  top: 0;
  z-index: 4;
  height: 44px;
  padding-block: 4px;
  padding-inline: 12px;
  background: var(--table-header-bg);
  color: var(--text-dim);
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.25;
  text-transform: none;
  letter-spacing: 0;
}

.catalog-table tbody tr {
  cursor: pointer;
}

@media (hover: hover) and (pointer: fine) {
  .catalog-table tbody tr:hover td {
    background: var(--catalog-row-hover);
  }
}

.catalog-table td {
  overflow: hidden;
  color: var(--text);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.catalog-table td.centered {
  text-align: center;
}

.catalog-table td.numeric {
  font-variant-numeric: tabular-nums;
}

.cell-empty {
  color: var(--text-muted);
}

.catalog-table td.wrap-cell {
  line-height: 1.35;
  white-space: normal;
}

.sticky-select,
.sticky-repo {
  position: sticky !important;
  background: var(--catalog-sticky) !important;
}

/* The corner cells stick both ways, so they sit above the sticky body cells
   that scroll under them; at an equal z-index the later rows paint on top. */
th.sticky-select,
th.sticky-repo {
  z-index: 8 !important;
  background: var(--table-header-bg) !important;
}

.sticky-select {
  inset-inline-start: 0;
  z-index: 6 !important;
  width: 44px;
  min-width: 44px;
  max-width: 44px;
  padding-inline: 0 !important;
  text-align: center !important;
}

.sticky-repo {
  inset-inline-start: 44px;
  z-index: 5 !important;
  padding-inline-start: 2px !important;
  box-shadow: 1px 0 0 var(--border);
}

@media (hover: hover) and (pointer: fine) {
  .catalog-table tbody tr:hover .sticky-select,
  .catalog-table tbody tr:hover .sticky-repo {
    /* The hover tint is translucent in the dark theme; a sticky cell must stay opaque. */
    background: linear-gradient(var(--catalog-row-hover), var(--catalog-row-hover)), var(--catalog-sticky) !important;
  }
}

/* The shortlist star lives inside the Repo ID cell, at its far end. On a
   pointer device it shows on the hovered or focused row and stays shown once
   the row is starred; on touch it is always there. */
.repo-cell {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.repo-cell .cell-primary {
  min-width: 0;
  overflow: clip;
  text-overflow: ellipsis;
}

.checkbox-hit-area {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  cursor: pointer;
}

.catalog-checkbox,
.column-option input {
  width: 16px;
  height: 16px;
  margin: 0;
  padding: 0;
  accent-color: var(--accent);
  cursor: pointer;
}

.star-button {
  display: inline-grid;
  flex: 0 0 auto;
  place-items: center;
  width: 28px;
  height: 28px;
  margin-inline-start: auto;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
}

.star-button svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linejoin: round;
}

.star-button.active {
  color: var(--accent);
}

.star-button.active svg {
  fill: currentColor;
}

.star-button:active {
  background: var(--catalog-info-bg);
}

@media (hover: hover) and (pointer: fine) {
  .star-button:not(.active) {
    opacity: 0;
  }

  .catalog-table tbody tr:hover .star-button,
  .catalog-table tbody tr:focus-within .star-button,
  .star-button:focus-visible {
    opacity: 1;
  }

  .star-button:hover {
    color: var(--accent);
    background: var(--catalog-info-bg);
  }
}

.column-head {
  display: flex;
  width: 100%;
  min-width: 0;
  align-items: center;
  gap: 4px;
}

/* Header labels wrap to two lines instead of being cut, and the sort arrow
   shows only on the sorted column. The filter icon is pinned to the cell's
   end edge, out of the flow, so a centred label is centred on the whole
   column; the end padding keeps the label clear of the icon. Values are
   centred under centred headers, except Repo ID and long truncated text. */
.catalog-table th {
  padding-inline-end: 30px;
}

.catalog-table th.centered {
  padding-inline-start: 30px;
}

.catalog-table th .column-filter-button {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-end: 6px;
  translate: 0 -50%;
}

.sort-button {
  display: flex;
  min-width: 0;
  flex: 1 1 auto;
  min-height: 28px;
  align-items: center;
  justify-content: flex-start;
  gap: 4px;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: start;
  cursor: pointer;
}

.sort-button > span:first-child {
  min-width: 0;
  text-wrap: balance;
}

.sort-mark:empty {
  display: none;
}

.catalog-table th.centered .sort-button {
  justify-content: center;
  text-align: center;
}

.column-filter-button {
  display: inline-flex;
  width: 24px;
  height: 24px;
  flex: 0 0 24px;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 5px;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
}

.column-filter-button svg {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.column-filter-button[aria-expanded="true"] {
  border-color: var(--border);
  background: var(--catalog-control);
  color: var(--text);
}

@media (hover: hover) and (pointer: fine) {
  .column-filter-button:hover {
    border-color: var(--border);
    background: var(--catalog-control);
    color: var(--text);
  }

  /* The icon keeps its place so nothing shifts when it appears. */
  .column-filter-button:not(.active):not([aria-expanded="true"]) {
    opacity: 0;
  }

  .catalog-table th:hover .column-filter-button,
  .catalog-table th:focus-within .column-filter-button {
    opacity: 1;
  }
}

.column-filter-button.active {
  border-color: var(--accent);
  background: var(--catalog-info-bg);
  color: var(--accent);
}

.sort-mark {
  flex: 0 0 auto;
  color: var(--text-muted);
  font-size: 12px;
}

.sort-button.active {
  color: var(--text);
}

.sort-button.active .sort-mark {
  color: var(--accent);
}

.column-filter-popover {
  position: fixed;
  z-index: 320;
  display: grid;
  width: min(340px, calc(100vw - 24px));
  max-height: min(620px, calc(100dvh - 24px));
  grid-template-rows: auto auto auto auto minmax(150px, 1fr) auto auto;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  box-shadow: 0 20px 56px rgba(0, 0, 0, 0.3);
}

.column-filter-popover.is-shortlist {
  grid-template-rows: repeat(3, auto);
}

.column-filter-popover.is-shortlist .column-filter-footer { display: none; }

#columnShortlistHint { font-size: 12px; margin-block: 0 8px; }
#columnShortlistFilter { padding-block-end: 12px; }

.column-filter-popover.is-range {
  grid-template-rows: repeat(4, auto);
}

.column-filter-popover[hidden] {
  display: none;
}

.column-filter-header {
  display: flex;
  min-height: 66px;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
}

.column-filter-kicker {
  display: block;
  margin-bottom: 3px;
  color: var(--text-muted);
  font-family: "IBM Plex Mono", monospace;
  font-size: 9px;
  font-weight: 500;
  text-transform: uppercase;
}

.column-filter-header h2 {
  max-width: 250px;
  margin: 0;
  overflow: hidden;
  color: var(--text);
  font-size: 16px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.column-sort-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}

.column-sort-actions button {
  display: flex;
  min-width: 0;
  min-height: 42px;
  align-items: center;
  gap: 8px;
  padding: 7px 9px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--input-bg);
  color: var(--text-dim);
  font-family: inherit;
  font-size: 10px;
  cursor: pointer;
}

.column-sort-actions button:hover {
  border-color: var(--accent);
  color: var(--text);
}

.column-sort-actions button > span:first-child {
  color: var(--accent);
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  font-weight: 600;
  white-space: nowrap;
}

.column-filter-search {
  padding: 10px 12px 6px;
}

.column-filter-search[hidden],
.column-value-tools[hidden],
.column-value-list[hidden] {
  display: none;
}

.column-filter-search .range-row label {
  min-inline-size: 0;
  color: var(--text-dim);
  font-size: 12px;
}

.column-filter-search .search-control input {
  height: 38px;
}

.column-value-tools {
  display: flex;
  min-height: 36px;
  align-items: center;
  gap: 12px;
  padding: 2px 12px 8px;
  border-bottom: 1px solid var(--border);
}

.column-value-tools .text-button {
  font-size: 11px;
}

.column-value-tools > span {
  min-width: 0;
  margin-left: auto;
  overflow: hidden;
  color: var(--text-muted);
  font-size: 10px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.column-value-list {
  min-height: 150px;
  overflow-y: auto;
  padding: 5px 0;
}

.column-value-option {
  display: grid;
  min-height: 36px;
  grid-template-columns: 18px minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  color: var(--text-dim);
  font-size: 11px;
  cursor: pointer;
}

.column-value-option:hover {
  background: var(--catalog-row-hover);
}

.column-value-option input {
  width: 15px;
  height: 15px;
  margin: 0;
  padding: 0;
  accent-color: var(--accent);
}

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

.column-value-count {
  color: var(--text-muted);
  font-family: "IBM Plex Mono", monospace;
  font-size: 9px;
  font-variant-numeric: tabular-nums;
}

.column-value-empty {
  padding: 24px 14px;
  color: var(--text-muted);
  font-size: 11px;
  text-align: center;
}

.column-value-note {
  margin: 0;
  padding: 7px 12px;
  border-top: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 9px;
}

.column-value-note[hidden] {
  display: none;
}

.column-filter-footer {
  display: flex;
  min-height: 60px;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  padding: 10px 12px;
  border-top: 1px solid var(--border);
}

.column-filter-footer .btn {
  min-width: 88px;
  padding: 9px 14px;
}

.cell-primary {
  color: var(--text);
  font-weight: 500;
}

.cell-mono {
  font-family: "IBM Plex Mono", monospace;
  font-size: 13px;
}

/* A value that reads as good / middling / bad gets a coloured dot before
   plain text: the colour carries the signal without a pill around every cell. */
.status-mark {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.status-mark::before {
  content: "";
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--text-muted);
}

.status-mark.success::before {
  background: var(--catalog-success);
}

.status-mark.warning::before {
  background: var(--catalog-warning);
}

.status-mark.danger::before {
  background: var(--catalog-danger);
}

.status-pill {
  display: inline-flex;
  min-height: 22px;
  align-items: center;
  padding: 3px 7px;
  border-radius: 5px;
  background: var(--code-bg);
  color: var(--text-dim);
  font-size: 10px;
  font-weight: 500;
  line-height: 1.2;
}

.status-pill.success {
  background: var(--catalog-success-bg);
  color: var(--catalog-success);
}

.status-pill.warning {
  background: var(--catalog-warning-bg);
  color: var(--catalog-warning);
}

.status-pill.danger {
  background: var(--catalog-danger-bg);
  color: var(--catalog-danger);
}

.quota-note {
  color: var(--text-dim);
  font-size: 12px;
  white-space: nowrap;
}

.quota-note[hidden] {
  display: none;
}

.table-footer {
  display: flex;
  min-height: 54px;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 8px 12px;
  border-top: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 13px;
}

.table-footer[hidden] {
  display: none;
}

.table-footer > div:first-child {
  display: flex;
  gap: 8px;
}

.table-footer strong {
  color: var(--text);
  font-weight: 500;
}

.styled-select {
  height: 32px;
  min-width: 64px;
  padding: 5px 28px 5px 9px;
  border: 1px solid var(--border);
  border-radius: 6px;
  appearance: none;
  background-color: var(--catalog-control);
  background-image:
    linear-gradient(45deg, transparent 50%, var(--text-muted) 50%),
    linear-gradient(135deg, var(--text-muted) 50%, transparent 50%);
  background-position:
    calc(100% - 13px) 13px,
    calc(100% - 9px) 13px;
  background-repeat: no-repeat;
  background-size: 4px 4px, 4px 4px;
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
}

.page-button,
.icon-button {
  display: inline-flex;
  width: 32px;
  height: 32px;
  align-items: center;
  justify-content: center;
  padding: 0;
}

.icon-button {
  border-color: transparent;
  background: transparent;
  font-size: 24px;
  font-weight: 300;
}

.table-empty {
  display: flex;
  min-height: 420px;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  padding: 40px 24px;
  text-align: center;
}

.table-empty[hidden] {
  display: none;
}

.table-empty h2 {
  margin-bottom: 8px;
  font-size: 22px;
}

.table-empty p {
  margin-bottom: 18px;
}

/* Пока каталог грузится, таблицы в рамке нет, и абсолютный оверлей схлопнулся
   бы в ноль высоты — держим рамку открытой на высоту скелета. */
.catalog-table-frame.is-loading {
  min-height: 420px;
}

.table-error-detail {
  color: var(--text-muted);
  font-family: "IBM Plex Mono", monospace;
  font-size: 12px;
}

.table-loading {
  position: absolute;
  inset: 0 0 54px;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 70px 24px;
  background: color-mix(in srgb, var(--dataset-bg) 92%, transparent);
}

.table-loading[hidden] {
  display: none;
}

.loading-line {
  width: 100%;
  height: 38px;
  border-radius: 4px;
  background: linear-gradient(90deg, var(--bg-alt), var(--border), var(--bg-alt));
  background-size: 240% 100%;
  animation: loading-shimmer 1.2s linear infinite;
}

@keyframes loading-shimmer {
  to { background-position: -240% 0; }
}

.drawer-backdrop {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(8, 10, 16, 0.54);
  opacity: 1;
}

.drawer-backdrop[hidden] {
  display: none;
}

.side-drawer {
  position: fixed;
  top: 0;
  right: 0;
  z-index: 210;
  display: grid;
  width: min(470px, 100vw);
  height: 100dvh;
  grid-template-rows: auto auto minmax(0, 1fr) auto;
  border-left: 1px solid var(--border);
  background: var(--bg);
  box-shadow: -20px 0 60px rgba(0, 0, 0, 0.24);
  transform: translateX(102%);
  transition: transform 180ms ease;
}

.side-drawer.detail-drawer {
  grid-template-rows: auto minmax(0, 1fr) auto;
  width: min(560px, 100vw);
}

.side-drawer.open {
  transform: translateX(0);
}

.drawer-header {
  display: flex;
  min-height: 84px;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 18px 20px;
  border-bottom: 1px solid var(--border);
}

.drawer-header .eyebrow {
  margin-bottom: 5px;
}

.drawer-header h2 {
  margin: 0;
  font-size: 24px;
  overflow-wrap: anywhere;
}

.drawer-search {
  padding: 12px 20px;
  border-bottom: 1px solid var(--border);
}

.drawer-search input {
  width: 100%;
  height: 40px;
  padding: 9px 12px;
}

.drawer-body {
  min-height: 0;
  overflow-y: auto;
  padding: 16px 20px 24px;
}

.drawer-footer {
  display: flex;
  min-height: 68px;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  padding: 12px 20px;
  border-top: 1px solid var(--border);
  background: var(--bg);
}

.drawer-footer .btn {
  min-width: 112px;
}

.filter-group {
  border-bottom: 1px solid var(--border);
}

.filter-group:last-child {
  border-bottom: 0;
}

.filter-group > summary {
  display: flex;
  min-height: 48px;
  align-items: center;
  justify-content: space-between;
  color: var(--text);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  list-style: none;
}

.filter-group > summary::-webkit-details-marker {
  display: none;
}

.filter-group > summary::after {
  content: "+";
  color: var(--text-muted);
  font-size: 18px;
}

.filter-group[open] > summary::after {
  content: "-";
}

.filter-controls {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 2px 0 18px;
}

.filter-control {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.filter-control > label,
.filter-control-title {
  color: var(--text-dim);
  font-size: 12px;
  font-weight: 500;
}

.filter-unavailable {
  display: block;
  color: var(--text-muted);
  font-size: 12px;
  line-height: 1.4;
}

.range-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.range-row input,
.text-filter-input {
  width: 100%;
  height: 38px;
  padding: 8px 10px;
}

.option-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.option-chip {
  min-height: 30px;
  padding: 5px 9px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--input-bg);
  color: var(--text-dim);
  font-family: inherit;
  font-size: 11px;
  cursor: pointer;
}

.option-chip:hover {
  border-color: var(--accent);
}

.option-chip.active {
  border-color: var(--accent);
  background: var(--catalog-info-bg);
  color: var(--accent);
}

.boolean-control {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--input-bg);
}

.boolean-control button {
  min-height: 30px;
  padding: 5px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--text-dim);
  font-family: inherit;
  font-size: 11px;
  cursor: pointer;
}

.boolean-control button.active {
  background: var(--bg-card);
  color: var(--text);
}

.column-presets {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-bottom: 22px;
}

.column-preset {
  min-height: 62px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--input-bg);
  color: var(--text);
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
}

.column-preset span {
  display: block;
  margin-top: 3px;
  color: var(--text-muted);
  font-size: 10px;
  font-weight: 400;
}

.column-preset:hover,
.column-preset.active {
  border-color: var(--accent);
}

.column-group {
  margin-bottom: 20px;
}

.column-group h3 {
  margin: 0 0 8px;
  color: var(--text-muted);
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  font-weight: 500;
  text-transform: uppercase;
}

.column-option {
  display: flex;
  min-height: 38px;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  border-bottom: 1px solid var(--border);
  color: var(--text-dim);
  font-size: 12px;
}

.column-option > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.column-option.locked {
  color: var(--text-muted);
}

.detail-lead {
  padding-bottom: 18px;
  border-bottom: 1px solid var(--border);
}

.detail-lead p {
  margin: 8px 0 0;
  line-height: 1.55;
}

.detail-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 12px;
}

.detail-section {
  padding: 18px 0;
  border-bottom: 1px solid var(--border);
}

.detail-section:last-child {
  border-bottom: 0;
}

.detail-section h3 {
  margin: 0 0 12px;
  color: var(--text-muted);
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  font-weight: 500;
  text-transform: uppercase;
}

.detail-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px 20px;
}

.detail-item {
  min-width: 0;
}

.detail-item dt {
  margin-bottom: 3px;
  color: var(--text-muted);
  font-size: 10px;
}

.detail-item dd {
  overflow-wrap: anywhere;
  color: var(--text);
  font-size: 12px;
  font-weight: 500;
}

.detail-footer {
  justify-content: space-between;
}

.small-action {
  min-height: 30px;
  padding: 5px 9px;
  font-size: 10px;
}

.toast-region {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 400;
  display: flex;
  width: min(360px, calc(100vw - 36px));
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
}

.toast {
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 6px;
  background: var(--bg-card);
  color: var(--text);
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.22);
  font-size: 12px;
  line-height: 1.45;
  animation: toast-in 160ms ease both;
}

.toast.success {
  border-left-color: var(--catalog-success);
}

.toast.error {
  border-left-color: var(--catalog-danger);
}

@keyframes toast-in {
  from { opacity: 0; transform: translateY(8px); }
}

@media (max-width: 1180px) {
  .catalog-toolbar {
    grid-template-columns: minmax(260px, 1fr) auto;
  }

  .preset-control {
    grid-row: 2;
    grid-column: 1 / -1;
    justify-self: start;
  }

  .toolbar-actions {
    grid-column: 2;
  }

  .catalog-table-scroll {
    max-height: calc(100svh - 286px);
  }

}

@media (max-width: 860px) {
  .catalog-page {
    padding: 10px 0 24px;
  }

  
  .catalog-container {
    padding: 0 14px;
  }

  .breadcrumbs {
    margin-bottom: 14px;
  }

  .catalog-title-row {
    align-items: flex-start;
    flex-direction: column;
    gap: 18px;
  }

  .catalog-title-compact {
    min-height: 28px;
    flex-direction: row;
    align-items: center;
    gap: 10px;
  }

  .catalog-title-row h1 {
    font-size: 29px;
    line-height: 1.16;
  }

  .catalog-title-compact h1 {
    margin: 0;
    font-size: 21px;
    line-height: 1.2;
  }

  .catalog-title-actions {
    width: 100%;
  }

  .catalog-title-actions .btn {
    flex: 1 1 0;
    padding: 10px 12px;
  }

  .catalog-toolbar {
    display: flex;
    flex-direction: column;
    align-items: stretch;
  }

  .preset-control {
    width: 100%;
    overflow-x: auto;
  }

  .preset-button {
    flex: 1 0 auto;
  }

  .toolbar-actions {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
  }

  .tool-button {
    padding: 8px 6px;
  }

  .selection-bar {
    align-items: flex-start;
    flex-direction: column;
  }

  .catalog-table-scroll {
    min-height: 420px;
    max-height: calc(100svh - 331px);
  }

  .table-footer {
    align-items: flex-start;
    flex-direction: column;
  }

  .table-footer > div:first-child {
    flex-direction: column;
    gap: 2px;
  }

  
  
  
  
  
  
  
  
  
  .status-tabs {
    width: 100%;
    overflow-x: auto;
  }

  
  
  .detail-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 520px) {
  .catalog-title-actions {
    flex-direction: column;
  }

  .catalog-title-actions .btn {
    width: 100%;
  }

  .toolbar-actions {
    grid-template-columns: 1fr 1fr;
  }

  .drawer-footer {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }

  .drawer-footer .btn {
    min-width: 0;
    padding: 10px 8px;
  }

  .column-presets {
    grid-template-columns: 1fr;
  }

  
  }

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* Sample links drawer. The links are presigned and short-lived, so they are
   listed rather than opened for the visitor: a browser blocks a burst of
   windows opened from a promise callback, and a list also shows what was
   actually issued against what was asked for. */
.sample-note {
  font-size: 13px;
  color: var(--text-muted);
  margin: 0 0 16px;
}
.sample-link-list {
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
}
.sample-link-list li {
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
}
.sample-link-list li:last-child { border-bottom: none; }
.sample-link-list a {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 13px;
  color: var(--accent);
  text-decoration: none;
}
.sample-link-list a:hover { text-decoration: underline; }
