/* Tracker — premium dark admin theme (Stage 7.2).
   Plain CSS, no build step. Status enum keys stay English in class names;
   visible text is Russian (rendered in templates). */

:root {
  --bg: #0c1015;
  --bg-2: #0f141b;
  --panel: #161c25;
  --panel-2: #1d2630;
  --panel-3: #232e3a;
  --text: #e7edf4;
  --muted: #93a1b1;
  --muted-2: #6b7785;
  --border: #28333f;
  --border-soft: #20292f;
  --accent: #4f8cff;
  --accent-soft: rgba(79, 140, 255, 0.15);

  /* status palette — restrained, distinct */
  --ok: #2ea36b;
  --warn: #d39a2a;
  --danger: #d4593a;
  --online: #4f8cff;
  --active: #2ea36b;
  --idle: #d39a2a;
  --afk: #e0623a;
  --offline: #5a6675;
  --pending: #8b6ee0;

  --radius: 12px;
  --radius-sm: 8px;
  --shadow: 0 1px 2px rgba(0,0,0,0.35), 0 6px 20px rgba(0,0,0,0.22);
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: "Inter", -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background:
    radial-gradient(1200px 600px at 80% -10%, rgba(79,140,255,0.08), transparent 60%),
    var(--bg);
  color: var(--text);
  font-size: 14px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* --- top bar ------------------------------------------------------------- */
.topbar {
  display: flex;
  align-items: center;
  gap: 1.75rem;
  padding: 0.7rem 1.5rem;
  background: rgba(15, 20, 27, 0.85);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 10;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.62rem;
  color: var(--text);
}
.brand:hover { text-decoration: none; }
.brand-emblem {
  position: relative;
  width: 30px;
  height: 30px;
  flex: 0 0 30px;
  border: 1px solid #3b4a5b;
  border-radius: 8px;
  background:
    linear-gradient(145deg, rgba(79, 140, 255, 0.17), rgba(79, 140, 255, 0.025)),
    #141c25;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    0 5px 14px rgba(0, 0, 0, 0.25);
}
.brand-emblem::before,
.brand-emblem::after {
  content: "";
  position: absolute;
  display: block;
  border-radius: 2px;
}
.brand-emblem::before {
  width: 15px;
  height: 2px;
  top: 8px;
  left: 7px;
  background: #dce7f4;
  box-shadow: 0 0 9px rgba(220, 231, 244, 0.1);
}
.brand-emblem::after {
  width: 2px;
  height: 14px;
  top: 8px;
  left: 13.5px;
  background: linear-gradient(180deg, #dce7f4 0 15%, #6198ff 15% 100%);
}
.brand-wordmark {
  color: #f0f4f9;
  font-size: 0.92rem;
  font-weight: 760;
  line-height: 1;
  letter-spacing: 0.17em;
  text-transform: uppercase;
}
.topbar nav { display: flex; gap: 0.35rem; }
.topbar nav a {
  color: var(--muted);
  padding: 0.4rem 0.75rem;
  border-radius: var(--radius-sm);
  font-weight: 500;
  transition: background 0.12s, color 0.12s;
}
.topbar nav a:hover { color: var(--text); background: var(--panel-2); text-decoration: none; }
.topbar nav a.is-active { color: var(--text); background: var(--accent-soft); }
/* Stage 10.1: live status + logout are grouped on the right via .topbar-right. */
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 1.1rem; }
.topbar .logout { display: flex; align-items: center; gap: 0.85rem; }
.topbar .who { color: var(--muted); font-size: 13px; }
.role-badge {
  display: inline-block;
  margin-left: 0.35rem;
  padding: 0.08rem 0.38rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--accent);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.03em;
}

/* Stage 10.49: restricted-account management in Settings. */
.access-user-list { display: grid; gap: 0.8rem; margin-top: 1rem; }
.access-user-card {
  padding: 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--panel);
}
.access-user-head, .access-user-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}
.access-user-actions { margin-top: 0.8rem; justify-content: flex-start; }
.access-groups {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.9rem;
  margin: 0.75rem 0;
}
.access-groups-label { width: 100%; color: var(--muted); font-size: 12px; }
.access-groups .check { margin: 0; }
.access-password-form { display: grid; gap: 0.55rem; margin-top: 0.65rem; }
@media (max-width: 640px) {
  .access-user-head, .access-user-actions { align-items: stretch; flex-direction: column; }
  .access-user-head .mono { overflow-wrap: anywhere; }
  .access-groups { align-items: flex-start; flex-direction: column; }
}

/* live "Обновлено HH:MM · авто 1м" topbar indicator (subtle, no bright blink) */
.topbar-status { display: inline-flex; align-items: center; gap: 0.3rem; font-size: 12px; color: var(--muted); white-space: nowrap; }
.topbar-status .live-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--muted-2); display: inline-block; }
.topbar-status .live-dot.is-live { background: var(--ok); animation: livepulse 2.6s ease-out infinite; }
@keyframes livepulse {
  0% { box-shadow: 0 0 0 0 rgba(46,163,107,0.45); }
  70% { box-shadow: 0 0 0 6px rgba(46,163,107,0); }
  100% { box-shadow: 0 0 0 0 rgba(46,163,107,0); }
}
.topbar-status .live-label, .topbar-status .live-auto { color: var(--muted-2); }
.topbar-status .live-time { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }

.content { padding: 1.5rem; max-width: 1320px; margin: 0 auto; }
.foot {
  padding: 1.35rem 1.5rem 1.55rem;
  color: var(--muted);
  border-top: 1px solid var(--border-soft);
  max-width: 1320px;
  margin: 0 auto;
  text-align: center;
}
.foot-secure {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  color: #9aa7b6;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.06em;
}
.foot-secure .login-lock {
  width: 12px;
  height: 10px;
  margin-top: 2px;
  border-color: #8b97a6;
}
.foot-secure .login-lock::before {
  width: 7px;
  height: 6px;
  left: 1px;
  bottom: 7px;
  border-color: #8b97a6;
}

/* --- headings ------------------------------------------------------------ */
h1 { margin: 0; font-size: 1.5rem; letter-spacing: -0.01em; }
h2 { margin: 0; font-size: 1.1rem; }
.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 1rem; margin-bottom: 1.25rem; }
.page-head .muted { margin: 0.3rem 0 0; }
.section-head { display: flex; align-items: center; gap: 0.75rem; margin: 1.75rem 0 0.85rem; }
.crumbs { margin: 0 0 0.75rem; }
.muted { color: var(--muted); }
.mono { font-family: "JetBrains Mono", Consolas, Menlo, monospace; font-size: 12px; }

/* --- summary ribbon (Stage 7.3 compact redesign) ------------------------- */
.stat-ribbon {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  margin: 0 0 0.75rem;
  align-items: stretch;
}
.stat-chip {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: linear-gradient(135deg, var(--panel), var(--panel-2));
  border: 1px solid var(--border);
  border-left: 3px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.35rem 0.75rem 0.35rem 0.6rem;
  min-width: 80px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.25);
  position: relative;
}
.stat-chip .sc-num {
  font-size: 1.3rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.01em;
}
.stat-chip .sc-lbl {
  color: var(--muted);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  line-height: 1.25;
  white-space: nowrap;
}
/* color accent per chip type */
.sc-devices    { border-left-color: var(--accent); }
.sc-devices .sc-num { color: var(--accent); }
.sc-pending    { border-left-color: var(--pending); }
.sc-pending .sc-num { color: var(--pending); }
.sc-approved   { border-left-color: var(--ok); }
.sc-approved .sc-num { color: var(--ok); }
.sc-online     { border-left-color: var(--online); }
.sc-online .sc-num { color: var(--online); }
.sc-active     { border-left-color: var(--active); }
.sc-active .sc-num { color: var(--active); }
.sc-idle       { border-left-color: var(--idle); }
.sc-idle .sc-num { color: var(--idle); }
/* Stage 7.4 activity-level chips: high=green, normal=blue, low=amber. */
.sc-high       { border-left-color: var(--active); }
.sc-high .sc-num { color: var(--active); }
.sc-normal     { border-left-color: var(--online); }
.sc-normal .sc-num { color: var(--online); }
.sc-low        { border-left-color: var(--idle); }
.sc-low .sc-num { color: var(--idle); }
.sc-afk        { border-left-color: var(--afk); }
.sc-afk .sc-num { color: var(--afk); }
.sc-offline    { border-left-color: var(--offline); }
.sc-offline .sc-num { color: var(--offline); }
.sc-blocked    { border-left-color: var(--danger); }
.sc-blocked .sc-num { color: var(--danger); }
.sc-deleted    { border-left-color: var(--muted-2); }
.sc-deleted .sc-num { color: var(--muted-2); }

/* Stage 10.9: the ribbon chips are clickable status filters. Keep the chip look
   (no link underline / inherited text colour) but add a clear interactive +
   selected state so it reads as a filter, not plain text. */
a.stat-chip {
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  transition: transform 0.08s ease, box-shadow 0.12s ease, border-color 0.12s ease;
}
a.stat-chip:hover {
  transform: translateY(-1px);
  border-color: var(--accent);
  box-shadow: 0 3px 10px rgba(0,0,0,0.35);
}
a.stat-chip:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.stat-chip.is-selected {
  border-color: var(--accent);
  background: linear-gradient(135deg, var(--panel-2), var(--panel));
  box-shadow: inset 0 0 0 1px var(--accent), 0 2px 8px rgba(0,0,0,0.35);
}
.stat-chip.is-selected .sc-lbl { color: var(--text); }

/* Stage 10.21: the «Скрытые» nav chip. Muted tone (it is not a live status), and
   `.is-nav` marks it as a chip that NAVIGATES to a separate page rather than
   filtering in place — a subtle left divider sets it apart from the filter chips,
   and a chevron after the label hints "opens a view". */
.sc-hidden     { border-left-color: var(--muted-2); }
.sc-hidden .sc-num { color: var(--muted-2); }
.stat-chip.is-nav {
  margin-left: 0.6rem;
  border-left-style: dashed;
}
.stat-chip.is-nav::before {
  content: "";
  position: absolute;
  left: -0.35rem;
  top: 20%;
  bottom: 20%;
  width: 1px;
  background: var(--border);
}
.stat-chip.is-nav .sc-lbl::after {
  content: " ›";
  color: var(--muted);
  font-weight: 700;
}

/* --- legacy summary cards (kept for compatibility, unused in 7.3) --------- */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(118px, 1fr));
  gap: 0.85rem;
  margin: 0 0 0.5rem;
}
.card {
  background: linear-gradient(180deg, var(--panel), var(--panel-2));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.9rem 1rem;
  text-align: center;
  position: relative;
  overflow: hidden;
  box-shadow: var(--shadow);
}
.card::before {
  content: "";
  position: absolute; inset: 0 auto 0 0; width: 3px;
  background: var(--border); opacity: 0.6;
}
.card .num { font-size: 1.55rem; font-weight: 700; line-height: 1.1; }
.card .num.mono { font-size: 0.95rem; word-break: break-all; }
.card .lbl { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; margin-top: 0.2rem; }
.card.accent-pending::before { background: var(--pending); }
.card.accent-online::before { background: var(--online); }
.card.accent-active::before { background: var(--active); }
.card.accent-idle::before { background: var(--idle); }
.card.accent-afk::before { background: var(--afk); }
.card.accent-offline::before { background: var(--offline); }
/* Stage 7.4 level accents: high=green, normal=blue, low=amber. */
.card.accent-high::before { background: var(--active); }
.card.accent-normal::before { background: var(--online); }
.card.accent-low::before { background: var(--idle); }

/* --- status legend ------------------------------------------------------- */
.legend {
  display: flex; flex-wrap: wrap; gap: 0.5rem 1.1rem;
  margin: 0 0 1rem; color: var(--muted); font-size: 12px;
}
.legend-item { display: inline-flex; align-items: center; gap: 0.4rem; }
.dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }

/* --- device row-cards ---------------------------------------------------- */
.device-list { display: flex; flex-direction: column; gap: 0.7rem; }
.device-card {
  background: linear-gradient(180deg, var(--panel), var(--panel-2));
  border: 1px solid var(--border);
  border-left: 3px solid var(--border);
  border-radius: var(--radius);
  padding: 0.75rem 1rem;
  box-shadow: var(--shadow);
  transition: border-color 0.12s, transform 0.12s;
}
.device-card:hover { border-color: #34465a; }
.life-border-approved { border-left-color: var(--active); }
.life-border-pending { border-left-color: var(--pending); }
.life-border-blocked { border-left-color: var(--warn); }
.life-border-deleted { border-left-color: var(--offline); }

.dc-main { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; }
.dc-name { font-size: 1rem; font-weight: 650; color: var(--text); }
.dc-sub { margin-top: 0.1rem; }
.dc-status { display: flex; flex-wrap: wrap; gap: 0.3rem; justify-content: flex-end; }

.dc-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(145px, 1fr));
  gap: 0.4rem 1rem;
  margin: 0.55rem 0;
  padding: 0.55rem 0;
  border-top: 1px solid var(--border-soft);
  border-bottom: 1px solid var(--border-soft);
}
.dc-field { display: flex; flex-direction: column; gap: 0.12rem; min-width: 0; }
.dc-label { color: var(--muted-2); font-size: 10px; text-transform: uppercase; letter-spacing: 0.04em; }
.dc-value { font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Stage 10.32: «Последняя связь» moved onto the identity row (grey, beside the name);
   АФК + Отходы(5–15м) + Проёбы(15+м) framed together as one block in the card grid. */
.dc-lastseen { font-size: 11.5px; color: var(--muted-2); white-space: nowrap; }
.dc-lastseen .dc-ls-val { color: var(--muted); font-variant-numeric: tabular-nums; }
.dc-afk-box {
  grid-column: span 2;
  display: flex; align-items: flex-start; flex-wrap: wrap; gap: 0.4rem 1.25rem;
  padding: 0.32rem 0.6rem; border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm); background: rgba(255,255,255,0.02);
}
.dc-afk-short .dc-value { color: #e0a06a; font-weight: 650; font-variant-numeric: tabular-nums; }
.dc-afk-long .dc-value { color: var(--afk); font-weight: 650; font-variant-numeric: tabular-nums; }

.dc-timeline { margin: 0.35rem 0 0.55rem; }
.dc-timeline .dc-label { display: block; margin-bottom: 0.25rem; }

.dc-footer { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; flex-wrap: wrap; }
/* Stage 10.40: Telegram is a compact bordered control «TG · вкл/выкл [тумблер]» so it
   reads as one grouped chip and (on phones) sits inline among the action buttons. */
.dc-telegram {
  display: inline-flex; align-items: center; gap: 0.3rem; flex-wrap: wrap;
  border: 1px solid var(--border); border-radius: 999px;
  padding: 0.12rem 0.45rem 0.12rem 0.5rem; background: rgba(255,255,255,0.025);
}
.dc-telegram .tg-tag {
  font-size: 10px; font-weight: 700; letter-spacing: 0.04em; color: var(--muted-2);
}
.dc-telegram form { display: inline; margin: 0; }
.dc-actions { display: flex; align-items: center; gap: 0.35rem; flex-wrap: wrap; }
.dc-actions form { margin: 0; }
/* Stage 10.39: «Переименовать» shortens to «Переим.» on phones (the short label is
   hidden on desktop). */
.rn-short { display: none; }

/* Stage 10.21: hidden-devices page. Reuses the device-card shell, but the footer
   holds only the two lifecycle actions: a safe «Вернуть в работу» on the left and
   the destructive «Удалить навсегда» pushed to the right with a divider so it is
   never clicked by accident. */
.hidden-list .hidden-card .dc-grid { margin-bottom: 0.2rem; }
.hidden-actions { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; width: 100%; }
.hidden-actions form { margin: 0; }
.hidden-actions .purge-form {
  margin-left: auto;
  padding-left: 0.75rem;
  border-left: 1px solid var(--border);
}
.hidden-intro { margin: 0.2rem 0 1.1rem; max-width: 60ch; }
@media (max-width: 560px) {
  .hidden-actions .purge-form {
    margin-left: 0;
    padding-left: 0;
    border-left: none;
  }
}

/* inline rename collapses into a disclosure to keep actions uncluttered */
.dc-rename { position: relative; }
.dc-rename summary { list-style: none; user-select: none; }
.dc-rename summary::-webkit-details-marker { display: none; }
.dc-rename[open] summary { outline: 1px solid var(--border); }
.dc-rename .rename {
  display: flex; gap: 0.3rem; margin-top: 0.4rem;
  position: absolute; right: 0; z-index: 5;
  background: var(--panel-3); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 0.5rem; box-shadow: var(--shadow);
}
.dc-rename .rename input { width: 160px; }

/* working hours inline form */
.dc-wh { position: relative; }
.dc-wh summary { list-style: none; user-select: none; }
.dc-wh summary::-webkit-details-marker { display: none; }
.dc-wh[open] summary { outline: 1px solid var(--accent); color: var(--accent); }
.dc-wh-panel {
  position: absolute; right: 0; z-index: 6;
  background: var(--panel-3); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 0.75rem; box-shadow: var(--shadow);
  min-width: 260px; margin-top: 0.3rem;
}
.dc-wh-panel .wh-title { font-size: 11.5px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 0.5rem; }
.wh-form .wh-row { display: flex; gap: 0.4rem; align-items: center; flex-wrap: wrap; margin-bottom: 0.4rem; }
.wh-form .wh-row label { font-size: 12px; color: var(--muted); min-width: 50px; }
.wh-form input[type=time], .wh-form input[type=text] { width: 100px; }
.wh-form .wh-actions { display: flex; gap: 0.35rem; margin-top: 0.5rem; flex-wrap: wrap; }
.pending-wh-panel form.wh-form {
  display: flex; flex-direction: column; align-items: stretch; gap: 0;
}

/* Stage 20: «Уже в системе» — one-click chips for shifts already assigned to
   somebody. Each chip is its own form, so the selectors are scoped tighter than the
   generic `.popover-panel form` layout rules that also apply inside this panel. */
.wh-presets {
  margin-top: 0.6rem; padding-top: 0.5rem;
  border-top: 1px solid var(--border-soft);
}
.wh-presets-lbl {
  font-size: 10px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--muted-2); margin-bottom: 0.4rem;
}
.wh-presets .wh-preset-list {
  display: flex; flex-wrap: wrap; gap: 0.3rem;
  max-height: 168px; overflow-y: auto;
}
.wh-presets .wh-preset-list form {
  display: inline-flex; margin: 0; flex: 0 0 auto; min-width: 0;
}
.wh-preset-chip {
  display: inline-flex; align-items: baseline; gap: 0.3rem;
  border: 1px solid var(--border); border-radius: 999px;
  background: rgba(255,255,255,0.03); color: var(--text);
  padding: 0.16rem 0.55rem; cursor: pointer;
  font-family: inherit; line-height: 1.3; white-space: nowrap;
  transition: border-color 0.12s, background 0.12s, color 0.12s;
}
.wh-preset-chip:hover { border-color: var(--accent); background: var(--accent-soft); }
.wh-preset-chip .pc-hours {
  font-size: 11.5px; font-weight: 650; font-variant-numeric: tabular-nums;
}
.wh-preset-chip .pc-days, .wh-preset-chip .pc-count {
  font-size: 9.5px; color: var(--muted-2); letter-spacing: 0.02em;
}
.wh-preset-chip:hover .pc-days, .wh-preset-chip:hover .pc-count { color: #9cc0ff; }
.full-day-badge { background: rgba(90, 174, 219, 0.16); color: #8ed7ff; border: 1px solid rgba(90, 174, 219, 0.4); }

/* Stage 19: card status row = «смена ✎» + «Активность сейчас: плашка». The shift is
   a bordered pill in the same family as the Telegram chip; a personal shift is tinted
   with the accent so an inherited global schedule is distinguishable at a glance. */
.dc-shift {
  position: relative;
  display: inline-flex; align-items: center; gap: 0.32rem;
  border: 1px solid var(--border); border-radius: 999px;
  padding: 0.1rem 0.3rem 0.1rem 0.55rem;
  background: rgba(255,255,255,0.025);
}
.dc-shift.is-personal { border-color: rgba(79,140,255,0.38); background: var(--accent-soft); }
.dc-shift .shift-lbl {
  font-size: 10px; font-weight: 700; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--muted-2);
}
.dc-shift .shift-val {
  font-size: 11.5px; font-weight: 650; color: var(--muted);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.dc-shift.is-personal .shift-val { color: #9cc0ff; }
/* Stage 22/31: the period chip — «● СМЕНА ИДЁТ | сегодня, 05.10 | 7h 5m из 12h» or
   «СМЕНА ЗАВЕРШЕНА | вчера, 04.10». It answers the first question the numbers below
   raise, so it is a real chip in the same family as the shift chip rather than the
   grey aside it started as. The palette is deliberately NOT the blue accent (that
   means "personal shift" here): a finished period is a warm neutral stamp, a running
   one takes the live blue with a pulsing dot, one that has not started yet is plain
   grey. Stage 31 dropped the hours (they repeated the shift chip beside it) and added
   the elapsed/total progress for a running period. */
.dc-period {
  display: inline-flex; align-items: center; gap: 0.3rem;
  border: 1px solid rgba(224,160,106,0.3); border-radius: 999px;
  padding: 0.1rem 0.5rem 0.1rem 0.55rem;
  background: rgba(224,160,106,0.09);
  white-space: nowrap;
}
.dc-period .dcp-lbl {
  font-size: 10px; font-weight: 700; letter-spacing: 0.04em;
  text-transform: uppercase; color: #c99367;
}
.dc-period .dcp-val {
  font-size: 11.5px; font-weight: 650; color: #f0cba6;
  font-variant-numeric: tabular-nums;
}
.dc-period .dcp-prog {
  font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums;
  padding-left: 0.3rem; border-left: 1px solid rgba(224,160,106,0.25);
}
.dc-period.is-upcoming { border-color: var(--border); background: rgba(255,255,255,0.025); }
.dc-period.is-upcoming .dcp-lbl { color: var(--muted-2); }
.dc-period.is-upcoming .dcp-val { color: var(--muted); }
/* Still running: a small pulsing dot before the label, so "in progress" is readable
   at a glance without another word competing with the date. */
.dc-period.is-running { border-color: rgba(79,140,255,0.4); background: var(--accent-soft); }
.dc-period.is-running .dcp-lbl { color: #9cc0ff; }
.dc-period.is-running .dcp-val { color: #cfe0ff; }
.dc-period.is-running .dcp-prog { color: #9cc0ff; border-left-color: rgba(79,140,255,0.28); }
.dc-period.is-running::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent); box-shadow: 0 0 0 0 rgba(79,140,255,0.55);
  animation: dcp-live 2.4s ease-out infinite;
}
@keyframes dcp-live {
  0%   { box-shadow: 0 0 0 0 rgba(79,140,255,0.5); }
  70%  { box-shadow: 0 0 0 5px rgba(79,140,255,0); }
  100% { box-shadow: 0 0 0 0 rgba(79,140,255,0); }
}
@media (prefers-reduced-motion: reduce) {
  .dc-period.is-running::before { animation: none; }
}
.shift-edit { position: relative; display: inline-flex; }
.shift-edit > summary {
  list-style: none; user-select: none; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  width: 19px; height: 19px; border-radius: 50%;
  color: var(--muted-2);
  transition: color 0.12s, background 0.12s;
}
.shift-edit > summary::-webkit-details-marker { display: none; }
.shift-edit > summary:hover { color: var(--accent); background: rgba(79,140,255,0.16); }
.shift-edit[open] > summary { color: var(--accent); background: rgba(79,140,255,0.22); }
/* Pencil drawn in CSS (no external assets, like the login lock/monogram). */
.shift-pen { position: relative; display: block; width: 11px; height: 11px; }
.shift-pen::before {
  content: ""; position: absolute; left: 1.5px; bottom: 2.5px;
  width: 9.5px; height: 3px; border-radius: 1px; background: currentColor;
  transform: rotate(-45deg); transform-origin: left bottom;
}
.shift-pen::after {
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 11px; height: 1.5px; border-radius: 1px;
  background: currentColor; opacity: 0.6;
}
.dc-act { display: inline-flex; align-items: center; gap: 0.35rem; }
.dc-act-lbl {
  font-size: 10px; font-weight: 600; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--muted-2); white-space: nowrap;
}

/* danger zone disclosure */
.dc-danger { position: relative; }
.dc-danger summary { list-style: none; user-select: none; }
.dc-danger summary::-webkit-details-marker { display: none; }
.dc-danger[open] summary { color: #e08a72; }
.dc-danger-panel {
  position: absolute; right: 0; z-index: 6;
  background: var(--panel-3); border: 1px solid rgba(212,89,58,0.4);
  border-radius: var(--radius-sm); padding: 0.6rem 0.75rem; box-shadow: var(--shadow);
  margin-top: 0.3rem; display: flex; flex-direction: column; gap: 0.35rem; min-width: 150px;
}
.dc-danger-panel form { margin: 0; }

/* Stage 10.48: pending rows are onboarding cards, not activity reports. */
.pending-card-main {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.75rem; min-width: 0;
}
.pending-identity { min-width: 0; }
.pending-identity .device-name {
  font-size: 16px; font-weight: 650; overflow-wrap: anywhere;
}
.pending-meta {
  display: flex; gap: 0.35rem 0.8rem; align-items: center;
  flex-wrap: wrap; margin-top: 0.2rem; font-size: 12px;
}
.pending-onboarding-actions {
  display: flex; align-items: center; gap: 0.45rem;
  flex-wrap: wrap; margin-top: 0.75rem; min-width: 0;
}
.pending-onboarding-actions form { margin: 0; }
.pending-action-panel { position: relative; }
.pending-action-panel summary { list-style: none; user-select: none; }
.pending-action-panel summary::-webkit-details-marker { display: none; }
.pending-action-panel[open] summary { outline: 1px solid var(--accent); }
.popover-panel {
  position: absolute; left: 0; z-index: 7; margin-top: 0.3rem;
  min-width: 280px; padding: 0.65rem;
  background: var(--panel-3); border: 1px solid var(--border);
  border-radius: var(--radius-sm); box-shadow: var(--shadow);
}
.popover-panel form {
  display: flex; align-items: center; gap: 0.4rem; min-width: 0;
}
.popover-panel input, .popover-panel select { min-width: 0; flex: 1 1 150px; }
.popover-panel.group-panel form + form { margin-top: 0.5rem; }

input[type=time] {
  background: var(--bg-2);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: 0.35rem 0.5rem;
  font-size: 13px;
  color-scheme: dark;
}
input[type=time]:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

.empty-state {
  background: var(--panel);
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  padding: 2.5rem 1.5rem;
  text-align: center;
}
.empty-state p { margin: 0.25rem 0; }

/* --- mini timeline (row strip) ------------------------------------------- */
/* Stage 10.25: the row graph is now full card width (was capped at 520px) so the
   per-hour axis below it is readable; the отходы strip + cells + axis all share it. */
.mini-tl-wrap { max-width: 100%; }
/* Stage 10.25: thin отходы strip above the row mini-timeline (reuses .afk-seg /
   .afk-short / .afk-long colours from the device-detail strip). */
.mini-afk-strip { height: 7px; margin: 0 0 2px; border-radius: 4px; }
.mini-timeline {
  display: flex;
  width: 100%;
  height: 18px;
  border: 1px solid var(--border);
  border-radius: 5px;
  overflow: hidden;
  background: var(--bg-2);
}
.mini-timeline.is-empty { opacity: 0.55; }
.timeline-segment { flex: 1 1 0; min-width: 0; }
.timeline-segment + .timeline-segment { border-left: 1px solid rgba(0,0,0,0.28); }

/* Stage 10.2: sparse, positioned time axis under the row strip. Fixed height so
   the ~5s auto-refresh never shifts the layout. */
.mini-tl-axis {
  position: relative; height: 17px; margin-top: 1px;
  font-size: 10px; color: var(--muted-2); overflow: hidden;
}
.mini-tl-axis .mtl-ax {
  position: absolute; top: 5px; transform: translateX(-50%);
  white-space: nowrap; font-variant-numeric: tabular-nums; line-height: 12px;
}
/* Stage 10.3: a subtle 1px tick anchored at the label's true point so it is clear
   which spot on the bar each label (e.g. 19:00 / 21:00) marks. The tick offset
   matches the label's alignment transform so it lands exactly on the percent. */
.mini-tl-axis .mtl-ax::before {
  content: ""; position: absolute; top: -5px; left: 50%; transform: translateX(-50%);
  width: 1px; height: 4px; background: var(--muted-2); opacity: 0.65;
}
.mini-tl-axis .mtl-ax.mtl-first { transform: none; }
.mini-tl-axis .mtl-ax.mtl-first::before { left: 0; transform: none; }
.mini-tl-axis .mtl-ax.mtl-last { transform: translateX(-100%); }
.mini-tl-axis .mtl-ax.mtl-last::before { left: 100%; transform: translateX(-100%); }
.mini-tl-axis .mtl-empty { position: absolute; left: 0; top: 5px; }

/* --- badges -------------------------------------------------------------- */
.badge {
  display: inline-flex; align-items: center;
  padding: 0.18rem 0.6rem;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: #fff;
  white-space: nowrap;
}
.act-active, .dot.act-active { background: var(--active); }
.act-idle, .dot.act-idle { background: var(--idle); }
.act-afk, .dot.act-afk { background: var(--afk); }
.act-offline, .dot.act-offline { background: var(--offline); }
/* Stage 7.4 meaningful-activity levels: high=green, normal=blue, low=amber. */
.act-high_activity, .dot.act-high_activity { background: var(--active); }
.act-normal_activity, .dot.act-normal_activity { background: var(--online); }
.act-low_activity, .dot.act-low_activity { background: var(--idle); }
.act-no_data, .dot.act-no_data { background: var(--offline); }
.act-none { background: transparent; color: var(--muted); border: 1px solid var(--border); }
.badge.input-unseen { background: transparent; color: var(--idle); border: 1px dashed var(--idle); cursor: help; }
.life-pending, .dot.life-pending { background: var(--pending); }
.life-approved { background: var(--ok); }
.life-blocked { background: var(--warn); }
.life-deleted { background: var(--offline); }

/* Stage 10.21: hidden-devices «last contact» badge. The timestamp is FROZEN at
   deletion (a hidden device is 403'd at /activity), so these describe how recently
   the machine was in contact before it was hidden — not a live presence. */
.hc-online { background: var(--ok); }
.hc-offline { background: var(--offline); }
.hc-stale { background: var(--muted-2); }
.hc-none { background: transparent; color: var(--muted); border: 1px solid var(--border); }

/* --- buttons ------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; gap: 0.3rem;
  border: 1px solid var(--border);
  background: var(--panel-3);
  color: var(--text);
  padding: 0.4rem 0.8rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.2;
  transition: filter 0.12s, border-color 0.12s, background 0.12s;
}
.btn:hover { filter: brightness(1.12); border-color: #3a4d61; text-decoration: none; }
.btn.sm { padding: 0.3rem 0.6rem; font-size: 12px; }
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn.ok { background: var(--ok); border-color: var(--ok); color: #fff; }
.btn.warn { background: var(--warn); border-color: var(--warn); color: #1a1304; }
.btn.danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn.ghost { background: transparent; color: var(--muted); }
.btn.ghost:hover { color: var(--text); background: var(--panel-2); }
.btn.danger.ghost { background: transparent; color: #e08a72; border-color: var(--border); }
.btn.danger.ghost:hover { background: rgba(212,89,58,0.12); border-color: var(--danger); color: #f0a48d; }

input[type=text], input[type=password], input[type=number], select {
  background: var(--bg-2);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: 0.45rem 0.6rem;
  font-size: 13px;
  color-scheme: dark;
}
input:focus, select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

/* Stage 7.4: advanced scoring weights tucked inside a disclosure. */
.settings-form details.adv { margin: 0.2rem 0 0.6rem; }
.settings-form details.adv > summary {
  cursor: pointer; color: var(--muted); font-size: 13px;
  padding: 0.3rem 0; user-select: none;
}
.settings-form details.adv[open] > summary { color: var(--text); }
.settings-form .help-note {
  color: var(--muted); font-size: 12px; line-height: 1.5;
  background: var(--accent-soft); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 0.5rem 0.7rem; margin: 0 0 0.9rem;
}

/* --- login --------------------------------------------------------------- */
body.login-page {
  min-height: 100vh;
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  background:
    radial-gradient(680px 420px at 50% 27%, rgba(79, 140, 255, 0.09), transparent 68%),
    radial-gradient(900px 520px at 50% 110%, rgba(38, 57, 79, 0.13), transparent 70%),
    linear-gradient(180deg, #0b1016 0%, #0c1117 100%);
}
.login-content {
  width: 100%;
  max-width: none;
  min-height: 100%;
  margin: 0;
  padding: clamp(2rem, 7vh, 5.5rem) 1.25rem 2rem;
  display: grid;
  place-items: center;
}
.login-wrap { width: min(100%, 400px); }
.login-card {
  position: relative;
  overflow: hidden;
  background:
    linear-gradient(180deg, rgba(27, 35, 46, 0.98), rgba(19, 26, 35, 0.99));
  border: 1px solid #2b3744;
  border-radius: 16px;
  padding: 2.4rem 2.2rem 2.25rem;
  box-shadow:
    0 24px 70px rgba(0, 0, 0, 0.38),
    0 2px 8px rgba(0, 0, 0, 0.32),
    inset 0 1px 0 rgba(255, 255, 255, 0.035);
}
.login-card::before {
  content: "";
  position: absolute;
  inset: 0 22% auto;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(103, 156, 255, 0.75), transparent);
}
.login-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.85rem;
  margin: 0 0 2.15rem;
  color: #f0f4f9;
}
.login-emblem {
  position: relative;
  width: 40px;
  height: 40px;
  flex: 0 0 40px;
  border: 1px solid #3b4a5b;
  border-radius: 10px;
  background:
    linear-gradient(145deg, rgba(79, 140, 255, 0.17), rgba(79, 140, 255, 0.025)),
    #141c25;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    0 8px 22px rgba(0, 0, 0, 0.28);
}
.login-emblem::before,
.login-emblem::after {
  content: "";
  position: absolute;
  display: block;
  border-radius: 2px;
}
.login-emblem::before {
  width: 20px;
  height: 3px;
  top: 11px;
  left: 9px;
  background: #dce7f4;
  box-shadow: 0 0 12px rgba(220, 231, 244, 0.1);
}
.login-emblem::after {
  width: 3px;
  height: 18px;
  top: 11px;
  left: 17.5px;
  background: linear-gradient(180deg, #dce7f4 0 16%, #6198ff 16% 100%);
}
.login-wordmark {
  font-size: 1.28rem;
  font-weight: 760;
  line-height: 1;
  letter-spacing: 0.17em;
  text-transform: uppercase;
}
.login-form {
  display: flex;
  flex-direction: column;
  gap: 1.05rem;
}
.login-form label {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}
.login-form label > span {
  color: #a8b4c2;
  font-size: 11px;
  font-weight: 650;
  letter-spacing: 0.055em;
  text-transform: uppercase;
}
.login-form input {
  width: 100%;
  height: 47px;
  padding: 0 0.85rem;
  color: var(--text);
  background: #0d131a;
  border: 1px solid #2b3743;
  border-radius: 9px;
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.28);
  transition: border-color 0.14s ease, box-shadow 0.14s ease, background 0.14s ease;
}
.login-form input:hover { border-color: #384858; }
.login-form input:focus {
  outline: none;
  border-color: #5f91ef;
  background: #0f161e;
  box-shadow:
    0 0 0 3px rgba(79, 140, 255, 0.13),
    inset 0 1px 2px rgba(0, 0, 0, 0.22);
}
.login-form input:-webkit-autofill,
.login-form input:-webkit-autofill:hover,
.login-form input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--text);
  -webkit-box-shadow: 0 0 0 1000px #0d131a inset;
  caret-color: var(--text);
}
.login-form button {
  height: 47px;
  margin-top: 0.3rem;
  padding: 0 1rem;
  border: 1px solid #6a9bfa;
  border-radius: 9px;
  color: #fff;
  background: linear-gradient(180deg, #5d93f8, #477ee3);
  box-shadow:
    0 8px 22px rgba(37, 91, 188, 0.2),
    inset 0 1px 0 rgba(255, 255, 255, 0.18);
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.035em;
  transition: transform 0.12s ease, filter 0.12s ease, box-shadow 0.12s ease;
}
.login-form button:hover {
  filter: brightness(1.055);
  transform: translateY(-1px);
  box-shadow:
    0 11px 26px rgba(37, 91, 188, 0.25),
    inset 0 1px 0 rgba(255, 255, 255, 0.2);
}
.login-form button:active { transform: translateY(0); }
.login-form button:focus-visible {
  outline: 2px solid #8cb4ff;
  outline-offset: 3px;
}
.error.login-error {
  margin: -0.65rem 0 1.1rem;
  padding: 0.68rem 0.78rem;
  color: #ffc1b4;
  background: rgba(212, 89, 58, 0.11);
  border: 1px solid rgba(212, 89, 58, 0.34);
  border-radius: 8px;
  font-size: 12px;
}
.login-foot {
  width: 100%;
  max-width: none;
  margin: 0;
  padding: 0.85rem 1.25rem 1.7rem;
  border: 0;
  text-align: center;
}
.login-secure {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  color: #7f8c9a;
  font-size: 11.5px;
  font-weight: 650;
  letter-spacing: 0.045em;
}
.login-lock {
  position: relative;
  width: 11px;
  height: 9px;
  margin-top: 3px;
  border: 1.5px solid #6f8093;
  border-radius: 2px;
}
.login-lock::before {
  content: "";
  position: absolute;
  width: 6px;
  height: 5px;
  left: 1px;
  bottom: 6px;
  border: 1.5px solid #6f8093;
  border-bottom: 0;
  border-radius: 5px 5px 0 0;
}
.error { color: #f48a72; margin: 0 0 0.5rem; }

@media (max-width: 480px) {
  .login-content { padding: 1.25rem 1rem; }
  .login-card {
    padding: 2rem 1.35rem 1.8rem;
    border-radius: 14px;
  }
  .login-brand { margin-bottom: 1.8rem; }
  .login-foot { padding-bottom: 1.25rem; }
}
@media (max-height: 620px) and (min-width: 481px) {
  .login-content { padding-top: 1.25rem; padding-bottom: 1.25rem; }
  .login-card { padding-top: 1.8rem; padding-bottom: 1.75rem; }
  .login-brand { margin-bottom: 1.55rem; }
}
@media (prefers-reduced-motion: reduce) {
  .login-form input,
  .login-form button { transition: none; }
}

/* --- detail header ------------------------------------------------------- */
.detail-header {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 0.65rem 1.5rem;
  background: linear-gradient(180deg, var(--panel), var(--panel-2));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem 1.15rem;
  margin: 0.75rem 0 1rem;
  box-shadow: var(--shadow);
}
.detail-header > div { display: flex; flex-direction: column; gap: 0.25rem; }
.detail-header .lbl { color: var(--muted-2); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; }

/* --- date navigation ----------------------------------------------------- */
.date-nav { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin: 0.5rem 0 1rem; }
.date-nav input[type=date] {
  background: var(--bg-2); border: 1px solid var(--border); color: var(--text);
  border-radius: var(--radius-sm); padding: 0.35rem 0.55rem; color-scheme: dark; font-size: 13px;
}
/* Stage 10.30+: detail-page top row — breadcrumbs (left) + date controls (right) on one
   line above the employee header. Reuses the shared .date-nav partial (comparison page
   unaffected); its margins are zeroed here so the row hugs the top. */
.detail-topbar { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 0.35rem 1.25rem; margin: 0 0 0.75rem; }
.detail-topbar .crumbs { margin: 0; }
.detail-topbar .date-nav { margin: 0; }

/* --- detail full-day timeline -------------------------------------------- */
/* Stage 10.2: premium time-axis labels above the wide detail bar (the old
   «Таймлайн дня» heading + explanatory line were removed). */
.day-timeline { margin: 1.25rem 0 0.6rem; }
.day-tl-axis {
  position: relative; height: 16px; margin-bottom: 1px;
  font-size: 10.5px; color: var(--muted-2);
}
.day-tl-axis .dtl-ax {
  position: absolute; top: 0; transform: translateX(-50%);
  white-space: nowrap; font-variant-numeric: tabular-nums; line-height: 12px;
}
/* Stage 10.3: subtle 1px tick beneath each detail-axis label, pointing down toward
   the (wider) bar so the label-to-position mapping is unambiguous. */
.day-tl-axis .dtl-ax::before {
  content: ""; position: absolute; bottom: -4px; left: 50%; transform: translateX(-50%);
  width: 1px; height: 4px; background: var(--muted-2); opacity: 0.65;
}
.day-tl-axis .dtl-ax.dtl-first { transform: none; }
.day-tl-axis .dtl-ax.dtl-first::before { left: 0; transform: none; }
.day-tl-axis .dtl-ax.dtl-last { transform: translateX(-100%); }
.day-tl-axis .dtl-ax.dtl-last::before { left: 100%; transform: translateX(-100%); }
/* Stage 10.30: the detail time-axis now sits BELOW the bar (operator request, like the
   overview rows). Flip the spacing and point each tick UP toward the timeline above. */
.day-timeline .timeline { margin-bottom: 0; }
.day-tl-axis.is-bottom { margin-bottom: 0; margin-top: 2px; }
.day-tl-axis.is-bottom .dtl-ax::before { bottom: auto; top: -6px; }
.timeline {
  display: flex; width: 100%; height: 30px;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  overflow: hidden; margin: 0 0 0.6rem; background: var(--bg-2);
}
.tl-cell { flex: 1 1 0; min-width: 0; }
.tl-cell + .tl-cell { border-left: 1px solid rgba(0,0,0,0.25); }
.tl-active { background: var(--active); }
.tl-idle { background: var(--idle); }
.tl-afk { background: var(--afk); }
.tl-offline { background: var(--offline); }
.tl-no_data { background: var(--panel-2); }
/* Stage 10.5: neutral "outside working hours" cell — a calm muted hatch, NOT the
   alarming red AFK. Used wherever night/before-shift idleness would have been AFK,
   so it reads as "no work expected here" rather than inflating AFK. */
.tl-off_hours { background: repeating-linear-gradient(45deg, #2a333f, #2a333f 4px, #313b48 4px, #313b48 8px); }
/* Stage 14: the day strips (row + detail) span the whole 00:00–24:00 now, so the
   employee's SHIFT is shown by dimming everything outside it — colour still means
   activity, brightness means "inside the working shift". Works unchanged for a
   night shift, whose window wraps past midnight and so lights up both ends of the
   bar. Applies to .timeline-segment and .tl-cell alike. */
.tl-offshift { opacity: 0.34; filter: grayscale(0.4); }
/* Stage 7.4 meaningful-activity levels (used by both the mini and full timeline). */
.tl-high_activity { background: var(--active); }
.tl-normal_activity { background: var(--online); }
.tl-low_activity { background: var(--idle); }
.tl-legend { display: flex; gap: 1.1rem; flex-wrap: wrap; color: var(--muted); font-size: 12px; margin-bottom: 0.5rem; }
.tl-legend i { display: inline-block; width: 12px; height: 12px; border-radius: 3px; vertical-align: -1px; margin-right: 0.3rem; }
.tl-legend i.tl-active { background: var(--active); }
.tl-legend i.tl-idle { background: var(--idle); }
.tl-legend i.tl-afk { background: var(--afk); }
.tl-legend i.tl-no_data { background: var(--panel-2); border: 1px solid var(--border); }
.tl-legend i.tl-high_activity { background: var(--active); }
.tl-legend i.tl-normal_activity { background: var(--online); }
.tl-legend i.tl-low_activity { background: var(--idle); }
.tl-legend i.tl-offline { background: var(--offline); }
/* Stage 10.25: thin "отходы" strip — in-shift AFK absences >=5 min, drawn above the
   timeline in the same 00:00-24:00 coordinate space (segments positioned by left/%
   width). Pale --afk = 5-15 min; solid --afk = >=15 min (alert-worthy). */
.afk-strip {
  position: relative; width: 100%; height: 9px; margin: 0 0 3px;
  background: var(--bg-2); border: 1px solid var(--border);
  border-radius: var(--radius-sm); overflow: hidden;
}
.afk-seg { position: absolute; top: 0; bottom: 0; min-width: 3px; border-radius: 2px; }
.afk-short { background: rgba(224, 98, 58, 0.45); }   /* 5-15 min — pale --afk */
.afk-long  { background: var(--afk); }                /* >=15 min — solid --afk */
/* Stage 30: in-shift time with the PC off — AFK red, hatched so it reads apart from a walk-away. */
.afk-offline, .tl-legend i.afk-offline {
  background: repeating-linear-gradient(135deg, var(--afk) 0 4px, #8f3518 4px 6px);
}
.afk-strip .afk-seg:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.afk-empty { position: absolute; left: 6px; top: 0; line-height: 9px; font-size: 8.5px; color: var(--muted-2); }
.tl-legend i.afk-short { background: rgba(224, 98, 58, 0.45); }
.tl-legend i.afk-long { background: var(--afk); }
.tl-legend-sep { width: 1px; align-self: stretch; background: var(--border); margin: 0 0.1rem; }

/* Stage 10.30: the DEVICE-DETAIL отходы strip is taller and labels every absence with
   its duration on a staggered "flag" (pole + tag) so the tags never overlap. The
   coloured bars live in a thin track pinned to the BOTTOM; flags rise above it by lane
   (0/1/2). The overview row strip (.mini-afk-strip) is untouched. Compound selector
   (.afk-strip.afk-strip-detail) so it always beats the single-class .afk-strip rules. */
/* Stage 10.40: the strip is exactly as tall as the busiest lane stack needs —
   ``--afk-lanes`` (set per render = max lane used + 1) × an 18px lane step that exceeds
   the tag height, so stacked tags at the same x NEVER overlap vertically, and a quiet
   day with one отход doesn't reserve a tall empty strip. */
.afk-strip.afk-strip-detail {
  height: calc(26px + var(--afk-lanes, 1) * 18px);
  background: transparent; border: 0; border-radius: 0;
  overflow: visible; margin: 0 0 4px;
}
.afk-strip-detail .afk-bar-track {
  position: absolute; left: 0; right: 0; bottom: 0; height: 10px;
  background: var(--bg-2); border: 1px solid var(--border);
  border-radius: var(--radius-sm); overflow: hidden;
}
.afk-flag {
  position: absolute; bottom: 11px; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center;
  pointer-events: none; z-index: 2;
}
/* Stage 10.30+: the minute tag is an interactive (hover/focus) pill that shows the
   SAME time tooltip as the bar segment below it; a slimmer rounded pill + 4 lanes keep
   the tags comfortably apart even on a busy day. */
.afk-flag .afk-tag {
  pointer-events: auto; cursor: pointer;
  font-size: 9.5px; line-height: 1.15; font-weight: 600; font-variant-numeric: tabular-nums;
  padding: 1.5px 5px; border-radius: 999px; white-space: nowrap;
  background: var(--panel-3); border: 1px solid var(--border); color: var(--muted);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.30);
}
.afk-flag .afk-tag:hover, .afk-flag .afk-tag:focus-visible {
  border-color: var(--accent); color: var(--text); outline: none;
}
.afk-flag .afk-tag-long, .afk-flag .afk-tag-offline {
  color: #f0b49d; border-color: rgba(224, 98, 58, 0.55); background: rgba(224, 98, 58, 0.16);
}
.afk-flag .afk-tag-offline { border-style: dashed; }
.afk-flag .afk-pole { width: 1px; height: 4px; background: var(--muted-2); opacity: 0.45; }
.afk-flag[data-lane="1"] .afk-pole { height: 22px; }
.afk-flag[data-lane="2"] .afk-pole { height: 40px; }
.afk-flag[data-lane="3"] .afk-pole { height: 58px; }
.afk-flag[data-lane="4"] .afk-pole { height: 76px; }
.afk-strip-detail .afk-empty { top: auto; bottom: 13px; left: 6px; }

/* --- tables (comparison / detail) ---------------------------------------- */
.table-wrap { overflow-x: auto; border-radius: var(--radius); }
table.grid {
  width: 100%; border-collapse: collapse;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow);
}
table.grid th, table.grid td {
  padding: 0.7rem 0.85rem; border-bottom: 1px solid var(--border-soft);
  text-align: left; vertical-align: middle;
}
table.grid th {
  background: var(--panel-2); font-size: 11px; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--muted); font-weight: 600;
}
table.grid tbody tr:hover { background: rgba(255,255,255,0.02); }
table.grid tr:last-child td { border-bottom: none; }
.cell-strong { font-weight: 600; color: var(--text); }
td.empty { text-align: center; color: var(--muted); padding: 1.75rem; }

/* --- top-app share bars -------------------------------------------------- */
.bar-wrap { display: flex; align-items: center; gap: 0.6rem; min-width: 180px; }
.bar { height: 9px; background: var(--accent); border-radius: 999px; min-width: 2px; max-width: 100%; }
.bar-lbl { color: var(--muted); font-size: 12px; white-space: nowrap; }

/* --- settings ------------------------------------------------------------ */
.settings-section {
  max-width: 720px; margin: 0 0 1.25rem; padding: 1.15rem 1.2rem 1.25rem;
  scroll-margin-top: 4.4rem; border: 1px solid var(--border);
  border-radius: var(--radius); background: linear-gradient(180deg, var(--panel), var(--panel-2));
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.08);
}
.settings-section .section-head {
  margin: -0.1rem -1.2rem 0.8rem; padding: 0 1.2rem 0.8rem;
  border-bottom: 1px solid var(--border-soft);
}
.settings-section .section-head h2 { font-size: 1.05rem; }
.settings-section-lead {
  margin: -0.1rem 0 1rem; color: var(--muted); font-size: 13px; line-height: 1.45;
}
.settings-section > .settings-form:last-child { margin-bottom: 0; }
.settings-section .settings-form { max-width: none; }
/* Stage 26: tabbed settings. One pane at a time; «Группы» is a list + panel. */
.st-tabs {
  display: flex; gap: 0.25rem; margin: 0 0 1.1rem; padding: 0.25rem;
  width: max-content; max-width: 100%; overflow-x: auto;
  background: var(--panel); border: 1px solid var(--border); border-radius: 999px;
}
.st-tab {
  padding: 0.42rem 1rem; border-radius: 999px; color: var(--muted);
  font-size: 13px; font-weight: 600; white-space: nowrap;
}
.st-tab:hover { color: var(--text); text-decoration: none; }
.st-tab.is-active { color: #fff; background: var(--accent); }
.st-pane { max-width: 1040px; }
.st-pane[hidden] { display: none; }
.st-card {
  border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
  background: rgba(0, 0, 0, 0.1); padding: 0.85rem 1rem; margin: 0 0 0.8rem;
}
.st-card h3 { margin: 0 0 0.55rem; font-size: 13px; font-weight: 650; }
.st-card-accent { border-color: rgba(79, 140, 255, 0.45); background: rgba(79, 140, 255, 0.07); }
.st-card-row { display: flex; gap: 0.6rem; align-items: center; flex-wrap: wrap; }
.st-card-row form { margin: 0; }
.st-details > summary, .st-details-inline > summary {
  cursor: pointer; font-weight: 600; font-size: 13px; color: var(--muted);
}
.st-details[open] > summary, .st-details-inline[open] > summary { color: var(--text); margin-bottom: 0.7rem; }
.st-details-inline { margin: 0.2rem 0 0.9rem; }
.st-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 0 0.9rem;
}
.st-actions { display: flex; gap: 0.5rem; margin-top: 0.2rem; }
.st-switch { font-weight: 600; font-size: 14px; }

.grp-layout { display: grid; grid-template-columns: 250px minmax(0, 1fr); gap: 1rem; align-items: start; }
.grp-list { display: flex; flex-direction: column; gap: 0.3rem; }
.grp-item {
  display: flex; flex-direction: column; gap: 0.1rem; padding: 0.55rem 0.75rem;
  border: 1px solid transparent; border-radius: var(--radius-sm); color: var(--text);
}
.grp-item:hover { background: var(--panel-3); text-decoration: none; }
.grp-item.is-active { background: var(--accent-soft); border-color: rgba(79, 140, 255, 0.5); }
.grp-item.is-default { margin-bottom: 0.35rem; border-bottom-color: var(--border-soft); }
.grp-item-name { font-weight: 650; font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.grp-item-meta { color: var(--muted); font-size: 12px; }
.grp-create { display: flex; gap: 0.35rem; margin-top: 0.45rem; }
.grp-create input { flex: 1; min-width: 0; }
.grp-panel[hidden] { display: none; }
.grp-panel-head { display: flex; align-items: baseline; gap: 0.7rem; flex-wrap: wrap; margin: 0.1rem 0 0.8rem; }
.grp-panel-head h2 { margin: 0; font-size: 1.15rem; }
.free-row { display: flex; align-items: center; gap: 0.5rem; }
.free-row input { width: 110px; font-size: 1.05rem; font-weight: 650; }
.free-unit { color: var(--muted); }
.free-hint { margin: 0.5rem 0 0; color: var(--muted); font-size: 12px; line-height: 1.45; }
.grp-members { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.grp-member {
  padding: 0.2rem 0.6rem; border-radius: 999px; font-size: 12.5px;
  background: var(--panel-3); border: 1px solid var(--border); color: var(--text);
}
.grp-member:hover { border-color: var(--accent); text-decoration: none; }

.tg-layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 360px); gap: 1.1rem; align-items: start; }
.tg-preview {
  margin: 0; padding: 0.7rem 0.85rem; white-space: pre-wrap; font: inherit; font-size: 13px;
  line-height: 1.5; background: #1f2c3a; border-radius: 10px 10px 10px 2px; color: var(--text);
}
.tg-preview-buttons { display: grid; grid-template-columns: 1fr 1fr; gap: 0.3rem; margin-top: 0.3rem; }
.tg-preview-buttons span {
  text-align: center; font-size: 12px; padding: 0.35rem; border-radius: 6px;
  background: rgba(79, 140, 255, 0.14); color: #9cc0ff;
}
.tg-preview-buttons span:only-child { grid-column: 1 / -1; }

.group-rename-form { display: flex; gap: 0.4rem; align-items: center; flex: 1; min-width: 220px; }
.group-rename-form input { flex: 1; }

.settings-form { max-width: 680px; }
.settings-form fieldset {
  border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
  margin: 0 0 1.1rem; padding: 1rem 1.1rem;
  background: rgba(0, 0, 0, 0.08);
}
.settings-form legend { padding: 0 0.5rem; color: var(--text); font-weight: 600; }
.settings-form label { display: flex; flex-direction: column; gap: 0.3rem; margin-bottom: 0.95rem; font-size: 13px; }
.settings-form small { color: var(--muted); font-size: 12px; }
.settings-form label.check { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 0.45rem; }
.settings-form label.check small { flex-basis: 100%; }
.ok-msg {
  color: #6fe0a6; background: rgba(46,163,107,0.12);
  border: 1px solid rgba(46,163,107,0.4); border-radius: var(--radius-sm);
  padding: 0.6rem 0.9rem; margin: 0 0 1rem;
}
.error-box {
  background: rgba(212,89,58,0.12); border: 1px solid var(--danger);
  border-radius: var(--radius-sm); padding: 0.75rem 1rem; margin-bottom: 1rem;
}
.error-box ul { margin: 0.5rem 0 0; }
form[data-action-busy="1"] { opacity: 0.72; pointer-events: none; }
.action-toast {
  position: fixed; right: 1rem; bottom: 1rem; z-index: 100;
  width: max-content; max-width: min(420px, calc(100vw - 2rem));
  padding: 0.72rem 0.95rem;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: rgba(22, 28, 37, 0.97); color: var(--text);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.38);
  opacity: 0; transform: translateY(0.5rem);
  pointer-events: none;
  transition: opacity 0.14s ease, transform 0.14s ease;
}
.action-toast.is-visible { opacity: 1; transform: translateY(0); }
.action-toast.is-ok { border-color: rgba(46, 163, 107, 0.72); }
.action-toast.is-error { border-color: var(--danger); }
.status-list { list-style: none; margin: 0; padding: 0; }
.status-list li { margin-bottom: 0.4rem; }

/* --- Stage 10: groups, filter bar, compact summary, secondary notes ------- */
/* muted note under the ribbon for hidden/blocked counts */
.ribbon-note { margin: -0.25rem 0 1rem; font-size: 12px; }

/* group filter bar (overview + devices) */
.group-filter {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem;
  margin: 0 0 1rem;
}
.group-filter .gf-label {
  color: var(--muted-2); font-size: 10.5px; text-transform: uppercase;
  letter-spacing: 0.04em; margin-right: 0.15rem;
}
.gf-pill {
  display: inline-flex; align-items: center;
  padding: 0.28rem 0.72rem; border-radius: 999px;
  border: 1px solid var(--border); background: var(--panel-2);
  color: var(--muted); font-size: 12px; font-weight: 500;
  transition: color 0.12s, background 0.12s, border-color 0.12s;
}
.gf-pill:hover { color: var(--text); border-color: #3a4d61; text-decoration: none; }
.gf-pill.is-active { color: #fff; background: var(--accent); border-color: var(--accent); }
/* «Без группы» pill carries a full label (desktop) + a short «без» (phones); the
   mobile media query swaps which one shows. */
.gf-short { display: none; }

/* Stage 10.4: list toolbar — group filter (left) + day pager (right) on one bar.
   The toolbar carries the bottom margin so the group filter sits flush inside it. */
.list-toolbar {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 0.5rem 1rem; margin: 0 0 1rem;
}
.list-toolbar .group-filter { margin: 0; }
.list-tools-main { display: flex; flex-wrap: wrap; align-items: center; gap: 0.45rem; }
.order-control { position: relative; }
.order-control > summary { list-style: none; user-select: none; }
.order-control > summary::-webkit-details-marker { display: none; }
.order-control[open] > summary { outline: 1px solid var(--accent); color: var(--accent); }
.order-panel {
  position: absolute; left: 0; z-index: 7; margin-top: 0.35rem;
  width: min(380px, calc(100vw - 2rem)); max-height: min(70vh, 620px);
  overflow: auto; background: var(--panel-3); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 0.7rem; box-shadow: var(--shadow);
}
/* Stage 10.39: a CLOSED reorder panel must never render. Some engines keep its
   position:fixed content laid out on phones (closed-<details> hiding doesn't apply to
   the fixed child), so its rows pushed a document-level sideways scroll — the «Порядок»
   panel «выпирало» past the viewport. Force-hide it whenever the details is closed. */
.order-control:not([open]) > .order-panel { display: none; }
.order-title {
  color: var(--muted); font-size: 11px; font-weight: 650;
  text-transform: uppercase; letter-spacing: 0.04em; margin: 0 0 0.45rem;
}
.order-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.3rem; }
.order-row {
  display: grid; grid-template-columns: auto minmax(0, 1fr) 58px;
  align-items: center; gap: 0.45rem; padding: 0.35rem 0.45rem;
  background: var(--panel-2); border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
}
.order-row.is-dragging { opacity: 0.55; border-color: var(--accent); }
.order-handle {
  color: var(--muted-2); cursor: grab; font-family: "JetBrains Mono", Consolas, Menlo, monospace;
  letter-spacing: -0.12em; padding: 0 0.15rem;
}
.order-person { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 0.35rem 0.5rem; min-width: 0; }
.order-avatar { grid-row: span 2; display: inline-flex; border-radius: 999px; }
.order-avatar .ident-badge { width: 24px; height: 24px; font-size: 11px; }
.order-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 650; }
.order-meta { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11px; }
.order-pos { width: 58px; padding: 0.3rem 0.4rem; text-align: center; font-variant-numeric: tabular-nums; }
.order-actions { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.55rem; }
.order-hint { font-size: 11px; }
.order-empty { padding: 0.5rem; }
.list-search { display: flex; align-items: center; gap: 0.35rem; flex-wrap: wrap; margin: 0; }
.list-search input[type=text] { width: 180px; padding: 0.35rem 0.55rem; }
.day-pager {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem;
  margin-left: auto;
}
.day-pager .dp-label {
  color: var(--muted-2); font-size: 10.5px; text-transform: uppercase;
  letter-spacing: 0.04em; margin-right: 0.15rem;
}
.dp-pill {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 2.5rem; padding: 0.28rem 0.6rem; border-radius: 999px;
  border: 1px solid var(--border); background: var(--panel-2);
  color: var(--muted); font-size: 12px; font-weight: 500;
  font-variant-numeric: tabular-nums;
  transition: color 0.12s, background 0.12s, border-color 0.12s;
}
.dp-pill:hover { color: var(--text); border-color: #3a4d61; text-decoration: none; }
.dp-pill.is-active { color: #fff; background: var(--accent); border-color: var(--accent); }
/* the «Сегодня» pill keeps a faint accent outline even when a past day is selected,
   so "now" is always easy to jump back to. */
.dp-pill.is-today:not(.is-active) { border-color: var(--accent); color: var(--text); }
/* Stage 21: «Сейчас» is the live view (each employee's own current shift), so it is
   set apart from the date pills that pin one shift. */
.dp-live { font-weight: 650; }
.dp-live:not(.is-active) { border-color: #3a4d61; color: var(--text); }

/* Stage 22: the «Смена | Сутки» switch replaces the static «СМЕНА» label — the label
   already stated the period, so turning it into the control is the shortest path from
   "I see the mode" to "I can change it". A segmented control (one outline, a filled
   active half) reads as one either/or choice, unlike two separate pills that would
   look like the date filters next to them. */
.dp-mode {
  display: inline-flex; align-items: stretch;
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--panel-2); padding: 2px; margin-right: 0.15rem;
}
.dp-mode-btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0.16rem 0.6rem; border-radius: 999px;
  font-size: 11.5px; font-weight: 600; color: var(--muted-2);
  transition: color 0.12s, background 0.12s;
}
.dp-mode-btn:hover { color: var(--text); text-decoration: none; }
.dp-mode-btn.is-active {
  color: #fff; background: var(--accent);
  box-shadow: 0 1px 4px rgba(0,0,0,0.28);
}
.dp-arrow {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.7rem; height: 1.7rem; border-radius: 999px;
  border: 1px solid var(--border); background: var(--panel-2);
  color: var(--muted); font-size: 15px; line-height: 1; text-decoration: none;
  transition: color 0.12s, border-color 0.12s;
}
.dp-arrow:hover { color: var(--text); border-color: #3a4d61; text-decoration: none; }
.dp-arrow.is-disabled { opacity: 0.35; pointer-events: none; cursor: default; }
/* small muted day suffix on the «Сотрудники» heading for a past day */
.section-head .sh-note { font-size: 0.62em; font-weight: 500; }

/* group badge on cards / detail header */
.badge.group-badge {
  background: var(--accent-soft); color: #9cc0ff;
  border: 1px solid rgba(79,140,255,0.35);
}

/* inline group assign/create control (mirrors the working-hours disclosure) */
.dc-group { position: relative; }
.dc-group summary { list-style: none; user-select: none; }
.dc-group summary::-webkit-details-marker { display: none; }
.dc-group[open] summary { outline: 1px solid var(--accent); color: var(--accent); }
.dc-group-panel {
  position: absolute; right: 0; z-index: 6;
  background: var(--panel-3); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 0.75rem; box-shadow: var(--shadow);
  min-width: 250px; margin-top: 0.3rem;
}
.dc-group-panel .wh-title {
  font-size: 11.5px; font-weight: 600; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 0.5rem;
}
.dc-group-panel form {
  display: flex; gap: 0.35rem; align-items: center; margin: 0 0 0.45rem; flex-wrap: wrap;
}
.dc-group-panel form:last-child { margin-bottom: 0; }
.dc-group-panel select,
.dc-group-panel input[type=text] { flex: 1 1 120px; min-width: 0; }
.dc-group-panel select {
  background: var(--bg-2); border: 1px solid var(--border); color: var(--text);
  border-radius: var(--radius-sm); padding: 0.4rem 0.5rem; font-size: 13px; color-scheme: dark;
}

/* compact, logically grouped device-detail summary */
.summary-group { margin: 0 0 0.7rem; }
.summary-group .grp-label {
  color: var(--muted-2); font-size: 10.5px; text-transform: uppercase;
  letter-spacing: 0.04em; margin: 0 0 0.35rem;
}
.cards.compact {
  grid-template-columns: repeat(auto-fill, minmax(94px, 1fr));
  gap: 0.5rem; margin: 0;
}
.cards.compact .card { padding: 0.55rem 0.6rem; }
.cards.compact .num { font-size: 1.15rem; }
.cards.compact .lbl { font-size: 10px; margin-top: 0.15rem; }
.cards.compact .card.weak { opacity: 0.82; }
.cards.compact .card.weak .num { color: var(--muted); }

/* "Технические события" disclosure on the detail page */
.tech-events { margin: 1.5rem 0 0.5rem; }
.tech-events > summary {
  cursor: pointer; user-select: none; color: var(--muted);
  font-size: 13px; padding: 0.4rem 0; font-weight: 600;
}
.tech-events[open] > summary { color: var(--text); }

/* --- Stage 10.1: premium identity chips + stable palette ------------------ */
.ident-chip {
  display: inline-flex; align-items: center; gap: 0.55rem;
  padding: 0.3rem 0.65rem 0.3rem 0.3rem; border-radius: 999px;
  border: 1px solid var(--border); background: var(--panel-2);
  color: var(--text); max-width: 100%; vertical-align: middle;
  transition: border-color 0.12s, background 0.12s;
}
.ident-chip:hover { text-decoration: none; border-color: #3a4d61; }
.ident-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 50%;
  font-weight: 700; font-size: 12px; color: #fff; flex: 0 0 auto;
}
/* Stage 10.2: the chip wraps ONLY the avatar + name (host/user live outside it). */
.ident-name { font-weight: 650; font-size: 0.95rem; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ident-chip-sm { padding: 0.2rem 0.6rem 0.2rem 0.25rem; }
.ident-chip-sm .ident-badge { width: 22px; height: 22px; font-size: 11px; }
.ident-chip-sm .ident-name { font-size: 0.9rem; }
.ident-chip-lg { padding: 0.4rem 0.95rem 0.4rem 0.4rem; }
.ident-chip-lg .ident-badge { width: 42px; height: 42px; font-size: 17px; }
.ident-chip-lg .ident-name { font-size: 1.3rem; letter-spacing: -0.01em; }
/* identity wrappers: chip on top, plain muted host/user line beneath (no chip bg) */
/* Stage 10.3: align-items:flex-start so the inline-flex chip hugs the avatar+name
   instead of being stretched to the column width (= the wider host/user line). */
/* Stage 10.25: name + host on ONE row (host to the RIGHT of the chip) to save
   vertical space; host wraps under the chip only when the row is too narrow. */
.dc-identity { display: flex; flex-direction: row; align-items: center; flex-wrap: wrap; gap: 0.15rem 0.55rem; min-width: 0; }
.dc-identity .dc-sub { margin-top: 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.detail-id-main { display: flex; flex-direction: column; align-items: flex-start; gap: 0.3rem; min-width: 0; }
.detail-id-main .dc-sub { font-size: 12px; }

/* eight restrained, deterministic tones (chip tint + badge fill) */
.pal-0 { background: rgba(79,140,255,0.12); border-color: rgba(79,140,255,0.30); }
.pal-0 .ident-badge { background: #3f6fd1; }
.pal-1 { background: rgba(120,140,170,0.13); border-color: rgba(120,140,170,0.30); }
.pal-1 .ident-badge { background: #5a6b85; }
.pal-2 { background: rgba(140,110,224,0.13); border-color: rgba(140,110,224,0.30); }
.pal-2 .ident-badge { background: #7a5fd0; }
.pal-3 { background: rgba(47,158,143,0.13); border-color: rgba(47,158,143,0.30); }
.pal-3 .ident-badge { background: #2f9e8f; }
.pal-4 { background: rgba(211,154,42,0.13); border-color: rgba(211,154,42,0.30); }
.pal-4 .ident-badge { background: #b9842c; }
.pal-5 { background: rgba(200,100,130,0.13); border-color: rgba(200,100,130,0.30); }
.pal-5 .ident-badge { background: #c25f7a; }
.pal-6 { background: rgba(70,160,200,0.13); border-color: rgba(70,160,200,0.30); }
.pal-6 .ident-badge { background: #3a91b8; }
.pal-7 { background: rgba(60,160,100,0.13); border-color: rgba(60,160,100,0.30); }
.pal-7 .ident-badge { background: #3f9e63; }

/* muted zero values across cards / summary / comparison */
.metric-zero, .metric-zero b { color: var(--muted-2) !important; opacity: 0.72; font-weight: 500 !important; }

/* --- Stage 10.1: device-detail identity header --------------------------- */
.detail-id {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.8rem 1.5rem; flex-wrap: wrap;
  background: linear-gradient(180deg, var(--panel), var(--panel-2));
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 0.85rem 1.15rem; margin: 0.5rem 0 1rem; box-shadow: var(--shadow);
}
.detail-meta { display: flex; gap: 0.5rem 1.6rem; flex-wrap: wrap; align-items: flex-start; }
.dm-item { display: flex; flex-direction: column; gap: 0.2rem; }
.dm-item .lbl { color: var(--muted-2); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; }
.dm-val { font-size: 13px; }

/* --- Stage 10.1: compact activity summary (stacked bar) ------------------ */
.summary-panel {
  background: linear-gradient(180deg, var(--panel), var(--panel-2));
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 0.8rem 1rem; margin: 0 0 0.7rem; box-shadow: var(--shadow);
}
.summary-panel .grp-label { color: var(--muted-2); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; margin: 0 0 0.5rem; }
.stack-bar { display: flex; width: 100%; height: 22px; border-radius: 6px; overflow: hidden; background: var(--bg-2); border: 1px solid var(--border); }
.stack-bar.is-empty { opacity: 0.5; }
.stack-seg { height: 100%; }
.stack-seg + .stack-seg { border-left: 1px solid rgba(0,0,0,0.25); }
.seg-high { background: var(--active); }
.seg-normal { background: var(--online); }
.seg-low { background: var(--idle); }
.seg-afk { background: var(--afk); }
.stack-legend { display: flex; flex-wrap: wrap; gap: 0.35rem 1.1rem; margin: 0.6rem 0 0; font-size: 12px; }
.sl-item { display: inline-flex; align-items: center; gap: 0.35rem; color: var(--text); }
.sl-item b { font-weight: 650; }
.seg-dot { width: 9px; height: 9px; border-radius: 2px; display: inline-block; }
.seg-dot.seg-high { background: var(--active); }
.seg-dot.seg-normal { background: var(--online); }
.seg-dot.seg-low { background: var(--idle); }
.seg-dot.seg-afk { background: var(--afk); }
.summary-keys { display: flex; flex-wrap: wrap; gap: 0.4rem 1.5rem; margin: 0.7rem 0 0; padding-top: 0.6rem; border-top: 1px solid var(--border-soft); }
.sk-item { display: inline-flex; align-items: baseline; gap: 0.4rem; font-size: 12.5px; }
.sk-item .sk-lbl { color: var(--muted); }
.sk-item b { font-weight: 700; font-size: 0.95rem; }
.input-row { display: flex; flex-wrap: wrap; gap: 0.5rem 1.6rem; }
.ir-item { display: inline-flex; align-items: baseline; gap: 0.4rem; font-size: 12.5px; }
.ir-item .ir-lbl { color: var(--muted); }
.ir-item b { font-weight: 700; font-size: 0.95rem; color: var(--text); }
.ir-weak .ir-lbl, .ir-weak b { color: var(--muted-2); }

/* --- Stage 10.30: weekly отходы/проёбы block (device detail) ----------------- */
/* Mon..Sun column chart: bars = active (working) time per day, counts of отходы
   (5–15 min) / проёбы (15+ min) below each, week totals in the head. Today is
   accent-highlighted, future days muted. Compact + responsive (7 cols fit a phone). */
.week-head { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 0.3rem 1rem; margin: 0 0 0.7rem; }
.week-head .grp-label { margin: 0; }
.week-totals { display: inline-flex; gap: 1rem; font-size: 12.5px; }
.wt-item { display: inline-flex; align-items: center; gap: 0.35rem; color: var(--muted); }
.wt-item i { width: 9px; height: 9px; border-radius: 2px; display: inline-block; }
.wt-item b { color: var(--text); font-weight: 700; font-size: 0.95rem; }
.week-chart { display: flex; gap: 0.4rem; align-items: stretch; }
.week-day {
  flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center;
  gap: 0.15rem; padding: 0.4rem 0.15rem 0.35rem; border-radius: var(--radius-sm);
  border: 1px solid transparent; text-decoration: none; color: inherit;
  transition: background 0.12s, border-color 0.12s;
}
/* Stage 10.30+: a day is a clickable link to that day's page. */
a.week-day { cursor: pointer; }
a.week-day:hover { background: var(--panel-3); border-color: var(--border); text-decoration: none; }
/* Stage 10.31: the STRONG highlight follows the day on screen (is-selected), not
   always «сегодня». Today keeps a subtle accent name + a thin outline so "now" is
   still easy to spot when you are looking at a different day. */
.week-day.is-selected { background: var(--accent-soft); border-color: rgba(79, 140, 255, 0.55); }
a.week-day.is-selected:hover { border-color: var(--accent); }
.week-day.is-today:not(.is-selected) { border-color: rgba(79, 140, 255, 0.35); }
.week-day.is-future { opacity: 0.45; }
.wd-bar-area {
  width: 100%; height: 60px; display: flex; align-items: flex-end; justify-content: center;
  background: var(--bg-2); border: 1px solid var(--border-soft); border-radius: 5px;
}
.wd-bar { width: 56%; max-width: 22px; min-height: 2px; border-radius: 3px 3px 0 0;
  background: linear-gradient(180deg, var(--active), #1f7a50); }
.wd-name { font-size: 12px; font-weight: 600; color: var(--text); }
.week-day.is-today .wd-name { color: var(--accent); }
.wd-date { font-size: 10.5px; color: var(--muted-2); font-variant-numeric: tabular-nums; }
/* Stage 10.30+: labelled per-day counts (отходы / проёбы), two stacked lines. */
.wd-counts { display: flex; flex-direction: column; gap: 1px; margin-top: 0.15rem; font-variant-numeric: tabular-nums; }
.wd-c-line { display: inline-flex; align-items: baseline; gap: 0.3rem; }
.wd-c-lbl { color: var(--muted-2); font-size: 10px; }
.wd-c-short { color: #e0a06a; font-weight: 700; font-size: 12.5px; }   /* отходы 5–15 мин */
.wd-c-long { color: var(--afk); font-weight: 700; font-size: 12.5px; } /* проёбы 15+ мин */
.wd-future { color: var(--muted-2); }
/* Stage 10.30+: week's total AFK time under the chart. */
.week-foot { margin-top: 0.7rem; padding-top: 0.6rem; border-top: 1px solid var(--border-soft);
  display: flex; align-items: baseline; gap: 0.4rem; font-size: 12.5px; }
.week-foot b { font-weight: 700; font-size: 0.95rem; }

/* --- Stage 10.31: sortable comparison headers + Отходы/Проёбы columns -------- */
/* Each header is a link; the active column is accented and shows a ↑/↓ arrow. The
   header text stays plain (substring checks unaffected). */
.comp-grid th.col-sort { padding: 0; }
.comp-grid th.col-sort .sort-link {
  display: flex; align-items: center; gap: 0.3rem;
  padding: 0.7rem 0.85rem; color: inherit; font: inherit;
  text-transform: inherit; letter-spacing: inherit; white-space: nowrap;
}
.comp-grid th.col-sort .sort-link:hover { color: var(--text); text-decoration: none; background: rgba(255,255,255,0.03); }
.comp-grid th.col-sort.is-sorted { color: var(--text); }
.comp-grid th.col-sort.is-sorted .sort-link { color: var(--accent); }
.sort-ind { font-size: 10px; line-height: 1; }
/* Stage 10.36: live-status dot that rides ahead of the name on phones (hidden on
   desktop, where the «Текущий статус» column carries the badge). */
.comp-row-dot { display: none; }
/* Отходы (5–15 мин) / Проёбы (15+ мин) counts reuse the week-chart colour code. */
.comp-grid td.comp-short { color: #e0a06a; font-weight: 650; font-variant-numeric: tabular-nums; }
.comp-grid td.comp-long { color: var(--afk); font-weight: 650; font-variant-numeric: tabular-nums; }
.comp-grid td.comp-short.metric-zero, .comp-grid td.comp-long.metric-zero { color: var(--muted-2) !important; font-weight: 500; }
/* Stage 21: every row can describe a DIFFERENT shift window (a night worker beside a
   day worker), so the period is named under the employee name. */
.comp-shift { display: block; font-size: 10.5px; font-variant-numeric: tabular-nums; margin-top: 0.15rem; }
/* Stage 22: the detail header's period chip carries the hours as a second, quieter
   segment so the date stays the thing the eye lands on. */
.dd-day .dd-hours {
  margin-left: 0.4rem; padding-left: 0.4rem;
  border-left: 1px solid rgba(79,140,255,0.3);
  font-weight: 500; color: #cfe0ff; font-variant-numeric: tabular-nums;
}

/* device-detail: viewed-day word + that day's Отходы/Проёбы/Всего АФК beside the name */
.detail-day { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem 0.8rem; margin-top: 0.15rem; }
.dd-day {
  display: inline-flex; align-items: center; padding: 0.12rem 0.6rem; border-radius: 999px;
  background: var(--accent-soft); color: #9cc0ff; border: 1px solid rgba(79,140,255,0.35);
  font-size: 12px; font-weight: 650;
}
.dd-stat { display: inline-flex; align-items: baseline; gap: 0.3rem; font-size: 12.5px; font-variant-numeric: tabular-nums; }
.dd-stat .dd-lbl { color: var(--muted); font-size: 11px; }
.dd-stat b { font-weight: 700; font-size: 0.95rem; color: var(--text); }
.dd-stat.dd-short b { color: #e0a06a; }
.dd-stat.dd-long b { color: var(--afk); }
.dd-stat.metric-zero b, .dd-stat.metric-zero .dd-lbl { color: var(--muted-2) !important; font-weight: 500; }

/* Share-bar pill — used by the «Активность %» column on /comparison. (The Stage 10.5
   app-time table that introduced these was removed in Stage 10.37; the share-bar
   styling is kept because /comparison still reuses it.) */
.app-share {
  display: inline-block; vertical-align: middle; width: 70px; height: 8px;
  background: var(--bg-2); border-radius: 999px; overflow: hidden; margin-right: 0.4rem;
}
.app-share-bar { display: block; height: 100%; background: var(--accent); border-radius: 999px; min-width: 2px; }
.app-share-pct { font-size: 12px; font-variant-numeric: tabular-nums; }

/* --- Stage 10.5: immediate custom tooltip (desktop hover/focus + touch tap) - */
/* Activity-bar cells advertise their interactivity and get a roomy touch target.
   `touch-action: manipulation` removes the 300ms tap delay on mobile. */
[data-ws-tooltip] { cursor: pointer; touch-action: manipulation; }
.tl-cell[data-ws-tooltip]:focus-visible,
.timeline-segment[data-ws-tooltip]:focus-visible {
  outline: 2px solid var(--accent); outline-offset: -1px;
}
.ws-tooltip {
  position: fixed; left: 0; top: 0; z-index: 1000;
  pointer-events: none; max-width: 260px;
  background: linear-gradient(180deg, var(--panel-3), var(--panel-2));
  color: var(--text); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 0.4rem 0.6rem;
  font-size: 12px; line-height: 1.45; box-shadow: var(--shadow);
  opacity: 0; transform: translateY(3px); transition: opacity 0.08s ease;
}
.ws-tooltip.is-visible { opacity: 1; transform: none; }
.ws-tooltip .tt-title { font-weight: 650; margin-bottom: 0.15rem; color: var(--text); white-space: nowrap; }
.ws-tooltip .tt-line { color: var(--muted); font-variant-numeric: tabular-nums; }

/* --- responsive ---------------------------------------------------------- */
@media (max-width: 640px) {
  .action-toast {
    left: 0.6rem; right: 0.6rem; bottom: 0.6rem;
    width: auto; max-width: none;
  }

  /* Topbar: a tidy second row of horizontally-scrollable nav tabs; the live/admin
     cluster stays compact and never collides with the brand. */
  .topbar { gap: 0.4rem 0.75rem; padding: 0.55rem 0.9rem; flex-wrap: wrap; }
  .topbar nav {
    order: 3; flex-basis: 100%; gap: 0.25rem;
    overflow-x: auto; -webkit-overflow-scrolling: touch;
    flex-wrap: nowrap; scrollbar-width: none;
  }
  .topbar nav::-webkit-scrollbar { display: none; }
  .topbar nav a { white-space: nowrap; padding: 0.35rem 0.6rem; }
  .topbar-right { gap: 0.5rem; margin-left: auto; }
  .topbar-status { font-size: 11px; }
  .topbar-status .live-label, .topbar-status .live-auto { display: none; }
  .topbar .who { display: none; }
  /* Stage 10.39: tighter side padding on phones → wider cards + wider, easier-to-tap
     activity bars (the operator reported the bars were too narrow to hit). */
  .content { padding: 0.85rem 0.6rem; }
  .settings-section { padding: 0.95rem 0.85rem 1rem; margin-bottom: 0.85rem; }
  .settings-section .section-head {
    margin: -0.05rem -0.85rem 0.7rem; padding: 0 0.85rem 0.7rem;
  }

  /* Stat ribbon: compact 3-up grid instead of a ragged wrap. */
  .stat-ribbon { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.4rem; }
  .stat-chip { min-width: 0; padding: 0.3rem 0.45rem; }
  .stat-chip .sc-num { font-size: 1.1rem; }
  .stat-chip .sc-lbl { font-size: 9.5px; }

  /* Filters + day pager. The single-row scroll containers NEED min-width:0 — without
     it their flex content (the pills) refuses to shrink and pushes a DOCUMENT-level
     sideways scroll (the whole page drifts left/right, not just the row). With
     min-width:0 the overflow-x scroll is contained inside the row and the page itself
     never scrolls sideways. */
  .list-toolbar { flex-direction: column; align-items: stretch; gap: 0.4rem; margin-bottom: 0.7rem; }
  /* Stage 10.39: the two scroll rows need max-width:100% (like .group-filter/.day-pager
     since 10.36) — without it the column-flex item refuses to clamp to the toolbar width,
     so its nowrap content (the «Найти»/«Порядок» edge) pushed a document sideways scroll. */
  .list-tools-main { min-width: 0; max-width: 100%; flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  .list-tools-main::-webkit-scrollbar { display: none; }
  .group-filter, .day-pager {
    min-width: 0; max-width: 100%;
    flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch;
    margin: 0; scrollbar-width: none;
  }
  .group-filter::-webkit-scrollbar, .day-pager::-webkit-scrollbar { display: none; }
  .day-pager { margin-left: 0; }
  .order-control { flex: 0 0 auto; }
  .order-panel { position: fixed; left: 0.75rem; right: 0.75rem; width: auto; max-height: 72vh; }
  .order-row { grid-template-columns: auto minmax(0, 1fr) 52px; }
  .list-search { min-width: 0; max-width: 100%; flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .list-search input[type=text] { width: 100%; min-width: 140px; }

  /* Stage 10.36 polish — compact pills + a shorter, symmetric header on phones.
     Smaller pills/labels fit more per row and shave the header height. */
  .gf-pill, .dp-pill { padding: 0.2rem 0.45rem; font-size: 11px; }
  .dp-pill { min-width: 2rem; }
  .dp-arrow { width: 1.45rem; height: 1.45rem; font-size: 14px; }
  .group-filter .gf-label, .day-pager .dp-label { font-size: 9px; }
  /* The mode switch is the one control that must never be squeezed out: it decides
     what every number on the page means. */
  .dp-mode-btn { padding: 0.14rem 0.42rem; font-size: 10.5px; }
  /* Stage 31: the caption is now the period's state («идёт» / «завершена»), so it
     stays on a phone too — only tighter. */
  .dc-period .dcp-lbl { font-size: 9px; }
  .dc-period .dcp-val, .dc-period .dcp-prog { font-size: 10.5px; }
  .dc-period { padding: 0.1rem 0.4rem; gap: 0.25rem; }

  /* On /comparison the toolbar holds ONLY the group filter + day pager (no reorder /
     search), so let them WRAP instead of scroll: every chip stays visible, nothing is
     chopped at the edge, and the header reads symmetrically. Scoped to .comp-toolbar
     so the overview toolbar (filter + reorder + search) keeps its one scrollable row. */
  .comp-toolbar .group-filter, .comp-toolbar .day-pager {
    flex-wrap: wrap; overflow-x: visible; gap: 0.3rem;
  }
  /* Hairline between the stacked group filter and day pager so the two rows read as
     distinct blocks instead of blending together (operator request). Phones only —
     on desktop they sit side-by-side on one row. */
  .comp-toolbar .day-pager { border-top: 1px solid var(--border); padding-top: 0.5rem; }

  /* Trim what wraps one item onto its own row (operator: «чтобы 2 лишние строки,
     которые рендерятся ради 1 слова, исчезли»). 1) «Без группы» → «без» so the group
     filter fits one line. 2) Drop the two OLDEST numeric day pills + the non-functional
     (disabled, most-recent-week) «›» arrow so the day pager (recent dates + Вчера/
     Сегодня) fits one line (comparison only — overview scrolls). */
  .gf-full { display: none; }
  .gf-short { display: inline; }
  /* Stage 21/22: drop the two OLDEST date pills so the row fits one line. The server
     marks them `.dp-minor`; the old positional :nth-of-type rule silently targeted a
     different pill every time the row's markup changed (the mode switch and the
     conditional live pill both shift the offsets), and it could hide the live view. */
  .comp-toolbar .day-pager .dp-minor { display: none; }
  .comp-toolbar .day-pager .dp-arrow.is-disabled { display: none; }

  /* Compact status legend (the per-row dots/word chips decode against it). «Ожидает»
     never applies on /comparison (approved devices only) and is the item that wrapped
     onto its own row — drop it on phones so the legend fits one line. */
  .legend { gap: 0.3rem 0.7rem; font-size: 11px; margin-bottom: 0.7rem; }
  .legend .dot { width: 8px; height: 8px; }
  .comparison-legend .legend-pending { display: none; }

  /* Action disclosures stay inside the phone viewport instead of inheriting the
     right edge of a narrow button. Inputs/buttons remain usable at 320px. */
  .dc-rename .rename,
  .dc-wh-panel,
  .dc-group-panel,
  .dc-danger-panel,
  .popover-panel {
    position: fixed; left: 0.6rem; right: 0.6rem; top: 0.6rem; bottom: auto;
    width: auto; min-width: 0; max-width: none;
    max-height: calc(100dvh - 1.2rem); overflow-y: auto;
    box-sizing: border-box;
    /* Above the sticky topbar (z-index 10): as a top-anchored sheet these panels
       used to open with their first field hidden behind the header. */
    z-index: 20;
  }
  .dc-rename .rename input,
  .wh-form input[type=time],
  .wh-form input[type=text],
  .dc-group-panel select,
  .dc-group-panel input[type=text],
  .popover-panel input,
  .popover-panel select {
    width: 100%; min-width: 0; flex-basis: 100%;
  }
  .dc-rename .rename,
  .wh-form .wh-row,
  .dc-group-panel form,
  .popover-panel form {
    align-items: stretch; flex-direction: column;
  }
  .dc-rename .rename .btn,
  .wh-form .wh-actions .btn,
  .dc-group-panel .btn,
  .dc-danger-panel .btn,
  .popover-panel .btn { min-height: 40px; }
  /* Stage 20: preset chips stay chips (not full-width rows) but get a tappable
     height; the scoped selector beats the generic column rule above. */
  .wh-presets .wh-preset-list form { flex-direction: row; align-items: center; }
  .wh-preset-chip { min-height: 34px; padding: 0.16rem 0.7rem; }

  .device-card, .pending-card-main, .pending-onboarding-actions { min-width: 0; max-width: 100%; }
  .pending-card-main { align-items: flex-start; flex-wrap: wrap; }
  .pending-identity { flex: 1 1 180px; }
  .pending-meta { flex-direction: column; align-items: flex-start; gap: 0.15rem; }
  .pending-onboarding-actions { align-items: stretch; }
  .pending-onboarding-actions > form,
  .pending-onboarding-actions > form > .btn { flex: 1 1 100%; width: 100%; }
  .pending-onboarding-actions summary { min-height: 40px; display: inline-flex; align-items: center; }

  .group-rename-form { width: 100%; min-width: 0; align-items: stretch; flex-direction: column; }
  .group-rename-form input, .group-rename-form .btn,
  .group-delete-form, .group-delete-form .btn { width: 100%; }

  /* Stage 10.39: compact mobile card. Host + «Последняя связь» are hidden (the
     nickname + status chips say enough on a phone); the group/status chips ride on the
     nickname row (freed by removing host/last-seen); «Активно» + «Простой» share one
     metric row with the АФК box below; Telegram folds into the button row. */
  .dc-main { flex-direction: row; align-items: center; gap: 0.4rem 0.6rem; flex-wrap: wrap; }
  .dc-identity { flex: 1 1 auto; min-width: 0; }
  .dc-sub, .dc-lastseen { display: none; }
  /* Stage 19: the shift chip needs room the nickname row does not have, so on a
     phone the chips wrap onto their own line under the name (Stage 10.39 kept them on
     the name row when there were only two short ones — with the shift there the
     nickname was truncated to «Дне…»). The chip itself keeps only «HH:MM–HH:MM»,
     the activity chip loses its caption (colour + legend already decode it), and the
     pencil grows into a real touch target. */
  .dc-status { justify-content: flex-start; flex: 1 1 100%; }
  .dc-shift { padding: 0.1rem 0.25rem 0.1rem 0.4rem; gap: 0.2rem; }
  .dc-shift .shift-lbl, .dc-act-lbl { display: none; }
  .shift-edit > summary { width: 26px; height: 26px; }
  .dc-grid { grid-template-columns: repeat(2, 1fr); gap: 0.3rem 0.7rem; margin: 0.45rem 0; padding: 0.45rem 0; }
  .dc-afk-box { order: 1; }   /* push the АФК box below the Активно + Простой row */
  .dc-footer { justify-content: flex-start; align-items: center; gap: 0.4rem 0.45rem; }
  /* Stage 10.40: dissolve .dc-actions so its buttons + the bordered TG chip flow into
     ONE wrapping button row (TG no longer sits alone on its own line). The action
     <details> panels keep their own position:relative, so this is layout-safe. */
  .dc-actions { display: contents; }
  .dc-telegram { padding: 0.1rem 0.4rem; gap: 0.25rem; }
  .rn-full { display: none; }
  .rn-short { display: inline; }
  .list-people-head { display: none; }   /* drop the «Сотрудники» heading on phones */
  .dm-agent { display: none; }            /* drop the «Агент» row on the detail page */
  .mini-tl-wrap { max-width: 100%; }
  .mini-afk-strip { height: 9px; }

  .page-head { flex-direction: column; align-items: flex-start; }
  .detail-id { flex-direction: column; align-items: flex-start; }
  .detail-meta { gap: 0.5rem 1rem; }
  .dm-item { min-width: 45%; }

  /* Taller touch targets so timeline cells are tappable on a phone (Stage 10.39
     bumped the row strip from 26→34px — the operator reported it was too small). */
  .mini-timeline { height: 34px; }
  .timeline { height: 40px; }
  .afk-strip { height: 13px; }  /* Stage 10.25: tappable отходы segments on phones */

  /* Stage 10.30: weekly chart compact on phones (7 narrow columns still fit ≥320px);
     detail отходы strip keeps room for 4 flag lanes with smaller tags (compound
     selector so it overrides the .afk-strip {height:13px} rule above). */
  .detail-topbar { gap: 0.3rem 0.6rem; }
  .week-head { gap: 0.2rem 0.6rem; }
  .week-chart { gap: 0.2rem; }
  .week-day { padding: 0.25rem 0.08rem; }
  .wd-bar-area { height: 42px; }
  .wd-name { font-size: 11px; }
  .wd-date { font-size: 9.5px; }
  .wd-c-lbl { font-size: 9px; }
  .wd-c-short, .wd-c-long { font-size: 11px; }
  .wd-c-line { gap: 0.2rem; }
  .week-totals { gap: 0.7rem; }
  /* Stage 10.40: the detail strip height is the per-render calc (var --afk-lanes);
     just shrink the tags a touch so the minute labels stay compact on a phone. */
  .afk-flag .afk-tag { font-size: 8.5px; padding: 1px 4px; line-height: 1.1; }

  /* Stage 10.36: comparison fits ONE phone screen — no sideways scrolling. The page
     used to be a 10-column table the operator had to drag left/right; on phones we now
     drop the FIVE noisy columns (Активность %, Активно, Алерты, Клавиатура, Клики) and
     keep the at-a-glance set the operator actually scans:
     сотрудник · статус · Отходы · Проёбы · АФК. The live status stays BOTH as a tiny
     colour dot before the name (quick left-edge scan) and — per operator request — as a
     compact word chip in column 2 right of the name. Headers stay tappable, so ?sort=
     still re-orders the column you care about. */
  .comp-grid th:nth-child(3),  .comp-grid td:nth-child(3),   /* Активность %  */
  .comp-grid th:nth-child(6),  .comp-grid td:nth-child(6),   /* Активно        */
  .comp-grid th:nth-child(8),  .comp-grid td:nth-child(8),   /* Алерты         */
  .comp-grid th:nth-child(9),  .comp-grid td:nth-child(9),   /* Клавиатура     */
  .comp-grid th:nth-child(10), .comp-grid td:nth-child(10) { /* Клики          */
    display: none;
  }
  .table-wrap { overflow-x: visible; }
  .comp-grid { table-layout: fixed; width: 100%; }
  table.grid.comp-grid th, table.grid.comp-grid td { padding: 0.6rem 0.32rem; }
  .comp-grid th.col-sort .sort-link { padding: 0.6rem 0.32rem; }

  /* Status dot leads the name; the employee column takes whatever width is left and
     long names ellipsize INSIDE the chip (full name on the desktop table / device
     page). The chip + its name need min-width:0, or the inline-flex box refuses to
     shrink and the whole chip collapses to a single «…». */
  .comp-row-dot { display: inline-block; vertical-align: middle; margin-right: 0.45rem; }
  .comp-grid td:first-child { white-space: nowrap; overflow: hidden; }
  .comp-grid td:first-child .ident-chip { min-width: 0; max-width: calc(100% - 1.1rem); }
  .comp-grid td:first-child .ident-name { min-width: 0; }

  /* Column 2 «Статус» — a compact word chip right of the name. Narrow column; the badge
     shrinks to a small nowrap pill (ellipsis if ever too long); the one-word header
     «Статус» stays on a single line (no wrap/overlap with neighbouring headers). */
  .comp-grid th:nth-child(2), .comp-grid td:nth-child(2) { width: 4rem; text-align: left; }
  .comp-grid th:nth-child(2) .sort-link {
    font-size: 10px; white-space: nowrap; letter-spacing: 0;
  }
  .comp-grid td:nth-child(2) .badge {
    display: inline-block; max-width: 100%; padding: 0.05rem 0.32rem;
    font-size: 9px; letter-spacing: 0; white-space: nowrap;
    overflow: hidden; text-overflow: ellipsis; vertical-align: middle;
  }

  /* The three metric columns: fixed-narrow, right-aligned so the numbers line up for
     quick scanning, header text shrunk a touch so «ПРОЁБЫ» never wraps. Tighter than
     the 4-column layout to leave room for the new status column. */
  .comp-grid th:nth-child(4), .comp-grid td:nth-child(4),
  .comp-grid th:nth-child(5), .comp-grid td:nth-child(5),
  .comp-grid th:nth-child(7), .comp-grid td:nth-child(7) {
    width: 2.9rem; text-align: right; white-space: nowrap;
  }
  .comp-grid th:nth-child(7), .comp-grid td:nth-child(7) { width: 3.7rem; }  /* АФК holds a duration */
  .comp-grid th:nth-child(4) .sort-link,
  .comp-grid th:nth-child(5) .sort-link,
  .comp-grid th:nth-child(7) .sort-link {
    justify-content: flex-end; font-size: 10px; letter-spacing: 0.01em; gap: 0.15rem;
  }

  /* keep the axis uncrowded on narrow screens: only edges + the centre label */
  .mini-tl-axis .mtl-minor, .day-tl-axis .dtl-minor { display: none; }
}

/* --- Monitor cross-link button ------------------------------------------------
   «Монитор» sits on the identity row (card) / header (detail) and jumps to the
   MeshCentral wall in single-screen mode. It gets a faint accent tint so it reads
   as a link out to the other system; the unlinked state is a plain muted, inert
   label that still occupies the slot so «не привязано» is always visible. */
.dc-monitor, .detail-monitor { display: inline-flex; align-items: center; }
.detail-monitor { margin-top: 0.35rem; }
.mon-link.btn { gap: 0.3rem; }
a.mon-link { color: var(--accent); border-color: var(--accent-soft); }
a.mon-link:hover, a.mon-link:focus {
  color: var(--text); border-color: var(--accent); background: var(--accent-soft);
}
.mon-link.is-unlinked {
  color: var(--muted-2); border-color: var(--border); background: transparent;
  cursor: not-allowed; opacity: 0.75;
}

@media (max-width: 760px) {
  .st-tabs { width: 100%; }
  .st-tab { padding: 0.4rem 0.75rem; }
  .grp-layout, .tg-layout { grid-template-columns: 1fr; }
  .grp-list { flex-direction: row; flex-wrap: nowrap; overflow-x: auto; gap: 0.35rem; padding-bottom: 0.2rem; }
  .grp-item { flex: 0 0 auto; border-color: var(--border); }
  .grp-item.is-default { margin-bottom: 0; }
  .grp-create { flex: 0 0 200px; margin-top: 0; }
  .st-card-row { flex-direction: column; align-items: stretch; }
}
