/* ============================================================================
   Grand Yan · Housekeeping Cockpit — ui.css
   Reusable, framework-free control library distilled from the Claude Design
   canvas (BOARD B · component library + BOARD B2 · role×state matrix + screens).

   Consumes design tokens via var(--…). Load AFTER tokens.css.
   Token vocabulary: --c-*, --st-*-{bg,bd,tx}, --hk-prio-1..4, --sem-*,
   --tint-*, --sp-*, --tap, --tap-touch, --ui-font, --ui-mono, --radius,
   --radius-sm, --shadow-*, --c-surface, --chrome-active.

   Principles: vanilla CSS, flat predictable selectors, mobile-first, large
   touch targets (tap ≥48px, maid primaries ≥64px), brand radius/shadow/spacing.
   ============================================================================ */

/* ============================================================================
   1 · BUTTONS — one .btn system + variants + sizes + states (§4.1)
   Uppercase tracked label per brand. md default; sm; lg = touch (≥64px).
============================================================================ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  font-family: var(--ui-font);
  font-weight: 700; font-size: 11px; letter-spacing: .13em; text-transform: uppercase;
  line-height: 1; white-space: nowrap;
  padding: 13px 22px; min-height: var(--tap);
  min-width: 0;           /* allow flex children to shrink below content width on narrow phones */
  border: 1px solid transparent; border-radius: var(--radius-sm);
  background: transparent; color: var(--c-dark);
  cursor: pointer; user-select: none;
  transition: background .12s ease, color .12s ease, border-color .12s ease, transform .04s ease;
}
.btn:focus-visible { outline: 2px solid var(--c-gold); outline-offset: 2px; }
.btn:active { transform: translateY(1px); }
.btn:disabled, .btn[aria-disabled="true"] {
  background: var(--sem-disabled-bg); color: var(--sem-disabled-text);
  border-color: var(--sem-disabled-bg); cursor: not-allowed; transform: none;
}

/* primary — solid dark */
.btn--primary { background: var(--c-dark); color: var(--c-cream); border-color: var(--c-dark); }
.btn--primary:hover { background: #2c2619; }
.btn--primary:active { background: #000; }

/* gold — ghost gold → fills gold on hover */
.btn--gold { border-color: var(--c-gold-dk); color: var(--c-gold-dk); background: transparent; }
.btn--gold:hover { background: var(--c-gold); border-color: var(--c-gold); color: var(--c-dark); }
.btn--gold:active { background: var(--c-gold-dk); border-color: var(--c-gold-dk); color: var(--c-cream); }

/* secondary / ghost — outlined dark → fills dark on hover */
.btn--secondary,
.btn--ghost { border-color: var(--c-dark); color: var(--c-dark); background: transparent; }
.btn--secondary:hover,
.btn--ghost:hover { background: var(--c-dark); color: var(--c-cream); }
.btn--secondary:active,
.btn--ghost:active { background: #000; border-color: #000; color: var(--c-cream); }

/* danger — single critical red */
.btn--danger { border-color: var(--sem-danger); color: var(--sem-danger); background: transparent; }
.btn--danger:hover { background: var(--sem-danger); color: var(--c-cream); }
.btn--danger:active { background: var(--sem-danger-deep); border-color: var(--sem-danger-deep); color: var(--c-cream); }

/* success — solid olive (maid "Убрано") */
.btn--success { background: var(--sem-success); color: var(--c-cream); border-color: var(--sem-success); }
.btn--success:hover { filter: brightness(.94); }

/* on-dark — light button placed on dark surfaces */
.btn--on-dark { background: var(--c-cream); color: var(--c-dark); border-color: transparent; }
.btn--on-dark:hover { background: #fff; }
.btn--on-dark:active { background: var(--c-straw); }
.btn--on-dark:disabled { background: rgba(244,239,229,.18); color: rgba(244,239,229,.4); }

/* sizes */
.btn--sm { font-size: 13px; letter-spacing: 0; text-transform: none; padding: 7px 14px; min-height: 0; }
.btn--lg,
.btn--touch { font-size: 17px; letter-spacing: .04em; text-transform: none; min-height: var(--tap-touch); padding: 0 24px; }
.btn--block { display: flex; width: 100%; white-space: normal; text-align: center; }

/* loading — append .is-loading, optionally with a <span class="btn__spin"> */
.btn.is-loading { color: color-mix(in srgb, currentColor 50%, transparent); pointer-events: none; }
.btn__spin {
  width: 11px; height: 11px; border-radius: 50%;
  border: 2px solid currentColor; border-top-color: var(--c-gold-lt);
  opacity: .8; animation: ui-spin .7s linear infinite; flex: 0 0 auto;
}
@keyframes ui-spin { to { transform: rotate(360deg); } }

/* ============================================================================
   2 · INPUTS / SELECT / TEXTAREA / STEPPER (§4.2)
   Label = eyebrow above field. Gold focus ring. Mobile ≥48px.
============================================================================ */
.field { display: block; margin-bottom: var(--sp-4); }
.field__label {
  display: block; margin-bottom: 7px;
  font-size: 11px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: var(--c-gold-dk);
}
.field__hint { margin-top: 6px; font-size: 12px; color: var(--c-brown); }
.field__error { margin-top: 6px; font-size: 12px; color: var(--sem-danger); }

.input, .select, .textarea {
  width: 100%; box-sizing: border-box;
  font-family: var(--ui-font); font-size: 15px; color: var(--c-dark);
  background: var(--c-surface);
  border: 1px solid var(--c-line); border-radius: var(--radius-sm);
  padding: 12px 14px; min-height: var(--tap);
  transition: border-color .12s ease, box-shadow .12s ease;
}
.input::placeholder, .textarea::placeholder { color: var(--c-brown); }
.input:focus, .select:focus, .textarea:focus,
.input:focus-visible, .select:focus-visible, .textarea:focus-visible {
  outline: none; border-color: var(--c-gold);
  box-shadow: 0 0 0 2px var(--c-gold); /* gold focus ring */
}
.textarea { min-height: 74px; line-height: 1.5; resize: vertical; }
.select { appearance: none; padding-right: 38px; cursor: pointer;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--c-gold-dk) 50%),
    linear-gradient(135deg, var(--c-gold-dk) 50%, transparent 50%);
  background-position: calc(100% - 18px) 55%, calc(100% - 12px) 55%;
  background-size: 6px 6px, 6px 6px; background-repeat: no-repeat;
}
.input.is-error, .select.is-error, .textarea.is-error { border-color: var(--sem-danger); }
.input:disabled, .select:disabled, .textarea:disabled,
.input[readonly] { background: var(--sem-disabled-bg); color: var(--sem-disabled-text);
  border-color: var(--sem-disabled-bg); cursor: not-allowed; }

/* stepper (mini-bar counts) */
.stepper { display: inline-flex; align-items: stretch; min-height: var(--tap);
  border: 1px solid var(--c-line); border-radius: var(--radius-sm);
  background: var(--c-surface); overflow: hidden; flex: 0 0 auto; }
.stepper__btn { border: none; background: var(--c-cream-2); color: var(--c-dark);
  width: 48px; min-height: 48px; font-size: 22px; line-height: 1;
  cursor: pointer; font-family: var(--ui-font); touch-action: manipulation; }
.stepper__btn:first-child { border-right: 1px solid var(--c-line); }
.stepper__btn:last-child { border-left: 1px solid var(--c-line); }
.stepper__val { width: 40px; display: flex; align-items: center; justify-content: center;
  font-family: var(--ui-mono); font-size: 18px; font-weight: 600; }

/* minibar disclosure toggle — styled like a secondary button */
.minibar-toggle {
  display: flex; align-items: center; justify-content: space-between;
  width: 100%; padding: 14px 16px;
  background: transparent; border: 1px solid var(--c-dark); border-radius: var(--radius-sm);
  font-family: var(--ui-font); font-size: 14px; font-weight: 600; color: var(--c-dark);
  cursor: pointer; text-align: left; min-height: var(--tap);
  touch-action: manipulation;
  transition: background .12s ease, color .12s ease;
}
.minibar-toggle:hover { background: var(--c-dark); color: var(--c-cream); }
.minibar-toggle:focus-visible { outline: 2px solid var(--c-gold); outline-offset: 2px; }
.minibar-toggle__arrow { font-size: 12px; opacity: .6; transition: transform .18s ease; }
details[open] .minibar-toggle__arrow { transform: rotate(180deg); }
details summary { list-style: none; }
details summary::-webkit-details-marker { display: none; }

/* ============================================================================
   3 · CHECKBOX + CHECKLIST ROW (§4.3)
   unchecked · checked (gold box, checked_at) · requires-photo · disabled-before-start
============================================================================ */
.check { width: 24px; height: 24px; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--c-line); background: var(--c-surface);
  border-radius: var(--radius-sm); color: var(--c-cream); font-size: 15px;
  cursor: pointer; }
.check.is-checked { border-color: var(--c-gold); background: var(--c-gold); }
.check.is-checked::after { content: "✓"; }
.check:disabled, .check.is-disabled { border-color: var(--sem-disabled-text);
  background: var(--sem-disabled-bg); cursor: not-allowed; }

.checklist { border: 1px solid var(--c-line); border-radius: var(--radius);
  background: var(--c-surface); overflow: hidden; }
.checklist-item { display: flex; align-items: center; gap: 14px; padding: 14px 16px;
  border-bottom: 1px solid var(--c-line-2); font-size: 15px; }
.checklist-item:last-child { border-bottom: none; }
.checklist-item__time { font-family: var(--ui-mono); font-size: 11px; color: var(--c-brown); }
.checklist-item.is-disabled { opacity: .5; }
.checklist-item.is-disabled .checklist-item__label { color: var(--sem-disabled-text); }
.checklist-item__photo { margin-left: auto;
  background: var(--sem-warn-bg); color: var(--c-gold-text);
  font-size: 12px; font-weight: 600; padding: 3px 8px; border-radius: var(--radius-sm); }

/* ============================================================================
   4 · TOGGLE + SEGMENTED CONTROL (§4.4)
============================================================================ */
.toggle { display: inline-flex; align-items: center; gap: 14px; cursor: pointer; }
.toggle__track { width: 46px; height: 26px; flex: 0 0 auto; position: relative;
  border-radius: 50px; background: var(--c-line); transition: background .15s ease; }
.toggle__thumb { position: absolute; top: 3px; left: 3px; width: 20px; height: 20px;
  border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(31,27,20,.3);
  transition: left .15s ease; }
.toggle.is-on .toggle__track { background: var(--c-gold); }
.toggle.is-on .toggle__thumb { left: 23px; }

.segmented { display: inline-flex; border: 1px solid var(--c-line);
  border-radius: var(--radius-sm); overflow: hidden; }
.segmented__item { padding: 10px 18px; font-size: 13px; color: var(--c-brown);
  background: transparent; border: none; border-left: 1px solid var(--c-line);
  cursor: pointer; font-family: var(--ui-font); }
.segmented__item:first-child { border-left: none; }
.segmented__item.is-active { font-weight: 600; color: var(--c-gold-dk);
  background: var(--c-cream-2); border-bottom: 2px solid var(--c-gold); }

/* ============================================================================
   5 · CHIPS · BADGES (§4.5)
   .chip carries a room-status modifier; .badge is a small neutral/gold label.
============================================================================ */
.chip { display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 600; padding: 4px 10px;
  border: 1px solid var(--c-line); border-radius: var(--radius-sm);
  background: var(--c-cream-2); color: var(--c-dark); }
.chip--dirty { background: var(--st-dirty-bg); border-color: var(--st-dirty-bd); color: var(--st-dirty-tx); }
.chip--clean { background: var(--st-clean-bg); border-color: var(--st-clean-bd); color: var(--st-clean-tx); }
.chip--inspected { background: var(--st-insp-bg); border-color: var(--st-insp-bd); color: var(--st-insp-tx); }
.chip--occupied { background: var(--st-occ-bg); border-color: var(--st-occ-bd); color: var(--st-occ-tx); }
.chip--ooo { background: var(--st-ooo-bg); border-color: var(--st-ooo-bd); color: var(--st-ooo-tx); }
.chip--success { background: var(--sem-success-bg); border-color: var(--sem-success); color: var(--sem-success); }
.chip--warn { background: var(--sem-warn-bg); border-color: var(--c-gold-dk); color: var(--c-gold-text); }
.chip--danger { background: #fff; border-color: rgba(178,59,59,.4); color: var(--sem-danger); }
.chip--mono { font-family: var(--ui-mono); font-weight: 400; } /* SLA timer e.g. +0:42 */

.badge { display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px; font-weight: 600; padding: 1px 5px; border-radius: var(--radius-sm);
  background: var(--c-cream-2); color: var(--c-dark); }
.badge--gold { background: var(--sem-warn-bg); color: var(--c-gold-text); }
.badge--vip::before { content: "♛ "; color: var(--c-gold-dk); }
/* count pill — hub/KPI notification counter */
.badge--count { min-width: 22px; height: 22px; padding: 0 6px; justify-content: center;
  border-radius: 11px; font-family: var(--ui-mono); background: var(--sem-danger); color: #fff; }
.badge--count.badge--gold { background: var(--c-gold); color: var(--c-dark); }

/* overdue indicators (mutually exclusive with a P1 bar — red-stacking rule) */
.overdue-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--sem-danger); display: inline-block; }
.overdue-timer { font-family: var(--ui-mono); font-size: 11px; color: var(--sem-danger);
  background: #fff; border: 1px solid rgba(178,59,59,.4); padding: 2px 6px; border-radius: var(--radius-sm); }

/* ============================================================================
   6 · PRIORITY COLOUR BAR (§4.5 / lists)
   Left-border accent only. Applied to .cell, .wl-row, .list-row.
============================================================================ */
.prio-bar { position: absolute; left: 0; top: 0; bottom: 0; width: 6px;
  border-radius: 3px 0 0 3px; flex: 0 0 auto; }
.prio-1 { background: var(--hk-prio-1); }
.prio-2 { background: var(--hk-prio-2); }
.prio-3 { background: var(--hk-prio-3); }
.prio-4 { background: var(--hk-prio-4); }
/* convenience: a flat (non-absolute) 6px rail for list rows */
.prio-rail { width: 6px; flex: 0 0 auto; }
.prio-rail.prio-1 { background: var(--hk-prio-1); }
.prio-rail.prio-2 { background: var(--hk-prio-2); }
.prio-rail.prio-3 { background: var(--hk-prio-3); }
.prio-rail.prio-4 { background: var(--hk-prio-4); }

/* ============================================================================
   7 · KPI TILE + RIBBON · HUB TILE (§4.6)
============================================================================ */
.ribbon { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 14px; }
.ribbon--inline { display: flex; flex-wrap: wrap; gap: 12px; }

.kpi { background: var(--c-cream-2); border: 1px solid var(--c-line);
  border-radius: var(--radius); padding: 18px; }
.kpi__num { font-family: var(--ui-mono); font-size: 30px; font-weight: 600; line-height: 1; }
.kpi__label { margin-top: 6px; font-size: 11px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--c-brown); }
.kpi__delta { font-size: 12px; font-weight: 600; margin-left: 8px; }
.kpi--danger  .kpi__num, .kpi--danger  .kpi__delta { color: var(--sem-danger); }
.kpi--success .kpi__num, .kpi--success .kpi__delta { color: var(--sem-success); }
.kpi--inspected .kpi__num { color: var(--st-insp-tx); }
.kpi--dark { background: var(--c-dark); border-color: var(--c-line-on-dark); }
.kpi--dark .kpi__num { color: var(--c-gold-lt); }
.kpi--dark .kpi__label { color: var(--c-brown); }
/* compact inline KPI used in topbar ribbons */
.kpi--inline { display: inline-flex; align-items: baseline; gap: 8px; padding: 10px 16px;
  background: var(--c-surface); }
.kpi--inline .kpi__num { font-size: 20px; }
.kpi--inline .kpi__label { margin: 0; letter-spacing: .06em; }
/* compact 3-up header KPI tile (canvas A1 mini-KPIs: осталось / готово / срочно) */
.kpi--mini { flex: 1; background: var(--c-cream-2); border: 1px solid var(--c-line);
  border-radius: var(--radius); padding: 8px 10px; }
.kpi--mini .kpi__num { font-family: var(--ui-mono); font-size: 19px; font-weight: 600; line-height: 1; }
.kpi--mini .kpi__label { margin-top: 3px; font-size: 10px; color: var(--c-brown);
  text-transform: uppercase; letter-spacing: .06em; font-weight: 400; }
.kpi--mini.kpi--danger .kpi__num { color: var(--sem-danger); }
.kpi--mini.kpi--danger { background: var(--sem-danger-bg); border-color: rgba(178,59,59,.25); }
.kpi--mini.kpi--success .kpi__num { color: var(--sem-success); }

.hub-tile { position: relative; cursor: pointer; display: block; text-align: left;
  background: var(--c-cream-2); border: 1px solid var(--c-line);
  border-radius: var(--radius); padding: 20px; color: var(--c-dark);
  text-decoration: none; transition: box-shadow .12s ease, transform .04s ease; }
.hub-tile:hover { box-shadow: var(--shadow-card); }
.hub-tile:active { transform: translateY(1px); }
.hub-tile__icon { font-size: 22px; margin-bottom: 14px; }
.hub-tile__title { font-weight: 600; font-size: 16px; }
.hub-tile__sub { font-size: 12px; color: var(--c-brown); margin-top: 4px; }
.hub-tile .badge--count { position: absolute; top: 14px; right: 14px; }

/* ============================================================================
   8 · FLOOR-MAP CELL (§4.5 chips + B1 chessboard)
   Colour = status/priority. VIP/DND/selected overlays. Touch grid.
============================================================================ */
.floor-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 11px; }

/* Supervisor board: chessboard + assign panel. Two columns on desktop, one on phone.
   The fixed 240px column otherwise forces the page wider than a phone viewport
   (horizontal scroll → clipped topbar/metrics, 1 cell per row). On phone it stacks:
   full-width chessboard (packs ~3 cells/row) then the assign panel below. */
.board-layout { display: grid; grid-template-columns: 1fr 240px; gap: 0; align-items: start; }
.board-chess  { padding: 20px 24px; }
.board-aside  { margin: 20px 24px 20px 0; overflow: hidden; }
@media (max-width: 719px) {
  .board-layout { grid-template-columns: 1fr; }
  .board-chess  { padding: 16px; }
  .board-aside  { margin: 0 16px 20px; }
}

.cell { position: relative; cursor: pointer; min-height: var(--tap);
  border: 1px solid var(--c-line); background: var(--c-cream);
  border-radius: var(--radius); padding: 11px 10px;
  font-family: var(--ui-font); color: var(--c-dark); text-align: left; }
.cell__no { font-weight: 600; font-size: 17px; line-height: 1.1; }
.cell__who { font-size: 11px; color: var(--c-brown); margin-top: 2px; }
.cell__icon { position: absolute; top: 6px; right: 8px; font-size: 11px; }
.cell__timer { font-family: var(--ui-mono); font-size: 10px; color: var(--sem-danger); margin-top: 4px; }
/* leave room for an absolute prio bar */
.cell.has-prio { padding-left: 14px; }

/* status modifiers */
.cell--free { border-style: dashed; }
.cell--free .cell__who { color: var(--c-brown); }
.cell--dirty { background: var(--st-dirty-bg); border-color: var(--st-dirty-bd); }
.cell--dirty .cell__no, .cell--dirty .cell__who { color: var(--st-dirty-tx); }
.cell--clean { background: var(--st-clean-bg); border-color: var(--st-clean-bd); }
.cell--clean .cell__no, .cell--clean .cell__who { color: var(--st-clean-tx); }
.cell--inspected { background: var(--st-insp-bg); border-color: var(--st-insp-bd); }
.cell--inspected .cell__no, .cell--inspected .cell__who { color: var(--st-insp-tx); }
.cell--occupied { background: var(--st-occ-bg); border-color: var(--st-occ-bd); }
.cell--ooo { border-color: var(--st-ooo-bd);
  background: repeating-linear-gradient(45deg, var(--st-ooo-bg), var(--st-ooo-bg) 6px,
              var(--st-ooo-stripe) 6px, var(--st-ooo-stripe) 12px); }
.cell--ooo .cell__no, .cell--ooo .cell__who { color: var(--st-ooo-tx); }
.cell--draft { border-style: dashed; border-color: var(--c-gold-dk); background: var(--tint-anya); }
.cell--refused { background: var(--sem-muted-bg); opacity: .55; }

/* overlays — orthogonal to status colour */
.cell--checkin { box-shadow: inset 4px 0 0 var(--c-gold); }   /* заезд сегодня */
.cell--rebook { border-width: 2px; border-color: var(--hk-prio-2); } /* перезаезд */
.cell.is-selected { outline: 2px solid var(--c-gold); outline-offset: 1px; }
.cell__vip { position: absolute; top: 4px; left: 6px; font-size: 11px; color: var(--c-gold-dk); } /* ♛ */
.cell__pick { position: absolute; top: 4px; left: 6px; width: 14px; height: 14px;
  display: flex; align-items: center; justify-content: center; font-size: 9px; color: #fff;
  border: 1.5px solid var(--c-gold-dk); background: var(--c-gold); border-radius: var(--radius-sm); }
.cell .overdue-dot { position: absolute; bottom: 7px; right: 7px; }

/* maid-tint helpers (assignment preview) */
.tint-anya { background: var(--tint-anya) !important; }
.tint-lena { background: var(--tint-lena) !important; }
.tint-ira  { background: var(--tint-ira)  !important; }

/* ============================================================================
   9 · WORKLIST / LIST + TABLE ROWS (§4.7)
   Left prio rail (6px) + body. .is-urgent for SLA breach. .is-done dims.
============================================================================ */
.worklist { border: 1px solid var(--c-line); border-radius: var(--radius);
  background: var(--c-surface); overflow: hidden; }
.wl-row { display: flex; align-items: stretch; border-bottom: 1px solid var(--c-line-2); }
.wl-row:last-child { border-bottom: none; }
.wl-row__body { flex: 1; padding: 14px 16px; }
.wl-row__head { display: flex; align-items: center; justify-content: space-between; }
.wl-row__no { font-weight: 600; font-size: 17px; }
.wl-row__meta { font-size: 13px; color: var(--c-brown); margin-top: 4px;
  display: flex; align-items: center; gap: 8px; }
.wl-row.is-done { opacity: .6; }
.wl-row.is-urgent .wl-row__no { color: var(--sem-danger); }

/* generic data table */
.table { width: 100%; border-collapse: collapse; font-size: 14px;
  border: 1px solid var(--c-line); border-radius: var(--radius); overflow: hidden; }
.table thead { background: var(--c-dark); color: var(--c-cream); }
.table th { padding: 13px 16px; text-align: left; font-size: 11px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; }
.table td { padding: 12px 16px; border-top: 1px solid var(--c-line-2); }
.table tbody tr:nth-child(even) { background: var(--c-cream); }
.table--scroll { display: block; overflow-x: auto; }
/* role-matrix access marks */
.acc-full { color: var(--sem-success); font-weight: 600; }   /* ● полный */
.acc-part { color: var(--c-gold-dk); font-weight: 600; }     /* ◐ ограниченный */
.acc-none { color: var(--sem-disabled-text); font-weight: 600; } /* ○ скрыто */

/* ============================================================================
   10 · CHAT THREAD + COMPOSER (D4)
============================================================================ */
.chat { background: var(--c-cream); display: flex; flex-direction: column; gap: 14px;
  padding: 20px; }
.chat__header { background: var(--c-dark); color: var(--c-cream);
  padding: 14px 20px; display: flex; align-items: center; gap: 11px; }
.msg { display: flex; flex-direction: column; max-width: 80%; }
.msg__bubble { padding: 11px 14px; font-size: 14px; line-height: 1.5; border-radius: 10px; }
.msg__time { font-family: var(--ui-mono); font-size: 10px; color: var(--c-brown); margin-top: 4px; }
.msg--in { align-items: flex-start; }
.msg--in .msg__bubble { background: var(--c-surface); border: 1px solid var(--c-line);
  border-radius: 2px 10px 10px 10px; }
.msg--out { align-items: flex-end; align-self: flex-end; }
.msg--out .msg__bubble { background: var(--c-dark); color: var(--c-cream);
  border-radius: 10px 2px 10px 10px; }
.msg--out .msg__time { text-align: right; }

.composer { display: flex; align-items: center; gap: 10px;
  padding: 12px 16px; border-top: 1px solid var(--c-line); background: var(--c-surface); }
.composer .input { min-height: 44px; }
.composer__send { flex: 0 0 auto; }

/* ============================================================================
   11 · PHOTO THUMBNAIL + UPLOADER (A5, B3)
============================================================================ */
.photo-thumb { width: 64px; height: 64px; flex: 0 0 auto;
  border: 1px solid var(--c-line); border-radius: var(--radius);
  background: var(--c-straw) center/cover no-repeat; }
.photo-row { display: flex; gap: 10px; flex-wrap: wrap; }
.uploader { width: 64px; height: 64px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  border: 1.5px dashed var(--c-gold-dk); border-radius: var(--radius);
  color: var(--c-gold-dk); font-size: 24px; background: transparent; cursor: pointer; }
.uploader:hover { background: var(--sem-warn-bg); }
.dropzone { display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; padding: 28px; text-align: center;
  border: 1.5px dashed var(--c-gold-dk); border-radius: var(--radius);
  color: var(--c-gold-dk); background: var(--sem-warn-bg); cursor: pointer; }
.dropzone.is-dragover { background: var(--c-gold-lt); }

/* ============================================================================
   12 · MODALS · SHEETS · DRAWER + BACKDROP (§4.8, B2)
============================================================================ */
.backdrop { position: fixed; inset: 0; background: rgba(31,27,20,.28); z-index: 90; }

/* shared panel skeleton: dark header · scroll body · sticky action footer */
.panel { display: flex; flex-direction: column; background: var(--c-surface);
  border: 1px solid var(--c-line); border-radius: var(--radius); overflow: hidden; }
.panel__header { background: var(--c-dark); color: var(--c-cream);
  padding: 16px 18px; display: flex; align-items: center; justify-content: space-between; }
.panel__eyebrow { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--c-gold); }
.panel__title { font-size: 20px; font-weight: 600; margin-top: 2px; }
.panel__close { width: 30px; height: 30px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--c-line-on-dark); border-radius: var(--radius-sm);
  color: var(--c-cream); background: transparent; cursor: pointer; }
.panel__badges { padding: 14px 18px; display: flex; gap: 8px; flex-wrap: wrap;
  border-bottom: 1px solid var(--c-line-2); }
.panel__body { flex: 1; padding: 16px 18px; overflow-y: auto;
  color: var(--c-brown); font-size: 14px; line-height: 1.6; }
.panel__footer { padding: 14px 18px; display: flex; gap: 10px; background: var(--c-cream);
  border-top: 1px solid var(--c-line); }
.panel__footer .btn { flex: 1; }
.panel__footer .btn--secondary, .panel__footer .btn--ghost { flex: 0 0 auto; }

.modal { position: fixed; z-index: 100; top: 50%; left: 50%; transform: translate(-50%,-50%);
  width: min(560px, calc(100vw - 32px)); max-height: calc(100vh - 64px);
  box-shadow: var(--shadow-float); }
.sheet { position: fixed; z-index: 100; left: 0; right: 0; bottom: 0;
  max-height: 90vh; border-radius: var(--radius) var(--radius) 0 0;
  box-shadow: var(--shadow-drawer); }
.drawer { position: fixed; z-index: 100; top: 0; right: 0; bottom: 0;
  width: min(440px, 92vw); border-radius: 0; box-shadow: var(--shadow-drawer); }

/* mobile-first: drawers collapse to bottom-sheet under 720px */
@media (max-width: 719px) {
  .drawer { top: auto; left: 0; right: 0; width: 100%; max-height: 90vh;
    border-radius: var(--radius) var(--radius) 0 0; }
}

/* ============================================================================
   13 · STATE SURFACES — empty · loading · error · toast · urgent banner
============================================================================ */
.empty { display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; padding: 48px 24px; text-align: center; color: var(--c-brown); }
.empty__icon { font-size: 28px; opacity: .5; }
.empty__title { font-size: 16px; font-weight: 600; color: var(--c-dark); }

.skeleton { position: relative; overflow: hidden;
  background: var(--c-cream-2); border-radius: var(--radius); min-height: 16px; }
.skeleton::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.45), transparent);
  transform: translateX(-100%); animation: ui-shimmer 1.3s infinite; }
@keyframes ui-shimmer { to { transform: translateX(100%); } }

.state-error { display: flex; flex-direction: column; align-items: center; gap: 10px;
  padding: 32px 24px; text-align: center;
  background: var(--sem-danger-bg); border: 1px solid rgba(178,59,59,.25);
  border-radius: var(--radius); color: var(--sem-danger); }

.toast { position: fixed; z-index: 110; left: 50%; bottom: 24px; transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: 10px;
  background: var(--c-dark); color: var(--c-cream);
  padding: 12px 18px; border-radius: var(--radius); box-shadow: var(--shadow-float);
  font-size: 14px; max-width: calc(100vw - 32px); }
.toast--success { border-left: 4px solid var(--sem-success); }
.toast--danger  { border-left: 4px solid var(--sem-danger); }
.toast--gold    { border-left: 4px solid var(--c-gold); }

.banner { padding: 12px 16px; border-radius: var(--radius);
  background: var(--sem-warn-bg); border-left: 3px solid var(--c-gold);
  color: var(--c-gold-text); font-size: 13px; line-height: 1.5; }
.banner--urgent { background: var(--sem-danger-bg); border-left-color: var(--sem-danger);
  color: var(--sem-danger); font-weight: 600; }

/* ============================================================================
   14 · SHELL · NAV · HEADER — command-center frame (cover/topbar + B1 shell)
============================================================================ */
.cc-topbar { background: var(--c-dark); color: var(--c-cream);
  border-bottom: 1px solid var(--c-line-on-dark); position: sticky; top: 0; z-index: 50; }
.cc-topbar__inner { max-width: 1320px; margin: 0 auto;
  padding: 14px clamp(20px,4vw,48px);
  display: flex; align-items: center; justify-content: space-between; gap: 20px; }

.gy-mark { display: flex; align-items: center; gap: 14px; }
.gy-mark__badge { width: 38px; height: 38px; flex: 0 0 auto; border-radius: 50%;
  background: #0F0F12; border: 1px solid var(--c-gold);
  display: flex; align-items: center; justify-content: center; }
.gy-mark__badge span { font-weight: 700; font-size: 15px; letter-spacing: -.02em; color: var(--c-gold-lt); }
.gy-mark__word { font-weight: 700; font-size: 14px; letter-spacing: .18em; }
.gy-mark__word em { font-style: normal; color: var(--c-gold); }

.cc-nav { display: flex; gap: 4px; flex-wrap: wrap; justify-content: flex-end; }
.cc-nav a { color: var(--c-cream); text-decoration: none; opacity: .78;
  padding: 7px 11px; border-radius: var(--radius-sm);
  font-size: 11px; font-weight: 600; letter-spacing: .04em; }
.cc-nav a:hover { opacity: 1; background: var(--chrome-active); }
.cc-nav a.is-active { opacity: 1; color: var(--c-gold-lt); }

/* desktop app shell: icon sidebar + main + optional right rail */
.cc-shell { display: flex; min-height: 100%; background: var(--c-cream); }
.cc-sidebar { width: 74px; flex: 0 0 auto; background: var(--c-dark);
  display: flex; flex-direction: column; align-items: center; padding: 18px 0; gap: 6px; }
.cc-sidebar__item { width: 46px; height: 46px; border-radius: 8px;
  display: flex; align-items: center; justify-content: center; font-size: 18px;
  opacity: .45; cursor: pointer; color: var(--c-cream); text-decoration: none; }
.cc-sidebar__item.is-active { opacity: 1; background: var(--chrome-active);
  border-left: 2px solid var(--c-gold); }
.cc-main { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.cc-header { padding: 18px 24px; border-bottom: 1px solid var(--c-line);
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 14px; }
.cc-header__eyebrow { font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--c-gold-dk); font-weight: 700; }
.cc-header__title { font-size: 23px; font-weight: 600; margin-top: 3px; }
.cc-rail { width: 188px; flex: 0 0 auto; background: var(--c-surface);
  border-left: 1px solid var(--c-line); padding: 18px 16px; }

/* page frame for content sections */
.page { max-width: 1320px; margin: 0 auto; padding: clamp(20px,4vw,48px); }
.section-eyebrow { font-size: 11px; font-weight: 700; letter-spacing: .22em;
  text-transform: uppercase; color: var(--c-gold-dk); }

/* mobile phone frame / bottom nav (maid app) */
.app-bottomnav { display: flex; border-top: 1px solid var(--c-line); background: var(--c-cream-2); }
.app-bottomnav__item { flex: 1; text-align: center; padding: 11px 0 16px;
  color: var(--c-brown); text-decoration: none; font-size: 10px; }
.app-bottomnav__item .nav-ico { font-size: 18px; opacity: .5; display: block; }
.app-bottomnav__item.is-active { color: var(--c-gold-dk); font-weight: 600; }
.app-bottomnav__item.is-active .nav-ico { opacity: 1; }

/* generic progress bar (maid load, checklist progress) */
.progress { height: 5px; border-radius: 3px; background: var(--c-surface); overflow: hidden; }
.progress__fill { height: 100%; background: var(--c-gold); }

/* avatar */
.avatar { width: 28px; height: 28px; flex: 0 0 auto; border-radius: 50%;
  background: var(--c-straw); border: 1px solid var(--c-line);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 600; color: var(--c-dark); }

/* ============================================================================
   15 · ROLE-GATED VISIBILITY HELPERS
   Drive show/hide from a role/permission attribute on an ancestor (e.g. <body>
   or .cc-shell). Default: action affordances hidden; reveal per granted perm.
   Usage: <body data-role="supervisor" data-can="assign edit-status inspect">
   Mark gated controls with [data-need="assign"] etc.
============================================================================ */
[data-need] { display: none !important; }
[data-can~="status"]   [data-need="status"],
[data-can~="assign"]   [data-need="assign"],
[data-can~="inspect"]  [data-need="inspect"],
[data-can~="minibar"]  [data-need="minibar"],
[data-can~="maint"]    [data-need="maint"],
[data-can~="ooo"]      [data-need="ooo"],
[data-can~="report"]   [data-need="report"],
[data-can~="checklist"][data-need="checklist"] { display: revert !important; }

/* read-only role: neutralise interactive affordances inside [data-readonly] */
[data-readonly] .btn:not(.btn--ghost):not(.btn--secondary),
[data-readonly] .cell, [data-readonly] .checklist-item, [data-readonly] .toggle {
  pointer-events: none;
}
[data-readonly] .btn { opacity: .55; }

/* explicit boolean attribute toggles (alternative to [data-can~]) */
[data-can-edit-status="false"] [data-need="status"],
[data-can-assign="false"]      [data-need="assign"],
[data-can-inspect="false"]     [data-need="inspect"] { display: none !important; }
[data-can-edit-status="true"]  [data-need="status"],
[data-can-assign="true"]       [data-need="assign"],
[data-can-inspect="true"]      [data-need="inspect"] { display: revert !important; }

/* «не беспокоить» plaque — muted danger wash + small uppercase label */
.plaque--dnd { display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  background: var(--sem-danger-bg); border: 1px solid rgba(178,59,59,.3);
  color: var(--sem-danger); padding: 1px 6px; border-radius: var(--radius-sm); }

/* link reset — card/row <a> wrappers should not inherit gold link styling */
.lnk-reset { color: inherit; text-decoration: none; }
.lnk-reset:hover { color: inherit; text-decoration: none; }

/* ----------------------------------------------------------------------------
   16 · UTILITIES (small, predictable)
---------------------------------------------------------------------------- */
.mono { font-family: var(--ui-mono); }
.eyebrow { font-size: 11px; font-weight: 700; letter-spacing: .22em; text-transform: uppercase;
  color: var(--c-gold-dk); }
.muted { color: var(--c-brown); }
.on-dark { background: var(--c-dark); color: var(--c-cream); }
.card { background: var(--c-cream); border: 1px solid var(--c-line);
  border-radius: var(--radius); box-shadow: var(--shadow-card); }
.stack { display: flex; flex-direction: column; gap: var(--sp-3); }
.row { display: flex; align-items: center; gap: var(--sp-3); }
.row--wrap { flex-wrap: wrap; }
.spacer { flex: 1; }
.is-hidden { display: none !important; }
