/*
  CHELABS Unified UI v2 — components
  Version: 2.2.0

  Every reusable component of the system, ported from
  docs/design-system/v2-reference/chelabs-ui.css. Every colour, shadow
  and structural size is a token from tokens.css; the remaining px
  literals are the reference's own internal paddings and type sizes.

  Only components with a real consumer exist here (ADR-006's "no CSS
  ahead of a consumer" rule is kept under v2 — the contract test fails
  on a class no template uses). Not ported for that reason: the
  reference's tabs, count pill, toggle switch, chart, stat cards,
  billing / referral / pricing blocks, project-row list and the
  select-like chip — none has a Control Plane consumer today. Add a
  component together with the first screen that needs it.

  Variants are named by meaning, not by colour, so that a product can
  never pick "orange" for a success: .success / .warning / .danger /
  .accent map onto the reference's .green / .orange / .red / .purple.
*/

/* ============= BUTTONS ============= */
.chelabs-btn {
  height: var(--cl-control-h);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 0 19px;
  border: 1px solid transparent;
  border-radius: var(--cl-r-btn);
  background: var(--cl-gradient);
  color: var(--cl-on-accent);
  font-weight: 700;
  font-size: 14px;
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  box-shadow: var(--cl-shadow-btn);
  transition: transform var(--cl-fast), box-shadow var(--cl-fast), filter var(--cl-fast), background var(--cl-fast), color var(--cl-fast);
}
.chelabs-btn:hover { transform: translateY(-1px); box-shadow: var(--cl-shadow-brand-glow); filter: saturate(1.03); }
.chelabs-btn:active { transform: translateY(0); box-shadow: var(--cl-shadow-btn-active); }
.chelabs-btn.secondary {
  background: var(--cl-surface);
  color: var(--cl-ink);
  border-color: var(--cl-line);
  box-shadow: var(--cl-shadow-secondary);
}
.chelabs-btn.secondary:hover { background: var(--cl-surface-soft); box-shadow: var(--cl-shadow-secondary-hover); }
.chelabs-btn.ghost {
  background: transparent;
  color: var(--cl-ghost-text);
  border-color: transparent;
  box-shadow: none;
}
.chelabs-btn.ghost:hover { background: var(--cl-nav-hover-bg); color: var(--cl-nav-hover); box-shadow: none; transform: none; }
/* Destructive actions only (revoke, archive, purge, regenerate). The
   reference defines no destructive button; this is its .badge.red
   treatment applied to the button shape — the same red the reference
   uses for anything alarming, without the primary's purple shadow. */
.chelabs-btn.danger {
  background: var(--cl-badge-red-bg);
  color: var(--cl-red);
  border-color: transparent;
  box-shadow: none;
}
.chelabs-btn.danger:hover { background: var(--cl-red-soft); box-shadow: var(--cl-shadow-secondary-hover); }
.chelabs-btn.small {
  height: var(--cl-control-h-sm);
  padding: 0 15px;
  border-radius: var(--cl-r-btn-sm);
  font-size: 13px;
}
.chelabs-btn.block { width: 100%; }
.chelabs-btn[disabled] {
  opacity: .5;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
  filter: none;
}
/* last, so it outranks the variant :hover rules of equal specificity */
.chelabs-btn[disabled]:hover { transform: none; box-shadow: none; filter: none; background: var(--cl-gradient); color: var(--cl-on-accent); }
.chelabs-btn.secondary[disabled]:hover { background: var(--cl-surface); color: var(--cl-ink); }
.chelabs-btn.ghost[disabled]:hover { background: transparent; color: var(--cl-ghost-text); }
.chelabs-btn.danger[disabled]:hover { background: var(--cl-badge-red-bg); color: var(--cl-red); }
.chelabs-btn .icon { width: 18px; height: 18px; stroke-width: 1.9; }

/* ============= CARDS ============= */
.chelabs-card {
  background: var(--cl-surface);
  border: 1px solid var(--cl-card-line);
  border-radius: var(--cl-r-lg);
  box-shadow: var(--cl-shadow-card);
  padding: var(--cl-card-pad);
  min-width: 0;
}
.chelabs-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px;
  padding-bottom: 20px;
  margin-bottom: 22px;
  border-bottom: 1px solid var(--cl-card-head-line);
}
.chelabs-card-head:not(:first-child) { margin-top: 28px; }
.chelabs-card-head h2 {
  margin: 0;
  color: var(--cl-ink);
  font-size: var(--cl-text-card-title);
  font-weight: 730;
  letter-spacing: -.015em;
}
.chelabs-card-subtitle { color: var(--cl-muted); font-size: 13px; margin-top: 5px; font-weight: 500; }
.chelabs-card-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.chelabs-card-actions form { margin: 0; }

/* ============= BADGES ============= */
.chelabs-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 24px;
  padding: 0 9px;
  border-radius: var(--cl-r-badge);
  font-size: 11px;
  font-weight: 800;
  line-height: 1;
  white-space: nowrap;
  background: var(--cl-gray-soft);
  color: var(--cl-th-text);
}
.chelabs-badge.accent { background: var(--cl-badge-accent-bg); color: var(--cl-badge-accent-text); }
.chelabs-badge.success { background: var(--cl-badge-green-bg); color: var(--cl-badge-green-text); }
.chelabs-badge.warning { background: var(--cl-badge-orange-bg); color: var(--cl-badge-orange-text); }
.chelabs-badge.danger { background: var(--cl-badge-red-bg); color: var(--cl-badge-red-text); }

/* ============= FORMS ============= */
.chelabs-form-row { margin-bottom: 18px; min-width: 0; }
.chelabs-form-row label,
.chelabs-form-row .label {
  display: block;
  margin-bottom: 8px;
  color: var(--cl-label);
  font-size: 13px;
  font-weight: 650;
}
.chelabs-input, .chelabs-select, .chelabs-textarea {
  width: 100%;
  height: var(--cl-input-h);
  border: 1px solid var(--cl-input-line);
  border-radius: var(--cl-r-btn);
  background: var(--cl-surface);
  padding: 0 14px;
  color: var(--cl-td-text);
  box-shadow: var(--cl-shadow-input);
  outline: none;
  transition: border-color var(--cl-fast), box-shadow var(--cl-fast);
}
.chelabs-input::placeholder, .chelabs-textarea::placeholder { color: var(--cl-placeholder); }
.chelabs-input:focus, .chelabs-select:focus, .chelabs-textarea:focus {
  border-color: var(--cl-input-focus-line);
  box-shadow: var(--cl-input-focus-ring);
}
.chelabs-input:disabled, .chelabs-select:disabled, .chelabs-textarea:disabled {
  background: var(--cl-input-disabled-bg);
  color: var(--cl-input-disabled-text);
  cursor: not-allowed;
}
.chelabs-input.is-error, .chelabs-select.is-error, .chelabs-textarea.is-error { border-color: var(--cl-red); }
.chelabs-textarea { height: auto; min-height: 110px; padding: 12px 14px; resize: vertical; }
.chelabs-select {
  appearance: none;
  padding-right: 38px;
  cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--cl-muted) 50%), linear-gradient(135deg, var(--cl-muted) 50%, transparent 50%);
  background-position: calc(100% - 19px) 50%, calc(100% - 14px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.chelabs-code-input {
  letter-spacing: .36em;
  font-size: 20px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.chelabs-form-error { font-size: 13px; color: var(--cl-red); margin: 8px 0 0; font-weight: 600; }
.chelabs-hint { font-size: 13px; color: var(--cl-muted); margin: 12px 0 0; line-height: 1.55; }
.chelabs-hint a, .chelabs-form-error a { color: var(--cl-link); font-weight: 650; }
.chelabs-caption { display: block; color: var(--cl-caption); font-size: 12px; margin-top: 3px; font-weight: 500; }

/* an inline row of fields + submit (filters, short actions) */
.chelabs-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 16px;
  align-items: flex-end;
  margin: 0;
}
.chelabs-filters .chelabs-form-row { margin-bottom: 0; min-width: 240px; flex: 1 1 240px; }
.chelabs-filters .chelabs-textarea { min-height: 0; }
.chelabs-filters .chelabs-btn { flex: 0 0 auto; }
.chelabs-filters + .chelabs-filters,
.chelabs-hint + .chelabs-filters,
.chelabs-form-error + .chelabs-filters,
.chelabs-table-wrap + .chelabs-filters { margin-top: 18px; }
.chelabs-hint + .chelabs-table-wrap,
.chelabs-form-error + .chelabs-table-wrap,
.chelabs-field-row + .chelabs-table-wrap { margin-top: 16px; }
.chelabs-actions-row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin: 18px 0 0; }
.chelabs-actions-row:first-child { margin-top: 0; }
.chelabs-actions-row form { margin: 0; }

/* ============= KEY / VALUE ROWS (the reference's .info-row) ============= */
.chelabs-field-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  min-height: 54px;
  padding: 8px 0;
}
.chelabs-field-row + .chelabs-field-row { border-top: 1px solid var(--cl-row-line); }
.chelabs-field-row > .label { color: var(--cl-info-key); flex: 0 0 auto; }
.chelabs-value {
  color: var(--cl-info-value);
  font-weight: 700;
  text-align: right;
  min-width: 0;
  overflow-wrap: anywhere;
}
.chelabs-value.empty { color: var(--cl-muted); font-weight: 500; }
.chelabs-value.danger { color: var(--cl-red); }
.chelabs-value a { color: var(--cl-link); }
.chelabs-value a:hover { color: var(--cl-brand-text-hover); }
.chelabs-value .chelabs-caption { text-align: right; }

/* ============= MESSAGES / NOTICES ============= */
.chelabs-message {
  display: flex;
  gap: 13px;
  align-items: flex-start;
  padding: 17px 19px;
  border: 1px solid var(--cl-brand-line);
  border-radius: var(--cl-r-notice);
  background: var(--cl-brand-soft-2);
  color: var(--cl-brand-text);
  font-size: 14px;
  line-height: 1.5;
  margin: 0;
}
.chelabs-message .icon { font-weight: 800; flex: 0 0 auto; }
.chelabs-message a { color: inherit; font-weight: 700; text-decoration: underline; }
.chelabs-message.success { border-color: var(--cl-green-soft); background: var(--cl-green-soft); color: var(--cl-message-success-text); }
.chelabs-message.success .icon { color: var(--cl-green); }
.chelabs-message.warning { border-color: var(--cl-notice-line); background: var(--cl-notice-bg); color: var(--cl-notice-text); }
.chelabs-message.warning strong { color: var(--cl-notice-strong); }
.chelabs-message.error { border-color: var(--cl-red-soft); background: var(--cl-red-soft); color: var(--cl-message-error-text); }
.chelabs-message.error .icon { color: var(--cl-red); }

/* ============= TABLES ============= */
/* The wrap bleeds to the card's edges (the reference's .table-card has
   the table flush with the card) and scrolls horizontally on narrow
   screens instead of breaking the layout. */
.chelabs-table-wrap {
  overflow-x: auto;
  margin: 0 calc(-1 * var(--cl-card-pad));
}
.chelabs-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
}
.chelabs-table th {
  padding: 13px 16px;
  text-align: left;
  color: var(--cl-th-text);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .035em;
  font-weight: 700;
  border-bottom: 1px solid var(--cl-th-line);
}
.chelabs-table td {
  padding: 17px 16px;
  color: var(--cl-td-text);
  font-size: 14px;
  border-bottom: 1px solid var(--cl-td-line);
  vertical-align: middle;
}
.chelabs-table th:first-child, .chelabs-table td:first-child { padding-left: var(--cl-card-pad); }
.chelabs-table th:last-child, .chelabs-table td:last-child { padding-right: var(--cl-card-pad); }
.chelabs-table tbody tr:last-child td { border-bottom: 0; }
.chelabs-table tbody tr { transition: background var(--cl-fast); }
.chelabs-table tbody tr:hover { background: var(--cl-row-hover); }
.chelabs-table td.num { font-variant-numeric: tabular-nums; white-space: nowrap; }
.chelabs-table td.right { text-align: right; }
.chelabs-table td.right form { display: inline-flex; justify-content: flex-end; }
.chelabs-table td a { color: var(--cl-link); font-weight: 700; }
.chelabs-table td a:hover { color: var(--cl-brand-text-hover); }
.chelabs-table td b { color: var(--cl-strong-text); }
.chelabs-table td a b { color: inherit; }
.chelabs-table .chelabs-caption { margin-top: 3px; }
/* an inline action form inside a cell stays compact and right-aligned */
.chelabs-table td.right .chelabs-filters { flex-wrap: nowrap; justify-content: flex-end; gap: 8px; }
.chelabs-table .chelabs-form-row { min-width: 0; flex: 0 0 160px; }
.chelabs-table .chelabs-form-row .chelabs-input { height: var(--cl-control-h-sm); }

/* ============= PAGINATION ============= */
.chelabs-pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  padding-top: 20px;
  font-size: 13px;
  color: var(--cl-muted);
}
.chelabs-pager > span:last-child { display: inline-flex; gap: 8px; }

/* ============= EMPTY STATE ============= */
.chelabs-empty {
  text-align: center;
  padding: 56px var(--cl-card-pad);
  background: var(--cl-surface);
  border: 1px dashed var(--cl-line-strong);
  border-radius: var(--cl-r-lg);
}
.chelabs-empty h3 { font-size: 20px; font-weight: 730; color: var(--cl-ink); letter-spacing: -.015em; margin: 0 0 8px; }
.chelabs-empty p { color: var(--cl-muted); font-size: 15px; margin: 0 auto 20px; max-width: 46ch; line-height: 1.55; }
.chelabs-empty form { margin: 0; }

/* ============= SECRET / CODE BLOCK ============= */
.chelabs-secret {
  display: block;
  padding: 16px 18px;
  margin: 16px 0;
  font-family: var(--cl-font-mono);
  font-size: 13px;
  line-height: 1.5;
  word-break: break-all;
  background: var(--cl-page);
  border: 1px solid var(--cl-line);
  border-radius: var(--cl-r-sm);
  color: var(--cl-ink);
}

/* ============= AVATAR ============= */
.chelabs-avatar {
  width: var(--cl-avatar-size);
  height: var(--cl-avatar-size);
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--cl-brand-soft);
  color: var(--cl-avatar-text);
  font-weight: 750;
  font-size: 14px;
}

/* ============= TABS =============
   Ported from the reference's .tabs / .tab / .count-pill, which DS-02
   left out for want of a consumer. The consumer is the entity page:
   one top-level record, its related entities in tabs (the approved
   ui-reference/02_entity_tabs.png).

   Tabs here are LINKS, not a JavaScript widget. Each tab is a real URL,
   so a tab can be shared, bookmarked and opened in a new window, the
   back button works, and the panel keeps its zero lines of JavaScript
   (Root Owner decision, 2026-09-24). */
.chelabs-tabs {
  display: flex;
  align-items: center;
  gap: var(--cl-tabs-gap);
  padding: 0 var(--cl-card-pad);
  border-bottom: 1px solid var(--cl-th-line);
  overflow-x: auto;
  scrollbar-width: thin;
}
.chelabs-tab {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 18px 0 14px;
  color: var(--cl-tab-text);
  font-weight: 600;
  font-size: 14px;
  white-space: nowrap;
  transition: color var(--cl-fast);
}
.chelabs-tab:hover { color: var(--cl-brand-text); }
.chelabs-tab.active { color: var(--cl-tab-active-text); }
.chelabs-tab.active::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: var(--cl-tab-underline-h);
  background: var(--cl-brand);
  border-radius: var(--cl-r-pill);
}
.chelabs-tab-count {
  display: inline-grid;
  place-items: center;
  min-width: var(--cl-pill-size);
  height: var(--cl-pill-size);
  padding: 0 6px;
  border-radius: var(--cl-r-pill);
  background: var(--cl-pill-bg);
  color: var(--cl-pill-text);
  font-size: 11px;
  font-weight: 800;
}
.chelabs-tab.active .chelabs-tab-count {
  background: var(--cl-brand-soft);
  color: var(--cl-brand-text);
}

/* ============= SEARCH =============
   The reference's .search: a bordered box with a leading glyph and a
   borderless input inside it, so the glyph is part of the field rather
   than sitting next to it. */
.chelabs-search {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 380px;
  max-width: 100%;
  height: var(--cl-search-h);
  padding: 0 15px;
  background: var(--cl-surface);
  border: 1px solid var(--cl-search-line);
  border-radius: var(--cl-r-nav);
  color: var(--cl-search-icon);
}
.chelabs-search:focus-within {
  border-color: var(--cl-input-focus-line);
  box-shadow: var(--cl-input-focus-ring);
}
.chelabs-search .icon { width: 18px; height: 18px; flex: 0 0 auto; stroke-width: 1.9; }
.chelabs-search input {
  width: 100%;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--cl-text);
  font: inherit;
}
.chelabs-search input::placeholder { color: var(--cl-placeholder); }

/* ============= AN ICON-LED CELL =============
   The Registry Pattern's identity column (icon/logo/avatar + name) and
   the change history's "Раздел" column are the same shape, so they are
   one class rather than two that drift apart. */
.chelabs-cell-lead {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  /* The label rides on ONE line and truncates. Letting it wrap makes a
     narrow column break "Root Owner" across two lines and pushes the
     row taller than its neighbours, which reads as a rendering fault
     rather than as a long name. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chelabs-cell-lead .icon {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
  color: var(--cl-brand-text);
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ============= BEFORE -> AFTER =============
   The change history's two value columns, per the approved
   ui-reference/03_change_history.png. A value is a chip so that an
   empty string, a space and a missing value are visibly different
   things rather than three kinds of nothing.

   `.before` is neutral and `.after` carries the brand tint: the eye
   should land on what the value BECAME, which is what the row is
   about. A value that is itself a status uses .chelabs-badge instead,
   because its own semantic colour carries more than the position. */
/* NOWRAP, and this is load-bearing rather than tidy. Wrapping put the
   arrow on one line and the value it points at on the next, which
   reads as a broken cell instead of as a change. A long value
   truncates instead -- the row says WHICH field changed, and the full
   value belongs to the record, not to the log line. */
.chelabs-diff { display: inline-flex; align-items: center; gap: 10px; flex-wrap: nowrap; min-width: 0; }
.chelabs-diff-value {
  display: inline-flex;
  align-items: center;
  min-width: 0;
  max-width: 24ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: 5px 10px;
  border-radius: var(--cl-r-xs);
  font-size: 13px;
  font-weight: 600;
}
.chelabs-diff-value.before { background: var(--cl-pill-bg); color: var(--cl-td-text); }
.chelabs-diff-value.after { background: var(--cl-brand-soft); color: var(--cl-brand-text); }
.chelabs-diff-value.empty { background: transparent; color: var(--cl-muted); font-weight: 500; }
.chelabs-diff-arrow { color: var(--cl-diff-arrow); flex: 0 0 auto; }

/* ============= A GROUP OF SETTINGS =============
   The approved ui-reference/04_settings.png: settings are grouped into
   semantic cards, and inside a card the fields lay out in columns
   rather than one long single-file form. Each field keeps its label,
   its control and its helper text together. */
.chelabs-form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 18px var(--cl-gap);
  align-items: start;
}
.chelabs-form-grid .chelabs-form-row { margin-bottom: 0; }
.chelabs-form-grid .chelabs-hint { margin-top: 7px; }
/* A field that needs the full width of the group (a description, a
   reason) rather than one column of it. */
.chelabs-form-grid .chelabs-form-row.wide { grid-column: 1 / -1; }

/* ============= RESPONSIVE ============= */
@media (max-width: 640px) {
  .chelabs-table { min-width: 720px; }
  .chelabs-filters .chelabs-form-row { min-width: 100%; }
  .chelabs-tabs { gap: 22px; padding: 0 18px; }
  .chelabs-form-grid { grid-template-columns: 1fr; }
  .chelabs-field-row { flex-direction: column; align-items: flex-start; gap: 4px; min-height: 0; padding: 12px 0; }
  .chelabs-value { text-align: left; }
  .chelabs-value .chelabs-caption { text-align: left; }
}
