/* BÖGGE CRM — design system. Source: sellererp.ru design spec. */

:root{
  --blue:#2563EB;
  --sky:#38BDF8;
  --cyan:#22D3EE;
  --navy:#0F172A;
  --navy-soft:#16213A;
  --bg:#F8FAFC;
  --text:#0F172A;
  --muted:#64748B;
  --muted-on-navy:#94A3B8;
  --line:#E5E9F0;
  --line-on-navy:rgba(255,255,255,0.12);
  --grad:linear-gradient(135deg,var(--blue),var(--cyan));
  --warn-bg:#FFFBEB;
  --warn-border:#FDE68A;
  --warn-text:#92400E;

  --error-bg:#FEF2F2;
  --error-border:#FECACA;
  --error-text:#B91C1C;
  --error-dot:#EF4444;

  --sidebar-w:264px;
  --sidebar-collapsed-w:72px;
}

/* ===== base / typography ===== */
body{
  font-family:'Manrope', sans-serif;
  background:var(--bg);
  color:var(--text);
}
h1,h2,h3,h4{font-weight:800; letter-spacing:-0.02em; color:var(--text);}
p{color:var(--muted);}
.text-muted-ds{color:var(--muted);}
small,.meta-text{font-size:12.5px; color:var(--muted);}

/* ===== buttons ===== */
.btn{font-weight:400; letter-spacing:-0.01em; transition:transform .15s, background-color .15s, border-color .15s, color .15s;}
.btn-grad{background:var(--grad); color:#fff; border:none;}
.btn-grad:hover{color:#fff; opacity:0.92; transform:translateY(-1px);}
.btn-grad:disabled{opacity:0.5; pointer-events:none;}
.btn-outline-navy{border:1px solid var(--line); color:var(--text); font-weight:400; background:#fff;}
.btn-outline-navy:hover{border-color:var(--blue); color:var(--blue); transform:translateY(-1px);}
.btn-outline-navy:disabled{opacity:0.6; pointer-events:none; transform:none;}
.btn-ghost-light{border:1px solid var(--line-on-navy); color:#fff; font-weight:400; background:transparent;}
.btn-ghost-light:hover{border-color:var(--cyan); color:var(--cyan); background:rgba(56,189,248,0.08); transform:translateY(-1px);}
/* destructive actions — same shape as btn-outline-navy, built on the existing error tokens (not in the source spec, added by analogy) */
.btn-outline-danger{border:1px solid var(--error-border); color:var(--error-text); font-weight:400; background:#fff;}
.btn-outline-danger:hover{border-color:var(--error-text); background:var(--error-bg); transform:translateY(-1px);}
.btn-outline-danger:disabled{opacity:0.6; pointer-events:none; transform:none;}
.btn svg{vertical-align:-3px; margin-right:6px;}
/* icon-only square button (e.g. a compact "add" action next to a filter
   row) — same footprint as .toolbar's 44px row, no text label. */
.btn-square{width:44px; padding:0 !important; display:inline-flex; align-items:center; justify-content:center; flex-shrink:0;}
.btn-square svg{margin-right:0;}
/* smaller icon-only button for inline row actions (e.g. an edit icon in a
   table row) — deliberately NOT named/using ".btn-sm": the legacy theme's
   own unscoped ".btn-sm" rule (main.css) sets padding:10px 20px, and since
   it loads after Bootstrap's ".btn-sm" it wins and inflates any button that
   uses that name to ~43px tall regardless of this file's own rules. */
.btn-icon-sm{width:30px; height:30px; padding:0 !important; border-radius:8px; display:inline-flex; align-items:center; justify-content:center; flex-shrink:0;}
.btn-icon-sm svg{margin-right:0;}
/* "add another row" affordance for a repeatable list inside a form (e.g. a
   list of address lines) — dashed so it reads as a placeholder action, not
   a regular button; sized to its own content, not the row above it. */
.btn-add-row{display:inline-flex; align-items:center; justify-content:center; gap:8px; padding:10px 16px; border:1px dashed var(--line); border-radius:10px; background:transparent; color:var(--muted); font-weight:500;}
.btn-add-row:hover{border-color:var(--blue); color:var(--blue); background:rgba(37,99,235,0.04);}
/* a labelled primary action that collapses to an icon-only .btn-square once the
   toolbar row is too narrow to spell it out — content breakpoint, see design-system.md */
@media (max-width:767px){
  .btn-add{width:44px; padding:0 !important; justify-content:center;}
  .btn-add .label{display:none;}
}

/* ===== forms ===== */
.form-label{font-weight:600; font-size:14px; margin-bottom:6px;}
.form-control{border:1px solid var(--line); border-radius:10px; padding:12px 14px; font-size:15px; background:var(--bg);}
.form-control:focus{border-color:var(--blue); box-shadow:0 0 0 3px rgba(37,99,235,0.12); background:#fff;}
.form-control.is-invalid{border-color:#DC2626 !important; background:var(--error-bg);}
/* yii\bootstrap5\ActiveField renders <select> with "form-select", not
   "form-control" — same visual language, kept as a separate rule so a
   genuine future divergence (e.g. a custom caret) doesn't fight this one. */
.form-select{border:1px solid var(--line); border-radius:10px; padding:12px 14px; font-size:15px; background-color:var(--bg);}
.form-select:focus{border-color:var(--blue); box-shadow:0 0 0 3px rgba(37,99,235,0.12); background-color:#fff;}
.form-select.is-invalid{border-color:#DC2626 !important; background-color:var(--error-bg);}
.invalid-feedback,.field-error{color:#DC2626; font-size:12px; margin-top:5px; display:none;}
.invalid-feedback.show,.field-error.show,.was-validated .invalid-feedback,.invalid-feedback:not(:empty){display:block;}
.form-summary-error{
  display:none; background:var(--error-bg); border:1px solid var(--error-border); color:var(--error-text);
  font-size:13px; font-weight:600; border-radius:10px; padding:12px 14px; margin-bottom:16px;
}
.form-summary-error.show{display:block;}
.password-wrap{position:relative;}
.password-wrap .form-control{padding-right:44px;}
.password-toggle-btn{
  position:absolute; right:10px; top:50%; transform:translateY(-50%); border:none; background:none;
  color:var(--muted); padding:4px; display:flex; cursor:pointer;
}
.password-toggle-btn:hover{color:var(--text);}
.password-toggle-btn .icon-off{display:none;}
.password-wrap.is-visible .icon-on{display:none;}
.password-wrap.is-visible .icon-off{display:flex;}

/* ===== select2 (kept as a working dependency — see project notes; this is
   just its visual skin, matched to .form-control/.form-select) =====
   Select2's real DOM nests an intermediate <span class="selection"> wrapper
   inside .select2-container, and the legacy theme's own site.css still
   targets that wrapper directly ("body .selection .select2-selection")
   with its own padding/height/font/color/background — every rule below has
   to out-specify that one, not just set a value once. */
/* select2 enhances the <select> on document-ready — until that JS runs, the
   raw element renders with browser defaults (small, unstyled), then snaps to
   the select2 box a moment later. Match its look/size up front so there's
   no visible jump. ".select2-hidden-accessible" is the class select2 itself
   adds once it has taken over, so this only ever affects the brief window
   before that. Codebase convention names select2 targets "s2-*". */
select[class*="s2-"]:not(.select2-hidden-accessible){
  height:44px; box-sizing:border-box; border:1px solid var(--line); border-radius:10px;
  background:var(--bg); padding:0 14px; font-family:'Manrope', sans-serif; font-size:14px;
  color:var(--text); appearance:none;
}
.toolbar select[class*="s2-"]:not(.select2-hidden-accessible){flex:1 1 180px; min-width:180px;}

.select2-container{width:100% !important;}
/* .selection — промежуточный <span>, который select2 вставляет между
   .select2-container и .select2-selection. Он inline-block по умолчанию
   и сам по себе НЕ наследует ширину от .select2-container (даже
   100% !important выше) — без explicit width:100% здесь select2-selection
   внутри сжимается по контенту (стрелка + пара пикселей текста), а не
   растягивается на всю колонку. Раньше это чинилось в старом site.css
   правилом ".product-list-container .select2 .selection{width:100%}" —
   работало только на страницах, у которых на обёртке был этот класс;
   /logistic/purchase/create его лишился при переезде на дизайн-систему
   2026-09-10, и select2 товара схлопнулся до одной стрелки. Здесь то же
   самое, но не завязано ни на какой класс-обёртку. */
.select2-container .selection{display:block; width:100%;}
.select2-container .selection .select2-selection{
  min-height:44px; border-radius:10px; border:1px solid var(--line) !important;
  background:var(--bg) !important; font-family:'Manrope', sans-serif !important;
  font-size:14px !important; color:var(--text) !important; display:flex; align-items:center;
  box-sizing:border-box; position:relative; cursor:pointer;
  transition:border-color .15s, background-color .15s;
}
/* --multiple's "search field" is a real <input> filling most of the box, so
   without this the browser shows a text caret on hover instead of the same
   pointer cursor every other dropdown in the row has. */
.select2-container .selection .select2-selection--multiple .select2-search__field{cursor:pointer;}
.select2-container--open .selection .select2-selection--multiple .select2-search__field{cursor:text;}
.select2-container--open .selection .select2-selection,
.select2-container--focus .selection .select2-selection{
  border-color:var(--blue) !important; background:#fff !important;
  box-shadow:0 0 0 3px rgba(37,99,235,0.12);
}
.select2-container .selection .select2-selection--single{padding:0 !important;}
.select2-container .selection .select2-selection--single .select2-selection__rendered{
  line-height:42px !important; padding-left:14px !important; padding-right:34px !important; color:var(--text) !important;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; display:block;
}
.select2-container .selection .select2-selection--single .select2-selection__placeholder{color:var(--muted) !important;}
.select2-container .selection .select2-selection--single .select2-selection__arrow{height:42px; right:10px;}
.select2-container .selection .select2-selection--single .select2-selection__arrow b{border-color:var(--muted) transparent transparent transparent;}
.select2-container--open .selection .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent var(--muted) transparent;}
/* select2's own theme draws a dropdown arrow only on --single — a
   --multiple box has no arrow element in its DOM at all, which is why it
   read as a different, plainer kind of control next to Статус/Наличие РД.
   Draw a matching one with a pseudo-element instead. */
.select2-container .selection .select2-selection--multiple{padding:0 34px 0 10px !important; position:relative;}
.select2-container .selection .select2-selection--multiple::after{
  content:''; position:absolute; right:14px; top:50%; margin-top:-2px;
  width:0; height:0; pointer-events:none;
  border-style:solid; border-width:5px 4px 0 4px; border-color:var(--muted) transparent transparent transparent;
}
.select2-container--open .selection .select2-selection--multiple::after{
  margin-top:-3px; border-width:0 4px 5px 4px; border-color:transparent transparent var(--muted) transparent;
}
.select2-container .selection .select2-selection--multiple .select2-selection__rendered{
  margin:0 !important; padding:0 !important; list-style:none;
  display:flex; flex-wrap:wrap; align-items:center; gap:4px; max-height:100%; overflow:hidden;
}
.select2-container .selection .select2-selection--multiple .select2-selection__placeholder{color:var(--muted); font-size:14px;}
/* the multi-select's placeholder isn't styled text — it's the native
   "placeholder" attribute on the inline search <input> select2 nests inside
   the __rendered list, which otherwise keeps browser-default input metrics
   (its own font-size/line-height/padding), sitting visibly lower and in a
   different size than every other box's text. */
.select2-container .selection .select2-selection--multiple .select2-search--inline{margin:0; padding:0;}
.select2-container .selection .select2-selection--multiple .select2-search__field{
  margin:0 !important; padding:0 !important; border:none !important; background:transparent !important;
  font-family:'Manrope', sans-serif !important; font-size:14px !important; line-height:20px !important;
  height:20px !important; color:var(--text) !important; box-shadow:none !important; vertical-align:middle;
}
.select2-selection__choice{
  background:rgba(37,99,235,0.08) !important; border:none !important; color:var(--blue) !important;
  border-radius:6px !important; padding:2px 6px !important; font-size:12.5px !important; font-weight:600;
  margin:0 !important; display:flex !important; align-items:center; gap:4px;
}
.select2-selection__choice__remove{color:var(--blue) !important; border:none !important; margin-right:2px !important;}
.select2-selection__choice__remove:hover{background:transparent !important; color:var(--error-text) !important;}

.select2-dropdown{
  border:1px solid var(--line) !important; border-radius:12px !important; overflow:hidden;
  box-shadow:0 10px 24px rgba(15,23,42,0.1); font-family:'Manrope', sans-serif;
}
.select2-search--dropdown{padding:8px !important;}
.select2-search--dropdown .select2-search__field{
  border:1px solid var(--line) !important; border-radius:8px !important; padding:8px 12px !important;
  font-family:'Manrope', sans-serif; font-size:14px; outline:none;
}
.select2-search--dropdown .select2-search__field:focus{border-color:var(--blue) !important;}
.select2-results__option{padding:9px 14px !important; font-size:14px;}
.select2-container--default .select2-results__option--highlighted[aria-selected]{
  background:rgba(37,99,235,0.06) !important; color:var(--blue) !important;
}
.select2-container--default .select2-results__option[aria-selected="true"]{
  background:var(--bg) !important; color:var(--text) !important; font-weight:600;
}
/* Превью товара внутри select2 (.product-select, site.js select2Config)
   рисует картинку+артикул+название через templateResult/templateSelection
   с классами .img-flag (в списке результатов) и .selected-text-flag/
   .selected-img-flag/.selected-text-value (в уже выбранном значении).
   Без ограничения размера реальное фото товара (не квадратная иконка!)
   рендерится в свой естественный пиксельный размер и перекрывает соседние
   поля формы — это и произошло на /logistic/purchase/create. Раньше
   сайзинг для выбранного значения жил только в старом site.css под
   классом .product-list-container, которого на новых страницах дизайн-
   системы больше нет. object-fit:cover — фото обрезается по квадрату, а
   не сжимается с искажением пропорций.

   ⚠️ Мало было один раз ограничить картинку — .select2-selection__rendered
   (родитель) сам по себе display:block с центровкой через line-height, а
   не flex; наш flex-контент внутри него садится по base-line, а не по
   центру, и не сжимается — отсюда съезд по вертикали и наезд на стрелку
   открытия одновременно. :has() — чтобы это включалось только для select2
   с картинкой, а не ломало центровку обычных текстовых select2 (Магазин/
   Склад), у которых родительский line-height и так работает исправно. */
.select2-selection__rendered:has(.selected-text-flag){display:flex !important; align-items:center;}
.selected-text-flag{display:flex; align-items:center; gap:8px; min-width:0; flex:1;}
.selected-text-value{overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0;}
.selected-img-flag{width:24px; height:24px; object-fit:cover; border-radius:4px; flex-shrink:0;}
.img-flag{width:24px; height:24px; object-fit:cover; border-radius:4px; margin-right:8px; flex-shrink:0; vertical-align:middle;}
/* Иконка-крестик в кнопке удаления строки товара: общее правило .btn svg
   добавляет margin-right:6px (отступ под текст в обычных кнопках) — на
   кнопке только-с-иконкой это тот же самый чужой отступ, что раньше уже
   один раз ловили и чинили у .product-list-container .remove-product svg;
   тут та же причина, тот же сброс. */
.remove-product svg{margin:0;}

/* ===== status pill ===== */
.status-pill{display:inline-flex; align-items:center; gap:6px; font-size:12px; font-weight:700; padding:4px 11px; border-radius:100px; white-space:nowrap;}
.status-pill .dot{width:7px; height:7px; border-radius:50%; flex-shrink:0;}
.status-success{background:#EFF9F1; color:#15803D;} .status-success .dot{background:#22C55E;}
.status-info{background:#EFF6FF; color:#1D4ED8;} .status-info .dot{background:#3B82F6;}
.status-warning{background:var(--warn-bg); color:var(--warn-text);} .status-warning .dot{background:#F59E0B;}
.status-neutral{background:#F1F5F9; color:#475569;} .status-neutral .dot{background:#94A3B8;}
.status-error{background:var(--error-bg); color:var(--error-text);} .status-error .dot{background:var(--error-dot);}

/* ===== page tabs (switch between views inside one card-soft, e.g.
   Финансы: Транзакции / Сводка по бюджетам — a real navigation, not JS
   toggling, so the active one is just whichever page rendered it) ===== */
.page-tabs{display:flex; align-items:center; gap:22px; margin-bottom:20px; border-bottom:1px solid var(--line);}
.page-tabs a{padding:0 0 12px; font-size:14.5px; font-weight:700; color:var(--muted); text-decoration:none; border-bottom:2px solid transparent; margin-bottom:-1px;}
.page-tabs a:hover{color:var(--text);}
.page-tabs a.active{color:var(--blue); border-bottom-color:var(--blue);}
/* доп. контроль справа от вкладок (выбор года, кнопки действий и т.п.) —
   на той же строке, что и сами вкладки, а не отдельным блоком под ними. */
.page-tabs-extra{margin-left:auto; display:flex; align-items:center; gap:10px; padding-bottom:8px;}

/* ===== cards ===== */
.card-soft{background:#fff; border:1px solid var(--line); border-radius:16px; padding:24px;}
.stat-box{background:var(--bg); border:1px solid var(--line); border-radius:12px; padding:16px;}
.stat-box .lbl{font-size:11px; font-weight:700; color:var(--muted); text-transform:uppercase; letter-spacing:0.04em;}
.stat-box .val{font-size:24px; font-weight:800; margin-top:4px;}
.stat-box .val.up{color:var(--blue);}
.stat-box .val.down{color:var(--error-text);}
/* same component, tighter — for a counters row that competes with a data
   table for vertical space, where fitting more rows matters more than the
   full-size default. */
.stat-box.is-compact{padding:8px 12px; border-radius:10px;}
.stat-box.is-compact .lbl{font-size:10px;}
.stat-box.is-compact .val{font-size:17px; margin-top:2px;}
.list-card{
  background:#fff; border:1px solid var(--line); border-radius:14px; padding:18px 20px;
  display:flex; align-items:center; gap:16px; flex-wrap:wrap;
  transition:transform .15s, box-shadow .15s;
}
.list-card:hover{transform:translateY(-2px); box-shadow:0 10px 24px rgba(15,23,42,0.07);}
.entity-icon{width:42px; height:42px; border-radius:11px; display:flex; align-items:center; justify-content:center; color:#fff; font-weight:800; font-size:14px; flex-shrink:0;}
.icon-box{width:44px; height:44px; border-radius:12px; display:flex; align-items:center; justify-content:center; background:var(--grad); color:#fff; flex-shrink:0;}

/* ===== tables ===== */
.table-scroll{overflow-x:auto; border:1px solid var(--line); border-radius:14px; background:#fff;}
.data-table{width:100%; border-collapse:collapse; font-size:13.5px;}
.data-table th{
  text-align:center; font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:0.03em; color:var(--muted);
  padding:12px 16px; border-bottom:1px solid var(--line); white-space:nowrap;
}
.data-table td{padding:12px 16px; border-bottom:1px solid var(--line); vertical-align:middle;}
.data-table tbody tr:last-child td{border-bottom:none;}
.data-table tbody tr:hover{background:var(--bg);}
/* group-header row inside a data-table, e.g. Финансы → Сводка по бюджетам
   splitting Доходные/Расходные — a full-width label row, not real data */
.data-table .group-row td{text-align:left; font-weight:700;}
.data-table .group-row.income td{background:#EFF9F1; color:#15803D;}
.data-table .group-row.outcome td{background:var(--error-bg); color:var(--error-text);}

/* ===== pagination ===== */
.pagination-row{display:flex; align-items:center; justify-content:space-between; gap:12px; margin-top:16px; flex-wrap:wrap;}
.pagination-info{font-size:12.5px; color:var(--muted);}
.pagination-controls{display:flex; align-items:center; gap:6px;}
.page-btn{
  border:1px solid var(--line); background:#fff; border-radius:8px; width:32px; height:32px; font-size:13px; font-weight:600;
  color:var(--text); cursor:pointer; display:flex; align-items:center; justify-content:center; text-decoration:none;
}
.page-btn:hover:not(:disabled){border-color:var(--blue); color:var(--blue);}
.page-btn:disabled,.page-btn.disabled{opacity:0.4; cursor:not-allowed; pointer-events:none;}
.page-btn.active{background:var(--grad); border-color:transparent; color:#fff;}

/* ===== toolbar / search / filters ===== */
/* every direct child (search box, selects, select2, buttons) is pinned to
   the same 44px so the row reads as one straight line — left unset, each
   control resolves its own height from its own padding/line-height and they
   never land on the same pixel, which is what "кривые косые" was. */
.toolbar{display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-bottom:18px;}
.toolbar .search-wrap{position:relative; flex:1; min-width:220px; height:44px;}
.toolbar .search-wrap svg{position:absolute; left:13px; top:50%; transform:translateY(-50%); width:16px; height:16px; stroke:var(--muted); pointer-events:none;}
.toolbar input[type="search"],.toolbar input.search-input{width:100%; height:100%; box-sizing:border-box; border:1px solid var(--line); border-radius:10px; padding:0 14px 0 38px; font-size:14px; background:var(--bg);}
.toolbar input[type="search"]:focus,.toolbar input.search-input:focus{border-color:var(--blue); box-shadow:0 0 0 3px rgba(37,99,235,0.12); background:#fff; outline:none;}
.toolbar .btn{height:44px; padding-top:0; padding-bottom:0; display:inline-flex; align-items:center;}
.toolbar select.form-control,
.toolbar select.form-select,
.toolbar input.form-control{height:44px; padding-top:0; padding-bottom:0; min-width:130px;}
.toolbar .date-range{display:flex; align-items:center; gap:8px;}
.toolbar .date-range input.form-control{width:130px;}
.toolbar .date-range .sep{color:var(--muted); font-size:13px;}
.filter-chip{
  border:1px solid var(--line); background:#fff; border-radius:100px; padding:8px 16px;
  font-size:13px; font-weight:700; color:var(--muted); cursor:pointer; display:inline-flex; align-items:center; gap:7px;
  transition:border-color .15s, color .15s, background-color .15s;
}
.filter-chip:hover{border-color:var(--blue); color:var(--text);}
.filter-chip.active{border-color:var(--blue); background:rgba(37,99,235,0.06); color:var(--blue);}

/* ===== empty state ===== */
.empty-state{text-align:center; padding:48px 24px;}
.empty-state .icon-wrap{
  width:56px; height:56px; border-radius:14px; background:var(--bg); border:1px solid var(--line);
  display:flex; align-items:center; justify-content:center; margin:0 auto 16px;
}
.empty-state .icon-wrap svg{width:26px; height:26px; stroke:var(--muted);}

/* ===== modal shell (Bootstrap .modal, restyled) — see design-system.md
   "Модальные окна" for the full markup this pairs with. One shared shell
   (#product-modal) is reused across pages for several kinds of content
   (product lists, cargo, build info) — only .content and #product-modal-title
   change per open, so the chrome below has to stay generic. ===== */
.modal-content.card-soft{padding:0; overflow:hidden;}
.modal-header-ds{
  display:flex; align-items:center; justify-content:space-between; gap:16px;
  padding:20px 24px; border-bottom:1px solid var(--line);
}
.modal-header-ds h3{margin:0; font-size:17px;}
.modal-body-ds{padding:24px;}
.modal-close-btn{
  width:32px; height:32px; border-radius:8px; border:none; background:transparent; color:var(--muted);
  display:flex; align-items:center; justify-content:center; cursor:pointer; flex-shrink:0;
  transition:background-color .15s, color .15s;
}
.modal-close-btn:hover{background:var(--bg); color:var(--text);}

/* ===== banners / hints ===== */
.warn-banner{
  display:flex; align-items:center; gap:14px; flex-wrap:wrap;
  background:var(--warn-bg); border:1px solid var(--warn-border); color:var(--warn-text);
  border-radius:14px; padding:14px 18px; margin-bottom:20px;
}
.result-banner{border-radius:12px; padding:14px 16px; font-size:13.5px; margin-bottom:20px; display:none;}
.result-banner.show{display:block;}
.result-banner.error{background:var(--error-bg); border:1px solid var(--error-border); color:var(--error-text);}
.result-banner.success{background:#EFF6FF; border:1px solid #BFDBFE; color:#1D4ED8;}
.info-hint-btn{
  width:18px; height:18px; border-radius:50%; border:1px solid var(--line); background:var(--bg);
  color:var(--muted); font-size:11px; font-weight:800; display:flex; align-items:center; justify-content:center;
  cursor:pointer; flex-shrink:0; line-height:1;
}
.info-hint-box{display:none; background:var(--bg); border:1px solid var(--line); border-radius:10px; padding:10px 14px; font-size:12.5px; color:var(--muted); margin:8px 0 16px; line-height:1.5;}
.info-hint-box.show{display:block;}

/* ===== switch ===== */
.switch{position:relative; display:inline-block; width:44px; height:26px; flex-shrink:0;}
.switch input{opacity:0; width:0; height:0;}
.switch-track{position:absolute; inset:0; background:var(--line); border-radius:100px; cursor:pointer; transition:background-color .15s;}
.switch-track::before{content:""; position:absolute; width:20px; height:20px; left:3px; top:3px; background:#fff; border-radius:50%; transition:transform .15s; box-shadow:0 1px 3px rgba(15,23,42,0.25);}
.switch input:checked + .switch-track{background:var(--grad);}
.switch input:checked + .switch-track::before{transform:translateX(18px);}
.switch input:disabled + .switch-track{opacity:0.6; cursor:not-allowed;}

/* ===== spinner ===== */
.icon-btn.spinning svg{animation:iconSpin 0.8s linear infinite;}
@keyframes iconSpin{ from{transform:rotate(0deg);} to{transform:rotate(360deg);} }

/* ===== logo ===== */
.logomark{width:32px; height:32px; border-radius:8px; background:var(--grad); display:flex; align-items:center; justify-content:center; flex-shrink:0;}
.logomark svg{width:18px; height:18px; stroke:#fff;}
.logo-word{font-size:18px; font-weight:800; color:var(--text); white-space:nowrap;}
.logo-word b{color:var(--blue);}
.logomark-lg{width:36px; height:36px; border-radius:9px;}
.logomark-lg svg{width:20px; height:20px;}
.logo-word-lg{font-size:20px;}

/* =========================================================
   Cabinet shell (sidebar + topbar) — new classes, deliberately
   not reusing the legacy theme's names to avoid main.css bleed.
   ========================================================= */
.cabinet-sidebar{
  position:fixed; top:0; left:0; bottom:0; width:var(--sidebar-w); background:#fff;
  border-right:1px solid var(--line); overflow-y:auto; z-index:1030;
  transition:width .15s, transform .15s;
  display:flex; flex-direction:column;
}
.cabinet-sidebar .sidebar-logo{
  display:flex; align-items:center; gap:10px; height:64px; padding:0 20px; box-sizing:border-box; flex-shrink:0;
}
.cabinet-sidebar .sidebar-logo .logo-word{overflow:hidden; transition:opacity .1s;}
.cabinet-sidebar nav{padding:8px 12px 16px; flex:1;}
/* yii\bootstrap5\Nav renders a plain "nav-link" class on leaf items, but on
   items with children the theme's own linkOptions (data-bs-toggle=collapse)
   blocks Yii's default class merge, so those links render as "collapsed"
   only — and a couple of sub-items override it again to "q". IMPORTANT: the
   "collapsed" class is not a static hook — Bootstrap's own Collapse JS
   toggles it (and aria-expanded) on the trigger every time the target
   show/hides, so styling keyed on ".collapsed" disappears the instant a
   section opens, and the row visibly snaps back to unstyled inline markup.
   `data-bs-toggle="collapse"` is the one attribute Bootstrap never touches —
   use that as the stable hook instead. */
.cabinet-sidebar nav a.nav-link,
.cabinet-sidebar nav a[data-bs-toggle="collapse"],
.cabinet-sidebar nav a.q{
  display:flex !important; align-items:center; gap:12px; padding:10px 12px; border-radius:10px;
  color:var(--muted) !important; font-size:14px; font-weight:600; text-decoration:none !important;
  transition:background-color .15s, color .15s;
}
.cabinet-sidebar nav a.nav-link svg,
.cabinet-sidebar nav a[data-bs-toggle="collapse"] svg,
.cabinet-sidebar nav a.q svg{flex-shrink:0;}
.cabinet-sidebar nav a.nav-link:hover,
.cabinet-sidebar nav a[data-bs-toggle="collapse"]:hover,
.cabinet-sidebar nav a.q:hover{background:var(--bg); color:var(--text) !important;}
.cabinet-sidebar .nav-item.active > a,
.cabinet-sidebar nav a.active{background:rgba(37,99,235,0.06); color:var(--blue) !important;}
/* parent rows only toggle a submenu (href="#") — a chevron marks that so they
   don't read as a destination link the way real nav-link/q items do. */
.cabinet-sidebar nav a[data-bs-toggle="collapse"]::after{
  content:''; width:7px; height:7px; margin-left:auto; flex-shrink:0;
  border-right:1.5px solid currentColor; border-bottom:1.5px solid currentColor;
  transform:rotate(45deg); transition:transform .15s; opacity:0.6;
}
.cabinet-sidebar nav a[data-bs-toggle="collapse"][aria-expanded="true"]::after{transform:rotate(-135deg);}
/* the current page's own link shouldn't re-fire a full navigation on repeat
   clicks — parent toggles (a[data-bs-toggle="collapse"]) are unaffected, they never carry the
   plain "active" class (see isItemActive() note above). */
.cabinet-sidebar nav a.nav-link.active,
.cabinet-sidebar nav a.q.active{pointer-events:none; cursor:default;}
/* sub-menus: Nav's dropdownOptions always sets id="ddmenu_*", but its class
   is only "collapse" (closed) or blank (open) — no stable class to hook.
   NOTE: this selector's specificity (0,2,1) beats Bootstrap's own
   ".collapse:not(.show){display:none}" (0,2,0) — setting `display`
   unconditionally here silently defeated Bootstrap's own hide/show and left
   every section permanently expanded. Only force `display:flex` for the
   states that should actually be visible; a plain "collapse" class (closed,
   not yet toggled open) is left alone so Bootstrap's own rule still hides it. */
.cabinet-sidebar nav [id^="ddmenu_"]{
  list-style:none; margin:0; padding-left:44px; flex-direction:column; gap:2px;
  padding-top:4px; padding-bottom:4px;
}
.cabinet-sidebar nav [id^="ddmenu_"]:not(.collapse),
.cabinet-sidebar nav [id^="ddmenu_"].show{display:flex;}
.cabinet-sidebar nav [id^="ddmenu_"] a{font-size:13.5px !important; font-weight:500 !important; padding:7px 10px !important;}
.cabinet-sidebar .msg-count{
  background:var(--grad); color:#fff; font-size:10.5px; font-weight:700; border-radius:100px;
  padding:1px 6px; margin-left:6px;
}
.cabinet-sidebar .logout-row{border-top:1px solid var(--line); padding:12px; flex-shrink:0;}
.cabinet-sidebar .logout-row button{
  width:100%; display:flex; align-items:center; gap:10px; padding:9px 12px; border-radius:10px;
  border:none; background:none; color:var(--muted); font-size:13.5px; font-weight:600; text-align:left;
}
.cabinet-sidebar .logout-row button:hover{background:var(--error-bg); color:var(--error-text);}

.cabinet-topbar{
  position:sticky; top:0; z-index:1020; height:64px; flex-shrink:0; display:flex; align-items:center; gap:14px;
  padding:0 24px; background:rgba(248,250,252,0.9); backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
  border-bottom:1px solid var(--line);
}
.cabinet-topbar .sidebar-toggle-btn{
  border:1px solid var(--line); background:#fff; border-radius:8px; width:34px; height:34px;
  display:flex; align-items:center; justify-content:center; color:var(--text); flex-shrink:0;
}
.cabinet-topbar .sidebar-toggle-btn:hover{border-color:var(--blue); color:var(--blue);}
.cabinet-page-title{margin:0; font-size:18px; font-weight:800; letter-spacing:-0.02em; color:var(--text);}
.cabinet-topbar .topbar-user{margin-left:auto; font-size:13.5px; font-weight:600; color:var(--muted);}

.cabinet-main{margin-left:var(--sidebar-w); min-height:100vh; display:flex; flex-direction:column; transition:margin-left .15s;}
.cabinet-content{padding:28px;}
.cabinet-overlay{display:none; position:fixed; inset:0; background:rgba(15,23,42,0.4); z-index:1025;}
.cabinet-overlay.active{display:block;}

/* desktop icon-collapse */
body.sidebar-collapsed .cabinet-sidebar{width:var(--sidebar-collapsed-w);}
body.sidebar-collapsed .cabinet-sidebar .logo-word,
body.sidebar-collapsed .cabinet-sidebar nav a.nav-link span.text,
body.sidebar-collapsed .cabinet-sidebar nav a[data-bs-toggle="collapse"] span.text,
body.sidebar-collapsed .cabinet-sidebar nav a.q span.text,
body.sidebar-collapsed .cabinet-sidebar nav [id^="ddmenu_"]{display:none;}
body.sidebar-collapsed .cabinet-sidebar nav a.nav-link,
body.sidebar-collapsed .cabinet-sidebar nav a[data-bs-toggle="collapse"],
body.sidebar-collapsed .cabinet-sidebar nav a.q{justify-content:center !important;}
/* the chevron's margin-left:auto fights justify-content:center once the
   label text is gone, so parent-item icons drift off-center relative to
   leaf items — the chevron is meaningless anyway while collapsed. */
body.sidebar-collapsed .cabinet-sidebar nav a[data-bs-toggle="collapse"]::after{display:none;}
body.sidebar-collapsed .cabinet-sidebar .logout-row button span.label{display:none;}
body.sidebar-collapsed .cabinet-main{margin-left:var(--sidebar-collapsed-w);}

@media (max-width:991px){
  .cabinet-sidebar{transform:translateX(-100%);}
  .cabinet-sidebar.mobile-open{transform:translateX(0); width:var(--sidebar-w);}
  .cabinet-main,body.sidebar-collapsed .cabinet-main{margin-left:0;}
  body.sidebar-collapsed .cabinet-sidebar{width:var(--sidebar-w);}
  body.sidebar-collapsed .cabinet-sidebar .logo-word,
  body.sidebar-collapsed .cabinet-sidebar nav a.nav-link span.text,
  body.sidebar-collapsed .cabinet-sidebar nav a[data-bs-toggle="collapse"] span.text,
  body.sidebar-collapsed .cabinet-sidebar nav a.q span.text,
  body.sidebar-collapsed .cabinet-sidebar .logout-row button span.label{display:inline;}
  body.sidebar-collapsed .cabinet-sidebar nav [id^="ddmenu_"]{display:flex;}
  body.sidebar-collapsed .cabinet-sidebar nav a.nav-link,
  body.sidebar-collapsed .cabinet-sidebar nav a[data-bs-toggle="collapse"],
  body.sidebar-collapsed .cabinet-sidebar nav a.q{justify-content:flex-start !important;}
  .cabinet-content{padding:18px;}
}

/* ===== ds-select: vanilla-JS dropdown (single + multiple), see
   frontend/web/js/ds-select.js — the reusable replacement for select2 where
   its own single/multiple split can't be reconciled into one consistent
   look and interaction. ===== */
.ds-select{position:relative; flex:1 1 180px; min-width:180px;}
.ds-select__native{position:absolute; opacity:0; width:1px; height:1px; pointer-events:none;}
.ds-select__trigger{
  width:100%; height:44px; box-sizing:border-box; display:flex; align-items:center; gap:6px;
  border:1px solid var(--line); border-radius:10px; background:var(--bg); cursor:pointer;
  padding:0 34px 0 14px; font-family:'Manrope', sans-serif; font-size:14px; color:var(--text);
  position:relative; text-align:left; transition:border-color .15s, background-color .15s;
}
.ds-select__trigger:hover{border-color:var(--blue);}
.ds-select.is-open .ds-select__trigger,
.ds-select__trigger:focus{
  border-color:var(--blue); background:#fff; box-shadow:0 0 0 3px rgba(37,99,235,0.12); outline:none;
}
.ds-select__value{
  flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  display:flex; flex-wrap:nowrap; align-items:center; gap:4px;
}
.ds-select__value.is-placeholder{color:var(--muted); white-space:nowrap;}
.ds-select__count{color:var(--text); font-weight:600; white-space:nowrap;}
.ds-select__arrow{
  position:absolute; right:12px; top:50%; margin-top:-2px; width:0; height:0; pointer-events:none;
  border-style:solid; border-width:5px 4px 0 4px; border-color:var(--muted) transparent transparent transparent;
  transition:transform .15s;
}
.ds-select.is-open .ds-select__arrow{transform:rotate(180deg); margin-top:-3px;}
/* single-select clear ("×"): reserve room next to the arrow so a chosen
   value can be unset without opening the panel — its list never re-offers
   the blank prompt option (see ds-select.js realOptions()). */
.ds-select--single .ds-select__trigger{padding-right:54px;}
.ds-select__clear{
  position:absolute; right:28px; top:50%; transform:translateY(-50%);
  width:16px; height:16px; display:flex; align-items:center; justify-content:center;
  border-radius:50%; color:var(--muted); font-size:15px; line-height:1; cursor:pointer;
}
.ds-select__clear:hover{background:var(--bg); color:var(--error-text);}
.ds-select__tag{
  background:rgba(37,99,235,0.08); color:var(--blue); border-radius:6px; padding:2px 6px;
  font-size:12.5px; font-weight:600; display:inline-flex; align-items:center; gap:4px;
}
.ds-select__tag-remove{cursor:pointer; line-height:1;}
.ds-select__tag-remove:hover{color:var(--error-text);}
.ds-select__panel{
  position:absolute; top:calc(100% + 4px); left:0; min-width:100%; width:max-content; max-width:320px; z-index:1050;
  background:#fff; border:1px solid var(--line); border-radius:12px; box-shadow:0 10px 24px rgba(15,23,42,0.1);
  overflow:hidden; font-family:'Manrope', sans-serif;
}
.ds-select__search-wrap{padding:8px; border-bottom:1px solid var(--line);}
.ds-select__search{
  width:100%; box-sizing:border-box; border:1px solid var(--line); border-radius:8px; padding:8px 12px;
  font-family:'Manrope', sans-serif; font-size:14px; outline:none; background:#fff;
}
.ds-select__search:focus{border-color:var(--blue);}
.ds-select__list{list-style:none; margin:0; padding:4px; max-height:240px; overflow-y:auto;}
.ds-select__option{padding:9px 14px; font-size:14px; border-radius:8px; cursor:pointer; color:var(--text);}
.ds-select__option:hover{background:rgba(37,99,235,0.06); color:var(--blue);}
.ds-select__option.is-selected{background:var(--bg); font-weight:600;}
.ds-select__empty{padding:12px 14px; font-size:13px; color:var(--muted); text-align:center;}

/* ===== auth pages ===== */
.auth-shell{min-height:100vh; display:flex; align-items:center; justify-content:center; background:var(--bg); padding:24px;}
.auth-card{width:100%; max-width:400px; background:#fff; border:1px solid var(--line); border-radius:20px; padding:32px; box-shadow:0 24px 60px rgba(15,23,42,0.08);}
.auth-card .sidebar-logo{display:flex; align-items:center; gap:10px; margin-bottom:24px;}
.auth-card h1{font-size:22px; margin-bottom:4px;}
.auth-card .auth-sub{font-size:13.5px; color:var(--muted); margin-bottom:24px;}
.auth-card .auth-foot{margin-top:18px; font-size:13px; color:var(--muted); text-align:center;}
.auth-card .auth-foot a{color:var(--blue); font-weight:600; text-decoration:none;}

/* ===== compact person cell (avatar + name/role/status), e.g. employee list ===== */
.avatar{
  width:38px; height:38px; border-radius:50%; background:var(--bg); border:1px solid var(--line);
  display:flex; align-items:center; justify-content:center; font-weight:800; font-size:13px;
  color:var(--text); flex-shrink:0;
}
.who-cell{display:flex; align-items:center; gap:12px; text-align:left;}
.who-cell .who-info{min-width:0; text-align:left;}
/* name/role are single-line + ellipsis on purpose: letting either wrap makes
   the status pill land at a different height row to row, which reads as the
   whole row "jumping" when scanning down the column. A rare long value still
   has its full text in the title tooltip. */
.who-cell .name{font-weight:700; font-size:13.5px; max-width:200px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.who-cell .role{font-size:12px; color:var(--muted); margin-top:1px; max-width:200px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.who-cell .status-pill{margin-top:5px;}

/* block + inline-icon, not flexbox — see .doc-link's comment above, same
   pattern (icon + text row) and treated the same way for the same reason. */
.contact-line{display:block; text-align:left; font-size:13px;}
.contact-line svg{display:inline-block; vertical-align:-2px; margin-right:6px; stroke:var(--muted);}
.contact-line + .contact-line{margin-top:3px;}

/* read-only weekly schedule dots, e.g. employee list — see .day-toggle below for the editable form version */
.day-dot-row{display:flex; gap:3px; margin-bottom:5px;}
.day-dot{
  width:19px; height:19px; border-radius:6px; font-size:9.5px; font-weight:800;
  display:flex; align-items:center; justify-content:center; color:var(--muted); background:var(--bg);
}
.day-dot.on{background:rgba(37,99,235,0.08); color:var(--blue);}

.amount-pair{display:flex; gap:16px;}
.amount-pair .lbl{font-size:10.5px; color:var(--muted); text-transform:uppercase; letter-spacing:0.03em; margin-bottom:1px;}
.amount-pair .val{font-size:13px; font-weight:700; font-variant-numeric:tabular-nums;}

/* plain block + inline-icon on purpose, NOT flexbox: two earlier flex-based
   attempts here (display:flex, then display:flex + explicit width:100% /
   justify-content:flex-start) both still rendered off-centre-left on a real
   production screen, never reproduced in any browser tested locally. Block
   flow + text-align:left + an inline-block icon has no equivalent "which
   axis, which alignment property" ambiguity for a browser to get wrong. */
.doc-link{display:block; text-align:left; font-size:12.5px; color:var(--blue); text-decoration:none; font-weight:600;}
.doc-link svg{display:inline-block; vertical-align:-2px; margin-right:5px; stroke:var(--blue);}
.doc-link + .doc-link{margin-top:4px;}

/* ===== table row → expandable detail panel (click a row for the rest of its fields) =====
   same 30×30 footprint as .btn-icon-sm (the edit button next to it) — a pair of
   equal-sized icon actions reads as one unit instead of two mismatched controls. */
.detail-toggle{
  width:30px; height:30px; padding:0; border-radius:8px; border:1px solid var(--line); background:#fff;
  display:inline-flex; align-items:center; justify-content:center; flex-shrink:0;
  color:var(--muted); cursor:pointer; transition:transform .18s, border-color .15s, color .15s;
}
.detail-toggle:hover{border-color:var(--blue); color:var(--blue);}
tr.is-open .detail-toggle{border-color:var(--blue); color:var(--blue); transform:rotate(180deg);}

tr.detail-row{display:none;}
tr.detail-row.is-open{display:table-row;}
tr.detail-row > td{background:var(--bg); padding:18px 20px 20px 66px; border-bottom:1px solid var(--line);}
.detail-grid{display:grid; grid-template-columns:repeat(auto-fit, minmax(150px,1fr)); gap:16px 24px;}
.detail-grid .f-lbl{font-size:10.5px; font-weight:700; color:var(--muted); text-transform:uppercase; letter-spacing:0.04em; margin-bottom:4px;}
.detail-grid .f-val{font-size:13.5px; font-weight:600;}
.detail-grid .f-val.muted{color:var(--muted); font-weight:400;}

/* ===== forms: day-of-week toggle chips (schedule editors) ===== */
.day-toggle-row{display:flex; gap:8px; flex-wrap:wrap;}
.day-toggle{
  position:relative; width:44px; height:44px; border-radius:10px; border:1px solid var(--line); background:var(--bg);
  display:flex; align-items:center; justify-content:center; font-size:13px; font-weight:700; color:var(--muted);
  cursor:pointer; transition:border-color .15s, color .15s, background-color .15s;
}
.day-toggle:hover{border-color:var(--blue);}
.day-toggle input{position:absolute; opacity:0; width:100%; height:100%; margin:0; cursor:pointer;}
.day-toggle:has(input:checked){background:rgba(37,99,235,0.08); border-color:var(--blue); color:var(--blue);}

/* generic vertical rhythm between a form's labelled sections (h3 + fields) */
.form-section{margin-bottom:28px;}
.form-section:last-of-type{margin-bottom:0;}
.form-section h3{font-size:15px; margin-bottom:16px;}

/* bootstrap-clockpicker (company/employee/create.php, company/leave/*) predates
   Bootstrap 5 and expects its own popover to be position:absolute — this
   Bootstrap 5 build's own ".popover" rule no longer sets that, so without this
   the picker was rendering statically at the bottom of <body> instead of next
   to its input. Pre-existing bug, not new; scoped to clockpicker's own class so
   it doesn't touch Bootstrap's regular tooltip/popover components. */
.clockpicker-popover{position:absolute;}

/* ===== messenger shell (chat/chat, chat/question) — list pane + thread pane ===== */
/* 100vh minus exactly the chrome above/below it: 64px topbar + 28px top/bottom
   .cabinet-content padding each — anything more just left dead space under
   the panes on a normal window. */
.messenger{display:grid; grid-template-columns:340px 1fr; gap:20px; height:calc(100vh - 120px); min-height:520px;}
@media (max-width:991px){
  .messenger{grid-template-columns:1fr; height:auto;}
}

.msg-list-pane{background:#fff; border:1px solid var(--line); border-radius:16px; display:flex; flex-direction:column; overflow:hidden;}
.msg-list-pane .toolbar{padding:16px 16px 0; margin-bottom:8px;}
/* overflow-x explicit on purpose: with only overflow-y set, an "auto"/"visible"
   mix resolves visible to auto too (CSS overflow spec), so the vertical
   scrollbar eating into the available width was enough to also trigger a
   horizontal one — visible on a real dialog list, invisible with 1-2 test rows. */
.msg-list{flex:1; overflow-y:auto; overflow-x:hidden; padding:4px 8px 8px;}
@media (max-width:991px){
  .msg-list{max-height:340px;}
}

.msg-list-item{display:block; text-decoration:none; color:inherit;}
.msg-list-item .row{display:flex; align-items:flex-start; gap:12px; padding:12px 10px; border-radius:12px; transition:background-color .15s;}
.msg-list-item:hover .row{background:var(--bg);}
.msg-list-item.active .row{background:rgba(37,99,235,0.07);}
.msg-list-item .top{display:flex; width:100%; box-sizing:border-box; align-items:baseline; justify-content:space-between; gap:8px; min-width:0;}
.msg-list-item .who{font-weight:700; font-size:13.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0;}
.msg-list-item .time{font-size:11.5px; color:var(--muted); flex-shrink:0;}
.msg-list-item .bottom-row{display:flex; width:100%; box-sizing:border-box; align-items:center; justify-content:space-between; gap:8px; margin-top:2px; min-width:0;}
.msg-list-item .preview{font-size:12.5px; color:var(--muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0;}
.msg-unread-badge{background:var(--grad); color:#fff; font-size:10.5px; font-weight:700; border-radius:100px; padding:1px 7px; flex-shrink:0;}
.msg-list-empty{padding:32px 16px; text-align:center; color:var(--muted); font-size:13px;}

.msg-thread-pane{background:#fff; border:1px solid var(--line); border-radius:16px; display:flex; flex-direction:column; overflow:hidden;}
.msg-thread{flex:1; overflow-y:auto; padding:20px;}
.msg-thread:empty::before{
  content:'Выберите диалог'; display:flex; align-items:center; justify-content:center;
  height:100%; color:var(--muted); font-size:13.5px;
}
.msg-bubble{max-width:70%; margin-bottom:14px;}
.msg-bubble.mine{margin-left:auto;}
.msg-bubble .head{display:flex; align-items:baseline; gap:8px; margin-bottom:4px; font-size:11.5px; color:var(--muted);}
.msg-bubble.mine .head{flex-direction:row-reverse;}
.msg-bubble .head .author{font-weight:700; color:var(--text);}
.msg-bubble .bubble{background:var(--bg); border:1px solid var(--line); border-radius:14px; padding:10px 14px; font-size:13.5px; line-height:1.5; word-break:break-word;}
.msg-bubble.mine .bubble{background:rgba(37,99,235,0.06); border-color:rgba(37,99,235,0.15);}
.msg-bubble .bubble p{color:var(--text); margin:0;}
.msg-bubble .bubble img{max-width:100%; border-radius:8px; display:block;}
.msg-bubble .bubble .selected-text{background:#FEF08A; border-radius:2px; padding:0 1px;}
.msg-product-card .selected-text{background:#FEF08A; border-radius:2px; padding:0 1px;}

.msg-composer{display:flex; align-items:center; gap:10px; padding:14px 16px; border-top:1px solid var(--line); flex-shrink:0;}
.msg-composer input[type="text"]{
  flex:1; border:1px solid var(--line); border-radius:10px; padding:11px 14px; font-size:14px; background:var(--bg);
}
.msg-composer input[type="text"]:focus{border-color:var(--blue); box-shadow:0 0 0 3px rgba(37,99,235,0.12); background:#fff; outline:none;}
.msg-icon-btn{
  width:42px; height:42px; border-radius:10px; display:flex; align-items:center; justify-content:center;
  flex-shrink:0; cursor:pointer; border:none; transition:transform .15s, opacity .15s;
}
.msg-icon-btn.send{background:var(--grad); color:#fff;}
.msg-icon-btn.send:hover{opacity:0.9; transform:translateY(-1px);}
.msg-icon-btn.attach{background:var(--bg); border:1px solid var(--line); color:var(--muted);}
.msg-icon-btn.attach:hover{border-color:var(--blue); color:var(--blue);}

.msg-product-card{display:flex; gap:14px; padding:14px 20px; border-bottom:1px solid var(--line); background:var(--bg); flex-shrink:0;}
/* .msg-thread has its own 20px padding; bleed the card back out to the pane's
   edges so its background reads as a header bar, not an inset box. */
.msg-thread > .msg-product-card:first-child{margin:-20px -20px 16px;}
.msg-product-card img{width:52px; height:52px; border-radius:10px; object-fit:cover; border:1px solid var(--line); flex-shrink:0; background:#fff;}
.msg-product-card .name{font-size:13px; font-weight:600;}
.msg-product-card .meta{font-size:11.5px; color:var(--muted); margin-top:2px;}
.msg-product-card a{color:var(--text); text-decoration:none;}
.msg-product-card a:hover{color:var(--blue);}
