/* Shared UI layer — the SAME components on the clinic app, the client portal and the platform cabinet
   (docs/ui-unification/02-standard.md). Colours come only from the --vs-* skin tokens (clinic skin or platform skin);
   nothing here is brand-specific. Loaded after style.css on the clinic and after platform.css on platform pages,
   so these rules win ties. Page-specific rules stay in their page / style.css. */

/* ─── 1. Long text never breaks the layout (G3/G4) ───────────────────────────────────────────────────────────────── */
/* Block containers break any over-long word (a chip number, an e-mail, a URL, one huge item name) instead of stretching the
   page. Spaces still wrap normally; `.text-nowrap` still wins. */
.alert, .card-body, .list-group-item, .modal-body, .toast-body { overflow-wrap: anywhere; }
/* Table cells: `anywhere` would also shrink every column to one letter when the table is wider than the screen, so a cell
   only breaks a word that is longer than its own cap (long values wrap at 32rem; short columns are untouched). */
.table td { overflow-wrap: break-word; max-width: 32rem; }
/* controls keep their labels whole: `anywhere` on a parent must not shrink a flex-item button to one letter per line */
.btn, .badge, .nav-link, .form-control, .form-select, .dropdown-item, .page-link { overflow-wrap: normal; }
.ui-money, .table td.text-end, .table th.text-end { font-variant-numeric: tabular-nums; }

/* ─── 2. Dialogs on a phone: full screen, header and footer always visible (G5) ─────────────────────────────────── */
@media (max-width: 575.98px) {
  .modal-dialog:not(.modal-sm):not(.ui-dialog-compact) {
    width: 100%; max-width: none; height: 100%; margin: 0;
  }
  .modal-dialog:not(.modal-sm):not(.ui-dialog-compact) .modal-content {
    height: 100%; border: 0; border-radius: 0;
  }
  /* most dialogs wrap body + footer in a <form>: it takes over the flex column so the body is the part that scrolls */
  .modal-dialog:not(.modal-sm):not(.ui-dialog-compact) .modal-content > form { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
  .modal-dialog:not(.modal-sm):not(.ui-dialog-compact) .modal-header,
  .modal-dialog:not(.modal-sm):not(.ui-dialog-compact) .modal-footer { border-radius: 0; flex-shrink: 0; }
  .modal-dialog:not(.modal-sm):not(.ui-dialog-compact) .modal-body { overflow-y: auto; }
  .modal-dialog:not(.modal-sm):not(.ui-dialog-compact) .modal-footer { flex-wrap: wrap; }
  .modal-dialog:not(.modal-sm):not(.ui-dialog-compact) .modal-footer > .btn { flex: 1 1 auto; }
  /* the appointment card / view dialogs are full-screen like every other dialog; the clinical-case pane (which assets/clinical_case_ui.js
     places beside the dialog on a desktop) becomes a bottom sheet over it, and the JS «shift» of the dialog is switched off */
  #apptViewModal .modal-dialog { transform: none !important; }
  .case-pane { left: 0 !important; right: 0; top: auto !important; bottom: 0; width: auto !important; max-height: 45vh; border-radius: .75rem .75rem 0 0; }
}

/* Page-level header rows written by hand (flex + space-between): wrap on a phone instead of pushing the page wider (G3) —
   until each page uses uiPageHeader(). A btn-group of filters scrolls inside itself. */
@media (max-width: 575.98px) {
  .container > .d-flex.justify-content-between, .container > .d-flex.align-items-center,
  .container > .d-flex > .d-flex.gap-2, .container > .d-flex > .d-flex.gap-1 { flex-wrap: wrap; gap: .5rem; }
  .btn-group:not(.btn-group-vertical):not(.dropdown) { max-width: 100%; overflow-x: auto; flex-wrap: nowrap; }
}

/* ─── 3. Touch targets (≥ 40 px) on a phone ─────────────────────────────────────────────────────────────────────── */
@media (max-width: 575.98px) {
  .btn-sm { padding-top: .5rem; padding-bottom: .5rem; }
  .form-select-sm, .form-control-sm { min-height: 40px; }
  .page-link { padding-top: .5rem; padding-bottom: .5rem; }
}

/* ─── 4. Tabs and segments are ONE scrollable row on a phone, never several wrapped rows (G9) ───────────────────── */
@media (max-width: 575.98px) {
  .nav-tabs:not(.flex-column), .nav-pills:not(.flex-column):not(.cat-lens), .ui-segment {
    flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; white-space: nowrap;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
  }
  .nav-tabs::-webkit-scrollbar, .nav-pills::-webkit-scrollbar, .ui-segment::-webkit-scrollbar { display: none; }
  .nav-tabs:not(.flex-column) > .nav-item, .nav-pills:not(.flex-column) > .nav-item { flex: 0 0 auto; }
}

/* ─── 5. Page header (uiPageHeader) ─────────────────────────────────────────────────────────────────────────────── */
.ui-page-head { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin-bottom: 1rem; }
.ui-page-title { font-size: 1.75rem; font-weight: var(--vs-heading-weight, 500); color: var(--vs-heading, inherit); margin: 0; flex: 1 1 auto; min-width: 0; }
.ui-page-title .bi { color: var(--vs-primary); margin-right: .5rem; }
.ui-page-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.ui-page-related { display: flex; flex-wrap: wrap; align-items: baseline; gap: .15rem .9rem; font-size: .85rem; color: var(--vs-text-muted, #6c757d); margin: -.5rem 0 1rem; }
.ui-page-related a { text-decoration: none; }
.ui-page-related a:hover { text-decoration: underline; }
@media (max-width: 575.98px) {
  .ui-page-title { font-size: 1.4rem; flex-basis: 100%; }
  .ui-page-actions { width: 100%; }
  .ui-page-actions > .btn-primary, .ui-page-actions > .ui-primary { flex: 1 1 auto; }
}

/* ─── 6. Statuses (uiStatus) — soft, skinnable; solid .badge.bg-* stays for counters only ──────────────────────── */
.badge-soft-neutral { background: var(--bs-secondary-bg, #e9ecef); color: var(--vs-text-muted, #5c636a); border: 1px solid var(--vs-surface-border, #dee2e6); }
.badge-soft-primary { background: var(--vs-primary-subtle); color: var(--vs-primary-emphasis); border: 1px solid var(--vs-primary-border-subtle); }
/* the clinic's legacy history statuses used fixed hex colours that ignored the skin */
.badge-cancelled { background: var(--bs-secondary-bg, #e9ecef); color: var(--vs-text-muted, #5c636a); border: 1px solid var(--vs-surface-border, #dee2e6); }
.badge-completed { background: var(--vs-info-subtle); color: var(--vs-info-emphasis); border: 1px solid var(--vs-info-border-subtle); }
.ui-status { font-weight: 600; }

/* ─── 7. KPI tile (uiStat) ──────────────────────────────────────────────────────────────────────────────────────── */
.ui-stat { display: block; height: 100%; padding: .9rem 1rem; background: var(--vs-surface-bg, #fff); border: 1px solid var(--vs-surface-border, #dee2e6);
  border-left-width: 4px; border-radius: var(--vs-card-radius, .5rem); color: inherit; text-decoration: none; }
a.ui-stat:hover { box-shadow: var(--vs-shadow, 0 2px 8px rgba(0,0,0,.08)); color: inherit; }
.ui-stat-label { font-size: .8rem; color: var(--vs-text-muted, #6c757d); }
.ui-stat-value { font-size: 1.5rem; font-weight: 700; line-height: 1.2; font-variant-numeric: tabular-nums; }
.ui-stat-hint { font-size: .78rem; color: var(--vs-text-muted, #6c757d); }
.ui-stat .bi.ui-stat-icon { float: right; font-size: 1.4rem; color: var(--vs-primary); opacity: .8; }
.ui-stat--warning { border-left-color: var(--vs-warning); }
.ui-stat--danger  { border-left-color: var(--vs-danger); }
.ui-stat--success { border-left-color: var(--vs-success); }
.ui-stat--info    { border-left-color: var(--vs-info); }

/* ─── 8. Width utilities that become full width on a phone (replace style="width:220px") ───────────────────────── */
.ui-w-sm { width: 100%; max-width: 8rem; }
.ui-w-md { width: 100%; max-width: 14rem; }
.ui-w-lg { width: 100%; max-width: 22rem; }
@media (max-width: 575.98px) { .ui-w-sm, .ui-w-md, .ui-w-lg { max-width: none; } }
/* the search box of a table toolbar */
.ui-w-search { max-width: 20rem; }
/* blocks that should not grow wider than a comfortable line (replace style="max-width:420px"); they shrink on a phone by themselves.
   xs 320px · sm 416px (sign-in cards) · md 520px · base 640px (forms) · wide 720px (readable text) · lg 960px */
.ui-measure-xs   { max-width: 20rem; }
.ui-measure-sm   { max-width: 26rem; }
.ui-measure-md   { max-width: 32.5rem; }
.ui-measure      { max-width: 40rem; }
.ui-measure-wide { max-width: 45rem; }
.ui-measure-lg   { max-width: 60rem; }

/* A heading outside a header row (a page with no action button): same look, own bottom margin */
.ui-page-title--solo { flex: none; margin-bottom: 1rem; }

/* ─── 9. Tables as cards on a phone: <table data-stack="sm"> (labels + roles are set by assets/ui.js) ───────────── */
@media (max-width: 575.98px) {
  table[data-stack="sm"], table[data-stack="sm"] tbody { display: block; width: 100%; }
  table[data-stack="sm"] thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  table[data-stack="sm"] tr {
    display: block; position: relative; margin-bottom: .6rem; padding: .35rem .75rem;
    background: var(--vs-surface-bg, #fff); border: 1px solid var(--vs-surface-border, #dee2e6); border-radius: var(--vs-card-radius, .5rem);
  }
  table[data-stack="sm"] tr[data-href], table[data-stack="sm"] tbody tr[style*="cursor"] { cursor: pointer; }
  table[data-stack="sm"] td {
    display: flex; justify-content: space-between; align-items: baseline; gap: .75rem; width: auto; max-width: none;
    padding: .3rem 0; border: 0; background: transparent; text-align: right; white-space: normal; min-width: 0; overflow-wrap: anywhere;
  }
  table[data-stack="sm"] td::before {
    content: attr(data-label); flex: 0 0 38%; max-width: 38%; text-align: left; color: var(--vs-text-muted, #6c757d); font-size: .8rem; font-weight: 400;
  }
  table[data-stack="sm"] td > * { min-width: 0; }
  /* the heading of the card: full width, no label */
  table[data-stack="sm"] td[data-stack-role="title"] { display: block; text-align: left; font-weight: 600; padding-top: .45rem; padding-bottom: .35rem; border-bottom: 1px solid var(--vs-surface-border, #dee2e6); margin-bottom: .2rem; }
  table[data-stack="sm"] td[data-stack-role="title"]::before { content: none; }
  /* a status badge column sits beside the heading */
  table[data-stack="sm"] td[data-stack-role="badge"] { position: absolute; top: .55rem; right: .75rem; padding: 0; }
  table[data-stack="sm"] td[data-stack-role="badge"]::before { content: none; }
  table[data-stack="sm"] td[data-stack-role="select"] { position: absolute; top: .55rem; right: .75rem; padding: 0; }
  table[data-stack="sm"] td[data-stack-role="select"]::before { content: none; }
  table[data-stack="sm"] tr:has(td[data-stack-role="select"]) td[data-stack-role="title"] { padding-right: 2rem; }
  table[data-stack="sm"] td[data-stack-role="actions"] { justify-content: flex-end; flex-wrap: wrap; gap: .4rem; padding-top: .5rem; border-top: 1px solid var(--vs-surface-border, #dee2e6); margin-top: .25rem; }
  table[data-stack="sm"] td[data-stack-role="actions"]::before { content: none; }
  table[data-stack="sm"] td[data-stack-role="empty"], table[data-stack="sm"] td[data-stack-role="hide"] { display: none; }
  table[data-stack="sm"] td[data-stack-role="full"] { display: block; text-align: center; }
  table[data-stack="sm"] td[data-stack-role="full"]::before, table[data-stack="sm"] td:not([data-label])::before { content: none; }
  /* a cell with several lines of its own (name + owner + phone): label above, value below, left-aligned */
  table[data-stack="sm"] td[data-stack-layout="block"] { display: block; text-align: left; }
  table[data-stack="sm"] td[data-stack-layout="block"]::before { display: block; max-width: none; margin-bottom: .1rem; }
  table[data-stack="sm"] td[data-stack-role="actions"] select, table[data-stack="sm"] td[data-stack-role="actions"] .form-select { flex: 1 1 8rem; width: auto; max-width: 100%; min-width: 0; }
  table[data-stack="sm"] td.text-nowrap, table[data-stack="sm"] td .text-nowrap { white-space: normal !important; }
  table[data-stack="sm"] td .badge { white-space: normal; }
  /* the table's own wrapper no longer needs to scroll sideways */
  .table-responsive:has(> table[data-stack="sm"]) { overflow-x: visible; }
  /* admin_table's "no match" / empty rows */
  table[data-stack="sm"] tr.d-none { display: none; }
  table[data-stack="sm"].table-hover > tbody > tr:hover > * { --bs-table-bg-state: transparent; }
}

/* ─── 10. Booking wizard stepper on a phone: only the current step, as «Шаг 2 из 5 · Врач» ───────────────────── */
@media (max-width: 575.98px) {
  .step-indicator > div:not(.step) { display: none !important; }
  .step-indicator .step:not(.active) { display: none; }
  .step-indicator .step.active { padding-left: 0; font-size: 1rem; }
  .step-indicator .step.active .step-num { display: none; }
  .step-indicator .step.active .step-of { display: inline !important; }
}

/* ─── 11. Empty list (emptyState() in includes/empty_state.php) ─────────────────────────────────────────────── */
.empty-state { text-align: center; padding: 2.5rem 1rem; color: var(--bs-secondary-color, #6c757d); }
.empty-state .empty-state-icon { font-size: 2.5rem; opacity: .55; display: block; margin-bottom: .5rem; }
.empty-state .empty-state-title { font-weight: 600; color: var(--bs-body-color, #212529); margin-bottom: .25rem; }
.empty-state .empty-state-text { max-width: 34rem; margin: 0 auto 1rem; }

/* ─── 12. Table head tint and row hover (skin tokens) — same on clinic and cabinet ─────────────────────────── */
.table th { background: var(--vs-table-head-bg); color: var(--vs-table-head-fg); font-weight: 600; }
/* A Bootstrap table-variant head (table-light/-dark/-success/…) sets its own
   --bs-table-bg/--bs-table-color, which the unconditional rule above used to
   silently paint over (docs/rebranding-and-skins/01-audit.md §B.1 #19).
   Equal specificity to `.table th` (both class+element) — placed AFTER it,
   so it wins. */
.table-light th, .table-dark th,
.table-primary th, .table-secondary th, .table-success th,
.table-danger th, .table-warning th, .table-info th {
  background-color: var(--bs-table-bg);
  color: var(--bs-table-color);
}
/* a result row in the brand colour (not a «success» green): P&L operating profit */
.table-brand { --bs-table-bg: var(--vs-primary-subtle); --bs-table-color: var(--vs-primary-emphasis); --bs-table-border-color: var(--vs-primary-border-subtle); }
.table-brand th { background-color: var(--bs-table-bg); color: var(--bs-table-color); }
.table-hover tbody tr:hover { background: var(--vs-row-hover); }

/* A tile that opens a menu: no caret (Bootstrap's dropdown-toggle arrow showed as a dark bar under the card) */
.card.dropdown-toggle::after { display: none; }

/* ─── 13. Form labels: one size, weight from the skin token (--vs-label-weight), «*» derived from `required` ─── */
.form-label { font-size: .875rem; margin-bottom: .25rem; }
.form-label.is-required::after { content: " *"; color: var(--vs-danger); }

/* ─── 14. On/off semantics (docs/ui-unification/02-standard.md §13) ────────────────────────────────────────────────
   PILL switch  = a setting the user turns on/off            (uiSwitch — .form-check.form-switch, theme-coloured when on)
   CHECKBOX     = consent, confirmation, «pick several»      (plain .form-check)
   CHECK / CROSS ICON = a state that is only SHOWN           (uiEnabled — .ui-enabled; badge-free, themed when on, grey when off) */
.ui-enabled { display: inline-flex; align-items: center; gap: .35rem; white-space: nowrap; }
.ui-enabled .bi { font-size: 1.05em; }
.ui-enabled--on .bi { color: var(--vs-control, var(--vs-primary)); }
.ui-enabled--off .bi, .ui-enabled--unknown .bi { color: var(--vs-text-muted, #6c757d); opacity: .55; }
.ui-enabled--off .ui-enabled-label, .ui-enabled--unknown .ui-enabled-label { color: var(--vs-text-muted, #6c757d); }
/* a disabled switch / checkbox is GREY even when ticked — never the theme colour */
.form-check-input:disabled:checked, .form-check-input:disabled[type=checkbox]:indeterminate { background-color: var(--vs-text-muted, #6c757d); border-color: var(--vs-text-muted, #6c757d); }
.form-switch .form-check-input:disabled { opacity: .5; }
.form-switch { min-height: 1.5rem; }
.form-switch .form-check-label { cursor: pointer; }
.form-switch .form-check-input:disabled ~ .form-check-label { cursor: default; color: var(--vs-text-muted, #6c757d); }
/* inside a coloured header / dark surface the indicator follows the surface's text colour (grey on green is unreadable) */
.card-header .ui-enabled .bi, .card-header .ui-enabled-label, .bg-dark .ui-enabled .bi, .bg-dark .ui-enabled-label, .navbar .ui-enabled .bi { color: inherit !important; opacity: 1; }
.card-header .ui-enabled--off { opacity: .8; }
/* segmented three-state control: labels never wrap */
.btn-group > .btn { white-space: nowrap; }
/* a segmented control inside a phone card scrolls inside the card instead of being clipped by it */
@media (max-width: 575.98px) {
  table[data-stack="sm"] td > form, table[data-stack="sm"] td .btn-group { min-width: 0; max-width: 100%; }
  table[data-stack="sm"] td .btn-group { overflow-x: auto; }
}

/* ─── 15. Page navigation — docs/ui-unification/04-page-layout.md ────────────────────────────────────────────────────
   B1 .ui-family  the other pages of this menu group (above the title)     B2 .ui-tabs  parts of THIS page (under the header)
   B3 .ui-toc     anchors of a long page (sticky, follows the scroll)       B4 .ui-crumbs  the way back from a page of one record
   B5 .ui-page-related / .ui-settings-btn                                   B6 .ui-segment  pills that filter a list (§4 above) */
.ui-family { margin: -.5rem 0 1rem; }
.ui-family-row { display: flex; flex-wrap: wrap; align-items: center; gap: .25rem 1.1rem; font-size: .875rem; padding-bottom: .5rem;
  border-bottom: 1px solid var(--vs-surface-border, #dee2e6); }
.ui-family-name { display: inline-flex; align-items: center; gap: .4rem; font-weight: 600; color: var(--vs-text, #212529); margin-right: .15rem; }
.ui-family-name .bi, .ui-family-toggle .bi { color: var(--vs-primary); }
.ui-family-sub { font-weight: 400; color: var(--vs-text-muted, #6c757d); }
.ui-family-link { padding: .125rem 0; text-decoration: none; color: var(--vs-link, var(--vs-primary)); }
.ui-family-link:hover { text-decoration: underline; }
.ui-family-link.is-current { color: var(--vs-text, #212529); font-weight: 600; text-decoration: none; box-shadow: inset 0 -2px 0 var(--vs-primary); }
.ui-family-phone, .ui-toc-phone { display: none; }
.ui-family-toggle { display: flex; align-items: center; gap: .4rem; width: 100%; text-align: left; font-size: .9rem; color: var(--vs-text, #212529);
  background: var(--vs-surface-bg, #fff); border: 1px solid var(--vs-surface-border, #dee2e6); border-radius: var(--vs-btn-radius, .375rem); padding: .5rem .75rem; }
.ui-family-toggle b { font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ui-family-toggle::after { margin-left: auto; }
.ui-family-toggle-group { color: var(--vs-text-muted, #6c757d); white-space: nowrap; }
.ui-family-menu { width: 100%; }
.ui-tabs { margin-bottom: 1rem; }
.ui-tabs .nav-link { display: inline-flex; align-items: center; }
.ui-tab-count { margin-left: .35rem; background: var(--vs-text-muted, #6c757d); color: #fff; font-weight: 500; }
.ui-tab-dot { margin-left: .3rem; background: var(--vs-danger, #dc3545); color: #fff; border-radius: 999px; font-size: .7rem; padding: .05rem .4rem; }
.ui-toc { position: sticky; top: 0; z-index: 1019; background: var(--vs-page-bg, #f8f9fa); padding: .5rem 0; margin: 0 0 1rem;
  border-bottom: 1px solid var(--vs-surface-border, #dee2e6); }
.ui-toc-row { display: flex; flex-wrap: wrap; gap: .375rem; }
.ui-toc-row .ui-toc-link { display: inline-flex; align-items: center; gap: .35rem; padding: .25rem .7rem; font-size: .85rem; text-decoration: none;
  color: var(--vs-text, #212529); background: var(--vs-surface-bg, #fff); border: 1px solid var(--vs-surface-border, #dee2e6); border-radius: 999px; }
.ui-toc-row .ui-toc-link.active { color: var(--vs-primary); background: var(--vs-primary-pale, #e4f0e7); border-color: var(--vs-primary); font-weight: 600; }
.ui-toc .dropdown-item.ui-toc-link { display: flex; align-items: center; gap: .4rem; }
.ui-toc-on { color: var(--vs-control, var(--vs-primary)); }
.ui-toc-off { color: var(--vs-text-muted, #6c757d); opacity: .6; }
.ui-toc-target { scroll-margin-top: 4.25rem; } /* clears the sticky anchor row; ui.js counts a section as current from the row's bottom + 48 px */
.ui-crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; font-size: .875rem; color: var(--vs-text-muted, #6c757d); margin: -.5rem 0 .75rem; }
.ui-crumbs a { text-decoration: none; }
.ui-crumbs a:hover { text-decoration: underline; }
.ui-crumbs-sep { color: #adb5bd; }
.ui-crumbs-here { color: var(--vs-text, #212529); }
.ui-crumbs-x { font-size: .65rem; }
.ui-settings-btn { padding-left: .55rem; padding-right: .55rem; }
@media (max-width: 575.98px) {
  .ui-family-row, .ui-toc-row { display: none; }
  .ui-family-phone, .ui-toc-phone { display: block; }
}
@media print { .ui-family, .ui-toc, .ui-crumbs, .ui-page-related, .ui-settings-btn { display: none !important; } }

/* ─── 15. One window for modal chains (UI.chain, docs/ui-unification/05-modal-chain.md) ─────────────────────────── */
/* Levels below the top stay "shown" for Bootstrap but are invisible (kept in layout so scroll positions and iframes survive). */
.modal.ui-chain-under { visibility: hidden !important; opacity: 0 !important; pointer-events: none !important; transition: none !important; z-index: 1040 !important; }
/* one dim layer for the whole chain: the backdrop a later level created is kept only because Bootstrap wants to remove it again */
.modal-backdrop.ui-chain-dup { opacity: 0 !important; transition: none !important; pointer-events: none; }
/* one width for every level, so the window does not jump between cards (the docked visit-card dialog keeps its own) */
.modal.ui-chain-wide .modal-dialog:not(.modal-sm):not(.modal-fullscreen):not(.ui-dialog-compact) { max-width: min(960px, calc(100vw - 1rem)); }
.ui-chain-enter .modal-dialog { animation: ui-chain-in .18s ease-out; }
@keyframes ui-chain-in { from { opacity: 0; transform: translateX(1.25rem); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .ui-chain-enter .modal-dialog { animation: none; } }

.ui-chain-bar { display: flex; align-items: center; gap: .5rem; padding: .5rem .75rem; min-height: 3rem;
  background: var(--vs-surface-bg, #fff); border-bottom: 1px solid var(--vs-surface-border, #dee2e6); border-radius: inherit; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.ui-chain-back { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; width: 2rem; height: 2rem; padding: 0;
  border: 1px solid var(--vs-surface-border, #dee2e6); border-radius: .375rem; background: transparent; color: var(--vs-text, inherit); }
.ui-chain-back:hover { background: var(--vs-primary-pale, #e9ecef); }
.ui-chain-crumbs { flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: nowrap; align-items: center; gap: .25rem; margin: 0; padding: 0; list-style: none; overflow: hidden; font-size: .9rem; }
.ui-chain-crumbs > li { flex: 0 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ui-chain-crumbs > li + li::before { content: "›"; margin-right: .25rem; color: var(--vs-text-muted, #6c757d); }
.ui-chain-crumbs > li.is-current { font-weight: 600; flex-shrink: 0; max-width: 60%; }
.ui-chain-crumb { border: 0; background: none; padding: 0; color: var(--vs-primary); max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
.ui-chain-crumb:hover { text-decoration: underline; }
.ui-chain-close { flex: 0 0 auto; margin: 0; }
.ui-chain-newtab { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; width: 2rem; height: 2rem; border: 1px solid var(--vs-surface-border, #dee2e6); border-radius: .375rem; color: var(--vs-text, inherit); text-decoration: none; }
.ui-chain-newtab:hover { background: var(--vs-primary-pale, #e9ecef); }
@media (max-width: 575.98px) { .ui-chain-newtab { width: 2.5rem; height: 2.5rem; } }
/* inside a chain the level's own title and ✕ are replaced by the bar; the rest of its header (buttons, links) stays */
.ui-chain-on > .modal-header .btn-close, .ui-chain-on > form > .modal-header .btn-close,
.ui-chain-on > .modal-header .modal-title, .ui-chain-on > form > .modal-header .modal-title { display: none; }
.ui-chain-on .modal-header.ui-chain-bare { display: none; }
@media (max-width: 575.98px) { .ui-chain-bar { flex-shrink: 0; } .ui-chain-back { width: 2.5rem; height: 2.5rem; } }
/* on a phone the bar keeps the previous step and the current one; the earlier steps are one tap on ← away */
@media (max-width: 575.98px) {
  .ui-chain-crumbs > li:not(.is-current):not(:nth-last-child(2)) { display: none; }
  .ui-chain-crumbs > li:nth-last-child(2) + li::before { content: "›"; }
  .ui-chain-crumbs > li:first-child::before { content: none; }
}

/* Questions (a small dialog you answer and leave) sit above any card or chain, with their own dimming (replaces the per-id z-index pairs) */
.modal.ui-question { z-index: 1065; }
.modal-backdrop.ui-question-backdrop { z-index: 1060; }

/* ── Chat: message box + online dot (assets/chat_compose.js; shared by clinic, client portal and cabinet) ── */
/* Message box (assets/chat_compose.js): one row by default, grows with the text, can be dragged taller. */
.chat-compose-input { resize: none; min-height: calc(1.5em + .75rem + 2px); line-height: 1.5; overflow-y: auto; }
/* the buttons beside the box keep their own height when the box grows */
.chat-compose-row { align-items: flex-end; }
.chat-compose-row > .btn { height: calc(1.5em + .75rem + 2px); padding-top: 0; padding-bottom: 0; display: inline-flex; align-items: center; justify-content: center; }
/* Drag handle on the border above the message box (assets/chat_compose.js). */
.chat-compose-grip { position: absolute; left: 0; right: 0; top: -4px; height: 9px; cursor: ns-resize; z-index: 2; touch-action: none; }
.chat-compose-grip::after { content: ""; position: absolute; left: 50%; top: 3px; width: 36px; height: 3px; margin-left: -18px; border-radius: 2px; background: currentColor; opacity: .25; transition: opacity .15s; }
/* touch: a finger needs a bigger target than a mouse (U1: 40 px targets on phones) */
@media (pointer: coarse) { .chat-compose-grip { height: 32px; top: -16px; } .chat-compose-grip::after { top: 14px; width: 48px; opacity: .4; } }
.chat-compose-grip:hover::after, body.chat-compose-dragging .chat-compose-grip::after { opacity: .6; }
body.chat-compose-dragging { cursor: ns-resize; user-select: none; }
.chat-compose-hint { font-size: .75rem; color: var(--bs-secondary-color, #6c757d); padding: .35rem .15rem 0; }
.chat-compose-hint .form-check-label { font-size: .75rem; cursor: pointer; }
/* Files waiting to be sent (ChatCompose.attachments): one removable chip each, a thumbnail for pictures. */
.chat-attach-chip { display: inline-flex; align-items: center; gap: .4rem; max-width: 100%; margin: 0 .4rem .3rem 0; padding: .15rem .45rem .15rem .2rem; border: 1px solid var(--bs-border-color); border-radius: .4rem; background: var(--bs-body-bg); }
.chat-attach-chip img { width: 32px; height: 32px; object-fit: cover; border-radius: .25rem; }
.chat-attach-chip > .bi { font-size: 1.4rem; padding-left: .25rem; }
.chat-attach-chip-name { max-width: 14rem; }
.chat-attach-chip-x { text-decoration: none; font-size: 1.2rem; line-height: 1; color: var(--bs-secondary-color); }
.chat-attach-chip-x:hover { color: var(--bs-danger); }
.chat-msg .chat-msg-text { white-space: normal; overflow-wrap: anywhere; }
.chat-online-dot { display: inline-block; width: .55rem; height: .55rem; border-radius: 50%; background: #adb5bd; flex-shrink: 0; }
.chat-online-dot.online { background: var(--vc-green-light, #28a745); }

/* Workspace tabs strip (assets/workspace_tabs.js, docs/workspace-tabs) — DESKTOP ONLY: from 1200 px with a mouse; under the top menu */
@media (min-width: 1200px) and (pointer: fine) { .ws-tabs { display: flex; } }
.ws-tabs { display: none; align-items: stretch; gap: .25rem; padding: .25rem .75rem 0; background: var(--bs-tertiary-bg, #f8f9fa); border-bottom: 1px solid var(--bs-border-color, #dee2e6); font-size: .85rem; min-height: 2.1rem; }
.ws-home, .ws-more { display: inline-flex; align-items: center; padding: 0 .55rem; color: var(--bs-secondary-color, #6c757d); background: none; border: 0; text-decoration: none; }
.ws-home:hover, .ws-more:hover { color: var(--bs-body-color); }
.ws-strip { display: flex; flex: 1 1 auto; min-width: 0; gap: .2rem; overflow: hidden; align-items: stretch; }
.ws-tab { display: flex; align-items: center; max-width: 14rem; min-width: 0; border: 1px solid transparent; border-bottom: 0; border-radius: .4rem .4rem 0 0; background: transparent; }
.ws-tab:hover { background: var(--bs-body-bg); }
.ws-tab.ws-active { background: var(--bs-body-bg); border-color: var(--bs-border-color, #dee2e6); font-weight: 600; margin-bottom: -1px; }
.ws-tab-link { display: flex; align-items: center; min-width: 0; padding: .3rem .25rem .3rem .65rem; color: var(--bs-body-color); text-decoration: none; }
.ws-tab-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ws-tab-x { display: inline-flex; align-items: center; padding: .2rem .45rem; border: 0; background: none; color: var(--bs-secondary-color, #6c757d); opacity: .55; font-size: .7rem; }
.ws-tab:hover .ws-tab-x, .ws-tab.ws-active .ws-tab-x { opacity: 1; }
.ws-tab-x:hover { color: var(--bs-danger, #dc3545); }
.ws-menu { position: fixed; z-index: 2100; min-width: 11rem; max-width: 20rem; padding: .25rem; background: var(--bs-body-bg); border: 1px solid var(--bs-border-color, #dee2e6); border-radius: .5rem; box-shadow: 0 .5rem 1rem rgba(0,0,0,.15); font-size: .85rem; }
.ws-menu-item { display: block; width: 100%; padding: .35rem .6rem; border: 0; border-radius: .35rem; background: none; color: var(--bs-body-color); text-align: left; text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ws-menu-item:hover { background: var(--bs-tertiary-bg, #f1f3f5); }
.ws-menu-head { padding: .3rem .6rem; color: var(--bs-secondary-color, #6c757d); font-size: .75rem; }

/* §15 Text on a coloured «selected» surface. Bootstrap's grey helpers (.text-muted, .text-secondary, .small hints, outline badges)
   are grey on purpose, so on the filled active row / pill / solid-coloured block they nearly vanish. One rule for every page and script. */
.list-group-item.active .text-muted, .list-group-item.active .text-secondary, .list-group-item.active .text-body-secondary, .list-group-item.active small, .list-group-item.active .small,
.nav-pills .nav-link.active .text-muted, .nav-pills .nav-link.active .small,
.dropdown-item.active .text-muted, .dropdown-item.active .small,
.btn.active .text-muted, .btn-check:checked + .btn .text-muted,
[class*="bg-primary"] .text-muted, [class*="bg-dark"] .text-muted, [class*="bg-success"] .text-muted, [class*="bg-danger"] .text-muted, [class*="bg-info"] .text-muted,
.text-bg-primary .text-muted, .text-bg-dark .text-muted, .text-bg-success .text-muted, .text-bg-danger .text-muted { color: rgba(255,255,255,.88) !important; }
.list-group-item.active .badge-soft-neutral, .list-group-item.active .badge-soft-secondary, .list-group-item.active .badge-cancelled { background: rgba(255,255,255,.9); color: #212529; border-color: transparent; }
.list-group-item.active .badge:not([class*="badge-soft"]):not(.text-bg-light) { outline: 1px solid rgba(255,255,255,.6); }
