/* Остров карты офиса: стили слоёв поверх холста Fabric (маркеры, рамки, миникарта, углы зума). Подключаются через
   Stylesheets модуля (_content/UI.Office/map/office-map.css, без версии: отпечаток даёт сборка), не <link>-ом в компоненте. Все селекторы под .om-map.
   Цвета — переменные --om-*, которые остров выставляет на корне из палитры портала (theme.js) и которые до этого
   ссылаются на токены MudBlazor; цвета состояний — токены MudBlazor. Ширины определяет остров по размеру окна карты
   (data-size хоста: xs < 600, sm < 960, md) — брейкпоинты MudBlazor. Слоёв z-index нет: порядок задаёт порядок в DOM. */

.om-map {
  /* Значения по умолчанию — токены MudBlazor; поверх них остров пишет палитру, присланную страницей. */
  --om-bg: var(--mud-palette-background);
  --om-surface: var(--mud-palette-surface);
  --om-text: var(--mud-palette-text-primary);
  --om-muted: var(--mud-palette-text-secondary);
  --om-line: var(--mud-palette-lines-default);
  --om-accent: var(--mud-palette-primary);
  --om-active: color-mix(in srgb, var(--om-accent) 12%, var(--om-surface));
  --om-hover: color-mix(in srgb, var(--om-text) 5%, var(--om-surface));
  --om-dots: color-mix(in srgb, var(--om-accent) 20%, var(--om-bg));
  --om-on-accent: var(--mud-palette-primary-text);

  position: absolute;
  inset: 0;
  overflow: hidden;
  background: var(--om-bg);
  color: var(--om-text);
  cursor: grab;
  outline: none;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.om-map [hidden] {
  display: none !important;
}

.om-map:focus-visible {
  box-shadow: inset 0 0 0 2px var(--om-accent);
}

.om-map.is-panning {
  cursor: grabbing;
}

.om-map.is-over {
  cursor: pointer;
}

/* Холст Fabric с сеткой точек под планом; размер и сдвиг сетки остров меняет вместе с камерой. */
.om-map .om-canvas {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(var(--om-dots) 0.8px, transparent 0.8px);
  background-size: 25px 25px;
  touch-action: none;
}

.om-map .om-canvas canvas {
  touch-action: none;
}

/* Скринридер: изменения выбора и загрузки; на экране не видна. */
.om-map .om-live {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---- Слой маркеров: одна transform на камеру, маркеры несут обратный масштаб --om-inv ---- */

.om-map .om-layer {
  --om-inv: 1;
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  transform-origin: 0 0;
  pointer-events: none;
}

.om-map .om-seats,
.om-map .om-frames,
.om-map .om-kitchens {
  position: absolute;
  left: 0;
  top: 0;
}

.om-map .om-layer[data-density="hidden"] .om-seat:not([data-state="mine"]) {
  display: none;
}

/* На общем плане обычные места скрыты, а своё остаётся одной геометкой без подписи и аватара. */
.om-map .om-layer[data-density="hidden"] .om-seat[data-state="mine"] {
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
}

.om-map .om-layer[data-density="hidden"] .om-seat[data-state="mine"]::before,
.om-map .om-layer[data-density="hidden"] .om-seat[data-state="mine"]::after,
.om-map .om-layer[data-density="hidden"] .om-seat[data-state="mine"] .om-avatar {
  display: none;
}

.om-map .om-layer[data-density="hidden"] .om-seat[data-state="mine"] .om-mine-pin {
  bottom: 0;
}

/* Место: свободно — success, моё — акцент, постоянное — info, занятое сегодня — warning, недоступное — приглушённое
   (те же тоны, что у состояния места в карточке страницы, OfficePresentation.SeatStatus). */
.om-map .om-seat {
  --om-seat: var(--mud-palette-success);
  position: absolute;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 3px 5px;
  transform: translate(-50%, -50%) scale(var(--om-inv));
  border: 1px solid color-mix(in srgb, var(--om-seat) 35%, var(--om-line));
  border-radius: 6px;
  background: color-mix(in srgb, var(--om-seat) 12%, var(--om-surface));
  box-shadow: var(--mud-elevation-2);
  color: var(--om-seat);
  font-family: inherit;
  font-size: 10px;
  font-weight: 600;
  line-height: 1.3;
  white-space: nowrap;
  cursor: pointer;
  pointer-events: auto;
}

/* Точка состояния и подпись — псевдоэлементы: место без человека — один узел DOM. */
.om-map .om-seat::before {
  content: "";
  flex-shrink: 0;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

.om-map .om-seat:not(.has-person)::after {
  content: attr(data-label);
}

.om-map .om-seat[data-state="mine"] {
  --om-seat: var(--om-accent);
  border-color: var(--om-accent);
  background: var(--om-surface);
}

.om-map .om-seat[data-state="assigned"] {
  --om-seat: var(--mud-palette-info);
}

.om-map .om-seat[data-state="occupied"] {
  --om-seat: var(--mud-palette-warning);
}

.om-map .om-seat[data-state="unavailable"] {
  --om-seat: var(--om-muted);
  background: var(--om-hover);
}

/* С человеком: аватар и имя на поверхности, цвет состояния остаётся в рамке. */
.om-map .om-seat.has-person {
  gap: 7px;
  padding: 4px 5px;
  border-radius: 9px;
  background: var(--om-surface);
  color: var(--om-text);
}

.om-map .om-seat.has-person::before {
  display: none;
}

.om-map .om-seat[data-state="mine"] {
  box-shadow: 0 0 0 2px var(--om-active);
}

/* Геометка своего места стоит прямо над столом. Это тот же Material PersonPinCircle, что в действиях портала;
   нажатие проходит в маркер целиком — остров приближает стол и открывает карточку. */
.om-map .om-mine-pin {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 4px);
  width: 30px;
  height: 30px;
  padding: 2px;
  transform: translateX(-50%);
  border: 1px solid var(--om-surface);
  border-radius: 50%;
  background: var(--om-surface);
  box-shadow: var(--mud-elevation-2);
  color: var(--om-accent);
  fill: currentColor;
  pointer-events: none;
}

.om-map .om-avatar {
  display: grid;
  flex-shrink: 0;
  place-items: center;
  width: 28px;
  height: 28px;
  overflow: hidden;
  border-radius: 50%;
  background: color-mix(in srgb, var(--om-accent) 18%, var(--om-surface));
  color: var(--om-accent);
  font-size: 11px;
  font-weight: 600;
  line-height: 1;
}

.om-map .om-avatar img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}

.om-map .om-seat.has-person::after {
  content: attr(data-name);
  width: 64px;
  font-size: 11px;
  font-weight: 500;
  line-height: 1.25;
  white-space: normal;
}

/* Плотность по масштабу: крупно — аватар и имя, средне — имя под аватаром, мелко — только аватар или значок. */
.om-map .om-layer[data-density="stacked"] .om-seat.has-person {
  flex-direction: column;
  gap: 2px;
  padding: 3px;
}

.om-map .om-layer[data-density="stacked"] .om-seat.has-person::after {
  width: 58px;
  font-size: 10px;
  text-align: center;
}

.om-map .om-layer[data-density="avatar"] .om-seat.has-person {
  padding: 2px;
  border-radius: 50%;
}

.om-map .om-layer[data-density="avatar"] .om-seat::after {
  display: none;
}

.om-map .om-layer[data-density="avatar"] .om-seat:not(.has-person) {
  padding: 4px;
}

/* ---- Кухни ---- */

.om-map .om-kitchen {
  --om-kitchen: var(--mud-palette-secondary);
  position: absolute;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 12px;
  transform: translate(-50%, -50%) scale(var(--om-inv));
  border: 1px solid var(--om-kitchen);
  border-radius: 13px;
  background: var(--om-surface);
  box-shadow: var(--mud-elevation-4);
  color: var(--om-text);
  font-family: inherit;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
  pointer-events: auto;
}

.om-map .om-kitchen:hover {
  box-shadow: 0 0 0 3px var(--om-active);
}

.om-map .om-kitchen:focus-visible {
  outline: 2px solid var(--om-accent);
  outline-offset: 2px;
}

.om-map .om-kitchen[data-occasion="pizza"] {
  --om-kitchen: var(--mud-palette-warning);
}

.om-map .om-kitchen[data-occasion="birthday"] {
  --om-kitchen: var(--mud-palette-tertiary);
}

.om-map .om-kitchen strong,
.om-map .om-kitchen small {
  display: block;
}

.om-map .om-kitchen strong {
  font-size: 12px;
  font-weight: 600;
}

.om-map .om-kitchen small {
  margin-top: 4px;
  color: var(--om-muted);
  font-size: 10px;
}

.om-map .om-kitchen-symbol {
  font-size: 25px;
  line-height: 1.4;
}

.om-map .om-kitchens[data-compact="true"] .om-kitchen {
  padding: 4px 8px;
}

.om-map .om-kitchens[data-compact="true"] .om-kitchen-copy {
  display: none;
}

/* ---- Рамки выбора и подсветки: толщина не зависит от масштаба ---- */

.om-map .om-frame {
  position: absolute;
  transform-origin: 0 0;
  border-radius: 3px;
  outline: calc(2px * var(--om-inv)) solid var(--om-accent);
  outline-offset: calc(3px * var(--om-inv));
  pointer-events: none;
}

.om-map .om-frame.is-focus {
  animation: om-focus 1.1s ease-out 2;
}

@keyframes om-focus {
  from {
    outline-offset: calc(3px * var(--om-inv));
    outline-color: var(--om-accent);
  }

  to {
    outline-offset: calc(22px * var(--om-inv));
    outline-color: transparent;
  }
}

@media (prefers-reduced-motion: reduce) {
  .om-map .om-frame.is-focus {
    animation: none;
  }
}

/* ---- Миникарта: правый нижний угол; за плавающую панель страницы её сдвигает остров (--om-minimap-*, overlays.js) ---- */

.om-map .om-minimap {
  position: absolute;
  right: var(--om-minimap-right, 16px);
  bottom: var(--om-minimap-bottom, 16px);
  width: 226px;
  height: 135px;
  border: 1px solid var(--om-line);
  border-radius: var(--mud-default-borderradius);
  background: var(--om-surface);
  box-shadow: var(--mud-elevation-4);
  cursor: crosshair;
  touch-action: none;
}

/* Среди панелей страницы миникарте нет места (узкое окно, панели с обеих сторон): прячется, пока место не появится. Размер
   у неё остаётся — по нему остров и узнаёт, что место появилось. */
.om-map .om-minimap.is-crowded {
  visibility: hidden;
}

/* Окно уже 600 px: на телефоне жесты и поиск заменяют миникарту. */
.om-map[data-size="xs"] .om-minimap {
  display: none;
}

/* ---- Углы зума ---- */

.om-map .om-corners {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.om-map .om-corners.is-zooming {
  pointer-events: auto;
  touch-action: none;
}

.om-map .om-corners-outline {
  position: absolute;
  left: 0;
  top: 0;
  border: 1px dashed color-mix(in srgb, var(--om-accent) 32%, transparent);
  border-radius: 5px;
}

.om-map .om-corner {
  position: absolute;
  left: 0;
  top: 0;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  cursor: nesw-resize;
  pointer-events: auto;
  touch-action: none;
}

.om-map .om-corner[data-corner="0"],
.om-map .om-corner[data-corner="3"] {
  cursor: nwse-resize;
}

.om-map .om-corner::after {
  content: "";
  position: absolute;
  inset: 10px;
  border: 2px solid var(--om-accent);
  border-radius: 3px;
  background: var(--om-surface);
  box-shadow: var(--mud-elevation-2);
}

.om-map .om-corner:is(:hover, :focus-visible, .is-active) {
  outline: 2px solid var(--om-accent);
  outline-offset: -3px;
  background: color-mix(in srgb, var(--om-accent) 15%, transparent);
}

/* ---- Редактор (data-mode="edit"): курсоры инструментов, черновик фигуры, направляющие, панель у выделенного ---- */

.om-map[data-mode="edit"] {
  cursor: default;
}

.om-map[data-mode="edit"][data-tool="hand"] {
  cursor: grab;
}

.om-map[data-mode="edit"]:is([data-tool="wall"], [data-tool="zone"], [data-tool="text"], [data-tool="place"]) {
  cursor: crosshair;
}

.om-map[data-mode="edit"].is-panning {
  cursor: grabbing;
}

/* Сюда можно бросить предмет из библиотеки. */
.om-map.is-drop-target {
  box-shadow: inset 0 0 0 2px var(--om-accent);
}

/* Черновик стены или зоны — в координатах плана, на слое с одной transform на камеру (как маркеры). */
.om-map .om-draft {
  position: absolute;
  transform-origin: 0 0;
  background: color-mix(in srgb, var(--om-accent) 22%, transparent);
  outline: calc(1px * var(--om-inv)) solid var(--om-accent);
  pointer-events: none;
}

.om-map .om-draft[data-kind="wall"] {
  background: color-mix(in srgb, var(--om-accent) 55%, transparent);
  outline: none;
}

/* Указатель над началом цепочки: щелчок замкнёт контур — отрезок плотнее. */
.om-map .om-draft[data-kind="wall"].is-closing {
  background: var(--om-accent);
}

/* Направляющие по краям и центрам: две линии на весь экран карты. */
.om-map .om-guides {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

.om-map .om-guides line {
  stroke: var(--mud-palette-secondary);
  stroke-width: 1;
  stroke-dasharray: 4 3;
  shape-rendering: crispEdges;
}

/* Плавающая панель действий у выделенного: место задаёт остров (transform), здесь — только вид. Не `om-actions`: так
   называется панель действий страницы (office.css). */
.om-map .om-selection-actions {
  position: absolute;
  left: 0;
  top: 0;
  display: flex;
  gap: 2px;
  padding: 4px;
  border: 1px solid var(--om-line);
  border-radius: var(--mud-default-borderradius);
  background: var(--om-surface);
  box-shadow: var(--mud-elevation-4);
  cursor: default;
}

.om-map .om-action {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--om-text);
  cursor: pointer;
}

.om-map .om-action svg {
  width: 20px;
  height: 20px;
  fill: currentColor;
}

.om-map .om-action:hover {
  background: var(--om-hover);
}

.om-map .om-action:focus-visible {
  outline: 2px solid var(--om-accent);
  outline-offset: 1px;
}

.om-map .om-action[data-action="remove"] {
  color: var(--mud-palette-error);
}

/* Подсказка инструмента «Стена»: по центру полосы внизу окна. Края полосы (панели страницы, миникарта) задаёт остров
   переменными --om-hint-*; ширина — по тексту, в узкой полосе текст переносится.
   Указатель она не ловит: щелчок по тексту ставит точку стены на плане под ней (иначе у нижнего края окна точка под
   подсказкой недостижима — нажатие уходит в data-om-ui и остров его пропускает); кликабельна только кнопка «Готово».
   Протяжкой текст не выделяется: user-select: none унаследован от .om-map. */
.om-map .om-draw-hint {
  position: absolute;
  left: var(--om-hint-left, 16px);
  right: var(--om-hint-right, 16px);
  bottom: var(--om-hint-bottom, 16px);
  display: flex;
  align-items: center;
  gap: 12px;
  width: fit-content;
  margin-inline: auto;
  padding: 6px 6px 6px 14px;
  border: 1px solid var(--om-line);
  border-radius: var(--mud-default-borderradius);
  background: var(--om-surface);
  box-shadow: var(--mud-elevation-4);
  color: var(--om-text);
  font-size: 13px;
  line-height: 1.35;
  pointer-events: none;
}

.om-map .om-draw-hint-done {
  flex: none;
  pointer-events: auto;
  min-height: 32px;
  padding: 0 14px;
  border: 0;
  border-radius: var(--mud-default-borderradius);
  background: var(--om-accent);
  color: var(--om-on-accent);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.om-map .om-draw-hint-done:hover {
  background: color-mix(in srgb, var(--om-accent) 85%, var(--om-surface));
}

.om-map .om-draw-hint-done:focus-visible {
  outline: 2px solid var(--om-accent);
  outline-offset: 2px;
}

/* ---- Объёмный вид (data-view="3d" на корне): холст WebGL, подписи, маркер поворота, счётчики ?diag=1 ---- */

/* Плоские слои на время 3D прячутся; маркеры мест и кухонь остаются — их точку на экране ставит камера 3D. */
.om-map[data-view="3d"] :is(.om-canvas, .om-frames, .om-corners, .om-edit, .om-guides) {
  display: none;
}

.om-map .om-layer[data-view="3d"] :is(.om-seat, .om-kitchen) {
  left: 0 !important;
  top: 0 !important;
}

.om-map .om-3d {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.om-map .om-3d-canvas {
  display: block;
  width: 100%;
  height: 100%;
  touch-action: none;
}

.om-map[data-view="3d"][data-mode="edit"] {
  cursor: grab;
}

.om-map[data-view="3d"][data-mode="edit"].is-over {
  cursor: move;
}

.om-map[data-view="3d"].is-pan-mode {
  cursor: grab;
}

.om-map[data-view="3d"].is-moving {
  cursor: move;
}

.om-map[data-view="3d"].is-panning {
  cursor: grabbing;
}

/* Подписи зон и подписи плана — лицом к экрану; только для глаз, указатель проходит сквозь них к плану. */
.om-map .om-3d-labels {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.om-map .om-3d-label {
  position: absolute;
  left: 0;
  top: 0;
  max-width: 190px;
  padding: 6px 9px;
  overflow: hidden;
  border: 1px solid var(--om-line);
  border-radius: 7px;
  background: var(--om-surface);
  box-shadow: var(--mud-elevation-2);
  color: var(--om-text);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.3;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.om-map .om-3d-label.is-selected {
  border: 2px solid var(--om-accent);
}

/* Круг поворота в 3D — часть сцены (plan-3d/viewer.js: ленты на полу цвета поверхности и акцента), стилей у него нет. */

/* Угол предмета, пока его поворачивают мышью: в 3D — у маркера на круге, в 2D — у указателя. Размер задан здесь
   (60 × 30), острова его не меряют. */
.om-map .om-angle {
  position: absolute;
  left: 0;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  width: 60px;
  height: 30px;
  border: 2px solid var(--om-accent);
  border-radius: 15px;
  background: var(--om-surface);
  box-shadow: var(--mud-elevation-2);
  color: var(--om-text);
  font-size: 18px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  pointer-events: none;
}

.om-map .om-angle[hidden] {
  display: none;
}

/* Маркер поворота над выбранным предметом (правка в 3D): нажать и вести по кругу — повернуть, щелчок и Enter — на 90°. */
.om-map .om-3d-rotate {
  position: absolute;
  left: 0;
  top: 0;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 2px solid var(--om-accent);
  border-radius: 50%;
  background: var(--om-surface);
  box-shadow: var(--mud-elevation-2);
  color: var(--om-accent);
  font-family: inherit;
  font-size: 22px;
  line-height: 1;
  cursor: crosshair;
  touch-action: none;
}

.om-map .om-3d-rotate:is(:hover, :focus-visible) {
  background: var(--om-accent);
  color: var(--om-on-accent);
}

/* Счётчики кадра (?diag=1): левый нижний угол окна карты, поверх плана, мимо указателя. */
.om-map .om-3d-diag {
  position: absolute;
  left: 12px;
  bottom: 12px;
  max-width: calc(100% - 24px);
  padding: 6px 9px;
  border: 1px solid var(--om-line);
  border-radius: var(--mud-default-borderradius);
  background: var(--om-surface);
  color: var(--om-text);
  font-family: ui-monospace, monospace;
  font-size: 11px;
  line-height: 1.45;
  white-space: pre-wrap;
  pointer-events: none;
}

/* Палец крупнее мыши: область нажатия 44 px. */
@media (pointer: coarse) {
  .om-map .om-corner {
    width: 44px;
    height: 44px;
  }

  .om-map .om-corner::after {
    inset: 15px;
  }

  .om-map .om-action {
    width: 44px;
    height: 44px;
  }

  .om-map .om-draw-hint-done {
    min-height: 44px;
  }
}
