/* ═══════════════════════════════════════════════════════════
   Components — ported 1:1 from Team's Axiom UI where it has one

   One set of rules for every control, so no two behave differently:
   - Height: 40px; --sm 32px; --lg 48px. Header controls share --control-h.
   - Corners by height (the design system's ADR-0016): 24–40px → --r-control (8px 0 8px 0),
    48–56px → --r-control-l (12px 0 12px 0). A field with its button is one control —
    .field-action below; a field never stands beside a separate button.
   - Neutral control (no fill): --border outline, --text-secondary; hover lifts the
     text to --text and the background to --surface. The outline never changes.
   - Control on a --surface fill: hover moves the fill to --surface-raised.
   - Primary: --accent fill; hover brightness(1.1), active scale(.98) — no jump.
   - Hover only where there is one — @media (hover: hover) (the design system, question
     49): on a touch screen a tap left the hover on.
   - Disabled by colour, not by opacity (question 12); a submit is never disabled, a busy
     one only stops taking clicks (question 28).
   - Under 48px a control gets a 48px hit area on a touch screen, invisibly (03 §2.4).
   ═══════════════════════════════════════════════════════════ */

/* ── Icons (IconHelper#icon): Lucide geometry, a 1px line at every size ── */
.icon { flex-shrink: 0; }
/* stroke-width 1 stays one screen pixel however the SVG is scaled. Not inherited, so it
   goes on the shapes themselves. */
.icon :is(path, circle, rect, line, polyline, polygon, ellipse) { vector-effect: non-scaling-stroke; }
[dir="rtl"] .icon--dir { transform: scaleX(-1); }

/* ── Buttons: Team .btn — Gilroy, 40px, asymmetric corners ── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  height: 40px;
  padding: 0 var(--sp-4);
  border: 1px solid transparent;
  border-radius: var(--r-control);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 400;
  line-height: var(--lh-20);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease),
              color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease),
              filter var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}
.btn .icon { width: 16px; height: 16px; }
.btn--primary { background: var(--accent); color: var(--on-accent); }
.btn--primary:active { transform: scale(0.98); }
.btn--secondary { background: var(--surface); color: var(--text); border-color: var(--border); }
.btn--outline { background: transparent; color: var(--text); border-color: var(--accent); }
.btn--ghost { background: transparent; color: var(--text-secondary); border-color: var(--border); }
@media (hover: hover) {
  .btn--primary:hover { filter: brightness(1.1); }
  .btn--secondary:hover { background: var(--surface-raised); }
  .btn--outline:hover { background: var(--accent); color: var(--on-accent); }
  .btn--ghost:hover { background: var(--surface); color: var(--text); }
}
.btn--sm { height: 32px; padding: 0 var(--sp-3); font-size: var(--text-xs); line-height: var(--lh-16); }
.btn--lg { height: 48px; padding: 0 var(--sp-6); font-size: var(--text-base); line-height: var(--lh-24); border-radius: var(--r-control-l); }
.btn:disabled, .btn[aria-disabled="true"] {
  color: var(--text-tertiary);
  background: var(--surface);
  border-color: var(--border);
  cursor: not-allowed;
  transform: none;
  filter: none;
}
form[aria-busy="true"] [type="submit"] { pointer-events: none; cursor: progress; }

/* ── Square icon button: Team 40×40, the control corners ── */
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  color: var(--text-secondary);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--r-control);
  cursor: pointer;
  transition: color var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}
@media (hover: hover) {
  .icon-btn:hover { color: var(--text); background: var(--surface); }
}
.icon-btn .icon { width: 20px; height: 20px; }
.icon-btn--sm { width: 36px; height: 36px; }

/* Touch: a 48px hit area round a smaller icon control, the look unchanged. */
@media (pointer: coarse) {
  /* (the header's cross keeps its own position: absolute from layout.css, loaded later) */
  /* (the bookmark on a picture is absolute already — a containing block for its ::after) */
  :is(.icon-btn--sm, .header-search__close, .search-field__clear) { position: relative; }
  :is(.icon-btn--sm, .bookmark--icon, .header-search__close, .search-field__clear)::after {
    content: "";
    position: absolute;
    inset: calc(50% - 24px);
  }
}

/* ── Inputs: Team .input-base ── */
.input {
  width: 100%;
  height: 48px;
  padding: 0 var(--sp-4);
  color: var(--text);
  background: var(--surface-sunken);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-field);
  font-size: var(--text-base);
  transition: border-color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease);
}
.input::placeholder { color: var(--text-tertiary); }
@media (hover: hover) {
  .input:hover { border-color: var(--border-hover); }
}
.input:focus, .input:focus-visible { outline: none; border-color: var(--accent); box-shadow: var(--ring); }
.input:-webkit-autofill {
  -webkit-box-shadow: 0 0 0 1000px var(--surface-sunken) inset;
  -webkit-text-fill-color: var(--text);
  transition: background-color 5000s ease-in-out 0s;
}

/* ── Field with an action: one field and its one button make one control ──
   A single field with its submit button (the newsletter, the search page) is one shell
   with the button inside, rather than a field beside a button. Beside each other their corners
   could not agree: a field has four equal corners, a button the signature pair. The shell is a
   48px control (12 on the signature pair), and the 40px button sits 4px in with its 8 — the
   same curve as the shell's, 4px in, on all four corners. The design system's ADR-0015 and
   ADR-0016. Every number is on the system's scales. */
.field-action {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  height: 48px;
  padding: 3px; /* + the 1px border: the button stands 4px in, 12 − 4 = its 8 */
  padding-inline-start: 0;
  background: var(--surface-sunken);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-control-l);
  transition: border-color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease);
}
@media (hover: hover) {
  .field-action:hover { border-color: var(--border-hover); }
}
.field-action:has(.field-action__input:focus) { border-color: var(--accent); box-shadow: var(--ring); }
.field-action__input {
  flex: 1;
  min-width: 0;
  height: 100%;
  padding: 0 var(--sp-2);
  padding-inline-start: var(--sp-4);
  color: var(--text);
  background: transparent;
  border: 0;
  border-radius: 0;
  outline: none;
  font-size: var(--text-base);
}
.field-action__input::placeholder { color: var(--text-tertiary); }
.field-action__input:-webkit-autofill {
  -webkit-box-shadow: 0 0 0 1000px var(--surface-sunken) inset;
  -webkit-text-fill-color: var(--text);
  transition: background-color 5000s ease-in-out 0s;
}
/* A leading icon (the search page's magnifier) takes the text's 16px start. */
.field-action > .icon:first-child {
  width: 20px;
  height: 20px;
  margin-inline-start: var(--sp-4);
  color: var(--text-tertiary);
  pointer-events: none;
}
.field-action > .icon:first-child ~ .field-action__input { padding-inline-start: var(--sp-3); }
.field-action > .btn { flex-shrink: 0; }

/* Invalid (field_validation_controller): the whole control turns red — and shakes on a
   refused submit, the button with it: it is one control. The message stands in the slot
   under it. The error stays through focus, until the next check. Under reduced motion
   base.css cuts the shake, the colour stays. Team's form_validation.js shake. */
.field-action.is-invalid,
.field-action.is-invalid:has(:focus) {
  border-color: var(--error);
  box-shadow: 0 0 0 3px rgba(255, 61, 61, 0.18);
}
.field-action.is-shaking { animation: field-shake var(--dur-3) cubic-bezier(0.36, 0.07, 0.19, 0.97); }
@keyframes field-shake {
  10%, 90% { transform: translateX(-1px); }
  20%, 80% { transform: translateX(2px); }
  30%, 50%, 70% { transform: translateX(-4px); }
  40%, 60% { transform: translateX(4px); }
}
.field-action__error { margin-top: var(--sp-2); font-size: var(--text-sm); line-height: var(--lh-20); color: var(--error); }
.field-action__error:empty { display: none; }

/* ── Tag: category label (Team badge) ── */
.tag {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  padding: 3px var(--sp-2);
  border-radius: var(--r-xs);
  font-size: var(--text-xs);
  font-weight: 400;
  line-height: var(--lh-16);
  color: var(--accent);
  background: var(--tint);
  border: 1px solid rgba(29, 226, 39, 0.2);
  transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
  width: fit-content;
}
@media (hover: hover) {
  a.tag:hover { background: var(--accent-subtle); border-color: var(--border-accent); }
}

/* ── Chips: filters and article tags (Team chip) ── */
.chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.chip {
  display: inline-flex;
  align-items: center;
  height: 36px;
  padding: 0 var(--sp-4);
  border-radius: var(--r-xs);
  font-size: var(--text-sm);
  line-height: var(--lh-20);
  color: var(--text-secondary);
  background: var(--surface);
  border: 1px solid var(--border);
  white-space: nowrap;
  transition: color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}
@media (hover: hover) {
  .chip:hover { color: var(--text); background: var(--surface-raised); }
}
.chip.is-active { color: var(--accent); background: var(--tint); border-color: var(--accent); }
/* One scrollable row on phones instead of a wrapped wall of chips. */
@media (max-width: 768px) {
  .chips--scroll {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    margin: 0 calc(var(--gutter) * -1);
    padding: 0 var(--gutter);
  }
  .chips--scroll::-webkit-scrollbar { display: none; }
}

/* ── Segmented switch: the Team portal's sign-in switch for any number of segments of
   any width. One thumb slides under the current segment (segmented_controller measures
   it); before the controller runs the current segment paints its own background, so
   nothing jumps when the thumb takes over. Hover changes the text only. ── */
.segmented { position: relative; min-width: 0; }
.segmented__scroller { overflow-x: auto; scrollbar-width: none; border-radius: inherit; }
.segmented__scroller::-webkit-scrollbar { display: none; }

/* ── Scroll edge (the design system's ADR-0020): content that scrolls never stops at an
   invisible line. Where the background is the same on both sides of the edge, the edge
   with more content past it fades out over 32px; edge_fades.js marks which (both in the
   middle, none when it all fits). Used by the category row, the filter dialog and the
   header search list. A container with its own visible border clips on its rounded
   border instead; content passing under the feed bar gets the progressive blur. ── */
.edge-fade { --fade: 32px; --fade-dir: to right; }
.edge-fade--y { --fade-dir: to bottom; }
[dir="rtl"] .edge-fade:not(.edge-fade--y) { --fade-dir: to left; }
.edge-fade[data-fade-end] {
  -webkit-mask-image: linear-gradient(var(--fade-dir), #000 calc(100% - var(--fade)), #0000);
  mask-image: linear-gradient(var(--fade-dir), #000 calc(100% - var(--fade)), #0000);
}
.edge-fade[data-fade-start] {
  -webkit-mask-image: linear-gradient(var(--fade-dir), #0000, #000 var(--fade));
  mask-image: linear-gradient(var(--fade-dir), #0000, #000 var(--fade));
}
.edge-fade[data-fade-start][data-fade-end] {
  -webkit-mask-image: linear-gradient(var(--fade-dir), #0000, #000 var(--fade), #000 calc(100% - var(--fade)), #0000);
  mask-image: linear-gradient(var(--fade-dir), #0000, #000 var(--fade), #000 calc(100% - var(--fade)), #0000);
}
.segmented__track { position: relative; display: flex; gap: var(--sp-1); width: max-content; }
.segmented__thumb {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 0;
  background: var(--surface-raised);
  border-radius: var(--r-control-l);
  pointer-events: none;
  transition: transform var(--dur-3) var(--ease-morph), width var(--dur-3) var(--ease-morph);
}
.segmented:not(.is-ready) .segmented__thumb { display: none; }
.segmented__item {
  position: relative;
  display: inline-flex;
  align-items: center;
  height: 48px;
  padding: 0 var(--sp-4);
  border-radius: var(--r-control-l);
  font-size: var(--text-sm);
  line-height: var(--lh-20);
  white-space: nowrap;
  color: var(--text-tertiary);
  transition: color var(--dur-2) var(--ease);
}
.segmented__item[aria-current="page"] { color: var(--text); }
.segmented:not(.is-ready) .segmented__item[aria-current="page"] { background: var(--surface-raised); }
/* While the thumb travels, the text colour travels with it. */
.segmented.is-moving .segmented__item[aria-current="page"] { color: var(--text-tertiary); }
.segmented.is-moving .segmented__item.is-target { color: var(--text); }
@media (hover: hover) {
  .segmented__item:not([aria-current="page"]):hover { color: var(--text); }
}
/* Inside: the scroller clips an outer ring. */
.segmented__item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* Part of a several-category selection: no thumb then, a dot marks each chosen one. */
.segmented__item.is-selected { color: var(--text); }
.segmented__item.is-selected::before {
  content: "";
  width: 8px;
  height: 8px;
  margin-inline-end: var(--sp-2);
  border-radius: 50%;
  background: var(--accent);
}

/* ── Count badge: a small number on a control's corner (active filters). ── */
.count-badge {
  position: absolute;
  top: var(--sp-1);
  inset-inline-end: var(--sp-1);
  min-width: 16px;
  height: 16px;
  padding: 0 var(--sp-1);
  border-radius: 999px; /* a counter is a capsule */
  font-size: 11px;
  line-height: var(--lh-16);
  font-variant-numeric: tabular-nums;
  text-align: center;
  color: var(--on-accent);
  background: var(--accent);
}

.count-badge--neutral { color: var(--text); background: var(--surface-raised); }

/* ── Bookmark («Избранное»): an outline bookmark that turns into bookmark-check and the
   accent colour once saved — both icons stay 1px outlines. Above a stretched row link. ── */
.bookmark { position: relative; z-index: 1; }
.bookmark__icon--on, .bookmark__label--on { display: none; }
.bookmark[aria-pressed="true"] { color: var(--accent); }
.bookmark[aria-pressed="true"] .bookmark__icon--off,
.bookmark[aria-pressed="true"] .bookmark__label--off { display: none; }
.bookmark[aria-pressed="true"] .bookmark__icon--on,
.bookmark[aria-pressed="true"] .bookmark__label--on { display: inline; }
.bookmark .icon { width: 16px; height: 16px; }
/* In a feed row: on the picture's top-right corner, opposite the category tag — 24px like
   the tag (one line, one height), 12px in, the same opaque fill (no glass in a list). */
.bookmark--icon {
  position: absolute;
  top: var(--sp-3);
  inset-inline-end: var(--sp-3);
  z-index: 2;
  width: 24px;
  height: 24px;
  background: var(--surface);
}
@media (hover: hover) {
  .bookmark--icon:hover { background: var(--surface-raised); }
}
.bookmark--labeled { gap: var(--sp-2); margin-inline-start: auto; }

/* ── Choice: a radio or a checkbox drawn as a chip (the filter dialog). ── */
.choices { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.choice { position: relative; display: inline-flex; cursor: pointer; }
.choice > span {
  display: inline-flex;
  align-items: center;
  height: 36px;
  padding: 0 var(--sp-4);
  border-radius: var(--r-xs);
  font-size: var(--text-sm);
  line-height: var(--lh-20);
  color: var(--text-secondary);
  background: var(--surface-raised);
  border: 1px solid transparent;
  white-space: nowrap;
  transition: color var(--dur-1) var(--ease), background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
@media (hover: hover) {
  .choice:hover > span { color: var(--text); }
}
.choice:has(:checked) > span { color: var(--accent); background: var(--tint); border-color: var(--border-accent); }
.choice:has(:focus-visible) > span { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ── Page & section headings ── */
.page-header { padding: var(--sp-12) 0 0; }
.page-title {
  display: inline-block;
  max-width: 100%;
  font-size: var(--text-4xl);
  line-height: var(--lh-48);
  letter-spacing: -0.02em;
  /* Team: one gradient title per page, primary text → light accent */
  background: linear-gradient(135deg, var(--text) 0%, var(--text) 45%, var(--accent-light) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.page-subtitle {
  margin-top: var(--sp-3);
  max-width: 720px;
  font-size: var(--text-lg);
  line-height: var(--lh-28);
  color: var(--text-secondary);
}
.section { margin-top: var(--sp-16); }
.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4);
  margin-bottom: var(--sp-6);
}
.section-title { font-size: var(--text-2xl); line-height: var(--lh-32); }
@media (max-width: 768px) {
  .page-header { padding-top: var(--sp-8); }
  .page-title { font-size: 28px; line-height: var(--lh-32); }
  .page-subtitle { font-size: var(--text-base); line-height: var(--lh-24); }
  .section { margin-top: var(--sp-12); }
  .section-title { font-size: var(--text-xl); line-height: var(--lh-28); }
}

/* ── Article card ── */
.card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
  transition: transform var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease);
}
.card__media {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--surface-raised);
  border-radius: var(--r-media-top);
}
/* A category tag on a picture's top-left corner (the read-also cards, the slider's cover,
   a feed row), 12px in: its 8 + 12 = the picture's 20. An opaque fill — the tag's own look
   on the surface — as the system allows no glass in a list. A block, so a name too long
   for a small picture ends in an ellipsis instead of running under the bookmark. */
.tag--on-media {
  position: absolute;
  top: var(--sp-3);
  inset-inline-start: var(--sp-3);
  z-index: 2;
  display: block;
  max-width: calc(100% - 2 * var(--sp-3));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  background: linear-gradient(var(--tint), var(--tint)), var(--surface);
}
.card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--dur-3) var(--ease);
}
.card__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-5);
}
.card__title {
  font-size: var(--text-xl);
  line-height: var(--lh-28);
  letter-spacing: -0.025em;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* The whole card is the link; the category tag stays clickable on top. */
.card__title a::after { content: ""; position: absolute; inset: 0; }
.card__excerpt {
  font-size: var(--text-sm);
  line-height: var(--lh-20);
  color: var(--text-secondary);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.card__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-1) var(--sp-3);
  margin-top: auto;
  font-size: var(--text-xs);
  line-height: var(--lh-16);
  color: var(--text-tertiary);
}
.card__meta-item { display: inline-flex; align-items: center; gap: var(--sp-1); }
.card__meta-item .icon { width: 16px; height: 16px; }
@media (hover: hover) {
  .card:hover { transform: translateY(-2px); border-color: var(--border-hover); box-shadow: var(--sh-card-hover); }
  .card:hover .card__media img { transform: scale(1.03); }
  .card:hover .card__title { color: var(--text); }
}

/* ── Missing cover: the brand gradient over a fine 40px grid, with the category's name set
   large at the bottom. Sized by its box (container units), so one rule serves a card and
   the slider. Fills a positioned 16:9 media box. ── */
.cover-fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  padding: 6%; /* of the media box: cqi here would measure an ancestor, not this box */
  container-type: inline-size;
  background:
    radial-gradient(ellipse 70% 90% at 85% 10%, rgba(29, 226, 39, 0.18), transparent 60%),
    repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.04) 0 1px, transparent 1px 40px),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.04) 0 1px, transparent 1px 40px),
    linear-gradient(135deg, var(--surface-raised), var(--surface));
}
.cover-fallback__label {
  font-family: var(--font-heading);
  font-size: clamp(16px, 7cqi, 44px);
  line-height: 1.1; /* drawn into the picture at its scale, not set text: relative on purpose */
  letter-spacing: -0.02em;
  color: var(--text-secondary);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ── Pagination: Team .pagy, 40px touch targets. Numbers only — no Previous/Next: the
   neighbouring numbers are the same links, and rel=prev/next live in <head>. ── */
.pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--sp-1);
  margin-top: var(--sp-12);
}
.pagination__link, .pagination__gap {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-1);
  min-width: 40px;
  height: 40px;
  padding: 0 var(--sp-3);
  border: 1px solid transparent;
  border-radius: var(--r-control);
  font-size: var(--text-sm);
  line-height: var(--lh-20);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
  transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.pagination__gap { color: var(--text-tertiary); }
@media (hover: hover) {
  .pagination__link:hover { background: var(--surface); color: var(--text); }
}
/* No glow: the design system keeps it for a chart's main line (question 107). */
.pagination__link[aria-current="page"] {
  color: var(--accent);
  background: var(--accent-subtle);
  border-color: var(--border-accent);
}

/* ── Flash banner (Team) ── */
.flash-banner {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--border);
  border-radius: var(--r-sm); /* ~48px tall */
  background: var(--surface-raised);
  font-size: 15px;
  line-height: var(--lh-20);
}
.flash-banner .icon { width: 20px; height: 20px; }
.flash-banner--notice { color: var(--accent); background: var(--tint); border-color: var(--accent); }
.page-flash { padding-top: var(--sp-6); }
.flash-banner--alert { color: var(--error); background: rgba(255, 61, 61, 0.1); border-color: rgba(255, 61, 61, 0.45); }

/* ── Empty state (Team) ── */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: var(--sp-16) var(--sp-4);
  text-align: center;
}
.empty-state__icon {
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  margin-bottom: var(--sp-4);
  color: var(--text-tertiary);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg); /* 64px */
}
.empty-state__icon .icon { width: 32px; height: 32px; }
.empty-state__title { font-size: var(--text-xl); line-height: var(--lh-28); }
.empty-state__text { max-width: 448px; margin-top: var(--sp-2); font-size: var(--text-sm); line-height: var(--lh-20); color: var(--text-secondary); }
.empty-state .btn { margin-top: var(--sp-6); }

/* ── Breadcrumbs ── */
.breadcrumbs ol { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); font-size: var(--text-sm); line-height: var(--lh-20); color: var(--text-tertiary); }
.breadcrumbs li { display: inline-flex; align-items: center; gap: var(--sp-2); min-width: 0; }
.breadcrumbs li + li::before { content: "/"; color: var(--text-tertiary); }
.breadcrumbs a { color: var(--text-secondary); transition: color var(--dur-1) var(--ease); }
@media (hover: hover) {
  .breadcrumbs a:hover { color: var(--accent); }
}
.breadcrumbs [aria-current="page"] {
  max-width: 40ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
