/* ============================================================================
   K-MINE: GeoField — app.css. Клей рівня застосунку поверх theme.css.
   theme.css = бренд-система (токени + компоненти). app.css = база документа,
   тонкі утиліти, які вже вживає розмітка (.row/.mut/.err/.toolbar/.fld), і
   специфічні компоненти застосунку (галерея фото, SVG-редактори глибини/покриття).
   Підключати ПІСЛЯ theme.css: <link theme.css><link app.css>.
   ============================================================================ */

/* сумісність: подекуди у JS-шаблонах лишались var(--line)/var(--mut) — аліасимо
   на бренд-токени, щоб нічого не лишилось без межі під час/після міграції */
:root{ --line:var(--km-border); --mut:var(--text-muted); }

/* ── База документа (НЕ .gf-root на body: базовий scope-клас фарбує тло, що
      небажано на самому body-контейнері; тут base тримає body) ── */
body{ margin:0; font-family:var(--font); background:var(--km-bg); color:var(--text);
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility; line-height:1.5; }
h1,h2,h3{ font-weight:var(--fw-black); letter-spacing:-.01em; line-height:1.08; margin:0; }
main{ padding:var(--sp-lg); max-width:1100px; margin:0 auto; }
a{ color:var(--km-blue); }

/* ── Тонкі утиліти (розмітка вже їх вживає — токенізуємо, JS не чіпаємо) ── */
.row{ display:flex; gap:var(--sp-sm); align-items:center; flex-wrap:wrap; }
.spacer{ flex:1; }
.mut{ color:var(--text-muted); }
.err{ color:var(--danger-text); font-size:var(--fs-xs); font-weight:var(--fw-semibold); min-height:16px; }
.toolbar{ display:flex; gap:var(--sp-sm); align-items:flex-end; flex-wrap:wrap; margin-bottom:var(--sp-md); }
.fld{ display:flex; flex-direction:column; gap:var(--sp-xs); }
.fld > label{ font-size:var(--fs-label); font-weight:var(--fw-semibold); color:var(--text-muted); letter-spacing:.02em; }
/* поля в .fld без класу .input — надаємо їм вигляд .input (width 130 як у полі-вводі
   тулбару; логін-форма перекриває інлайн width:100%) */
.fld input, .fld select, .fld textarea{
  width:130px; height:42px; border:1.5px solid var(--km-border); border-radius:var(--r-lg);
  background:var(--km-surface); padding:0 var(--sp-md); font-family:var(--font); font-size:var(--fs-field);
  font-weight:var(--fw-semibold); color:var(--text); font-variant-numeric:tabular-nums; }
.fld textarea{ width:100%; height:auto; min-height:72px; padding:var(--sp-sm) var(--sp-md); font-weight:var(--fw-regular); line-height:1.4; resize:vertical; }
.fld input:focus, .fld select:focus, .fld textarea:focus{ outline:none; border-color:var(--km-blue); box-shadow:var(--focus-ring); }
.fld select{ appearance:none; -webkit-appearance:none; cursor:pointer; padding-right:30px;
  background-image:linear-gradient(45deg,transparent 50%,var(--text-muted) 50%),linear-gradient(135deg,var(--text-muted) 50%,transparent 50%);
  background-position:calc(100% - 16px) 18px, calc(100% - 11px) 18px; background-size:5px 5px,5px 5px; background-repeat:no-repeat; }

/* ── Галерея фото (перефарбовано dark→light; позицію/розмір плиток лишає JS!) ── */
.gal-scroll{ border:1px solid var(--km-border); border-radius:var(--r-sm); background:var(--km-bg); }
.gal-tile{ border-radius:var(--r-sm); cursor:pointer; box-sizing:border-box; }
.gal-tile > div{ box-sizing:border-box; }
.gal-tile:hover .gal-img{ outline:2px solid var(--km-blue); }
.gal-id{ font-size:var(--fs-meta); line-height:1.2; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  padding:2px 4px; color:var(--text); font-variant-numeric:tabular-nums; }
.gal-id b{ font-size:var(--fs-depth); font-weight:var(--fw-bold); }
.gal-img{ position:relative; height:104px; border-radius:var(--r-xs); overflow:hidden;
  background:var(--km-bg); border:1px solid var(--km-border); }
.gal-img img{ width:100%; height:100%; object-fit:cover; display:block; }
.gal-sub{ font-size:var(--fs-dense); color:var(--text-muted); white-space:nowrap; overflow:hidden;
  text-overflow:ellipsis; padding:2px 4px; }
.gal-group{ align-items:center; }
.gal-group + .gal-group, .gal-group.has-sep{ border-top:1px solid var(--km-border); }
/* Плейсхолдер порожнього кадру — причина трьома станами (за мовою станів системи) */
.gal-ph{ position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  text-align:center; font-size:var(--fs-micro); padding:6px; line-height:1.25; }
.gal-ph.sev-info{ color:var(--text-muted); }
/* К10 (відомо e26aced: «sev-warning/sev-error CSS»). photo-view.placeholderFor віддає
   severity 'warning'/'error', а стилі були лише для скорочених sev-warn/sev-err — тобто
   ЖОДЕН плейсхолдер «увага» не фарбувався. Тримаємо обидві форми, щоб не залежати від
   написання в рушії. */
.gal-ph.sev-warn, .gal-ph.sev-warning{ color:var(--conflict-text); background:var(--conflict-bg); }
.gal-ph.sev-err, .gal-ph.sev-error{ color:var(--danger-text); background:var(--danger-bg); }
/* Смуга стану синхр. плитки зліва — та сама мова, що й .irow .bar (ok/queued/attention) */
.gal-tile.sync-confirmed .gal-img{ border-left:3px solid var(--ok); }
.gal-tile.sync-pending   .gal-img{ border-left:3px solid var(--queued); }
.gal-tile.sync-attention .gal-img{ border-left:3px solid var(--danger); }
/* Іконка стану на плитці (надлишкове кодування — не лише колір смуги) */
.gal-sub .gsync{ display:inline-flex; width:12px; height:12px; vertical-align:-2px; margin-right:4px; flex:none; }
.gal-sub .gsync svg{ width:12px; height:12px; }
.gsync--confirmed{ color:var(--ok); }
.gsync--pending{ color:var(--queued); }
.gsync--attention{ color:var(--danger); }

/* ── SVG-редактори: покриття + глибина (заливки в JS ставляться через класи нижче;
      CSS fill перекриває presentation-атрибут) ── */
[data-testid="coverage-strip"] .cov-track{ fill:var(--km-surface-hover); }
[data-testid="coverage-strip"] .cov-declared{ fill:color-mix(in srgb, var(--ok) 60%, var(--km-surface)); }
[data-testid="coverage-strip"] .cov-delivered{ fill:var(--ok); }
[data-testid="coverage-strip"] .cov-gap{ fill:var(--danger); }
[data-testid="coverage-strip"]:focus{ outline:2px solid var(--km-blue); outline-offset:2px; }
[data-testid="depth-editor"] .depth-track{ fill:var(--km-surface-hover); }
[data-testid="depth-editor"] .depth-sel{ fill:var(--ok); }
[data-testid="depth-editor"] .depth-sel.is-ro{ fill:var(--km-gray); }
[data-testid="depth-editor"] .depth-handle{ fill:var(--km-ink); }        /* видимий на світлому (було майже-біле) */
[data-testid="depth-editor"] .depth-handle.is-ro{ fill:var(--km-gray); }
[data-testid="depth-editor"] .depth-handle{ cursor:ew-resize; }
[data-testid="depth-editor"] svg:focus{ outline:2px solid var(--km-blue); outline-offset:2px; }

/* ── ROI-редактор (рамка на фото) ── */
[data-testid="roi-rect"]{ border:2px solid var(--ok); background:color-mix(in srgb, var(--ok) 16%, transparent); }

/* ── Таблиця на вузькому екрані: скрол замість обрізання колонки «стан» ──
      display:block лишає вирівнювання колонок (анонімний table-box), але дає overflow */
@media (max-width:820px){
  .gtable{ display:block; overflow-x:auto; -webkit-overflow-scrolling:touch; }
}

/* ── Контроли всередині темної шапки ── */
.appbar{ min-height:56px; flex-wrap:wrap; row-gap:6px; }   /* вузький екран: перенос, не горизонтальний скрол сторінки */
@media (max-width:520px){ .appbar .mut{ display:none; } }  /* контекст вторинний — ховаємо на телефоні */
.appbar .lockup{ flex:none; }
.appbar .mut{ color:var(--on-dark-2); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0; }  /* #ctx: еліпсис, не 3 рядки */
.appbar-text-btn{ background:transparent; border:0; color:var(--on-dark-2); font-family:var(--font);
  font-size:var(--fs-dense); font-weight:var(--fw-semibold); cursor:pointer; padding:6px 8px; border-radius:var(--r-sm); }
.appbar-text-btn:hover{ background:rgba(255,255,255,.08); }

/* ── К10: банери сесії/сховища (П2-C12, K3) — видимі на КОЖНОМУ екрані, не лише на фото ── */
.banner{ padding:var(--sp-sm) var(--sp-md); border-radius:var(--r-sm); font-size:var(--fs-xs);
  font-weight:var(--fw-semibold); margin-bottom:var(--sp-sm); }
.banner--warn{ color:var(--conflict-text); background:var(--conflict-bg); border:1px solid var(--conflict); }
.banner--danger{ color:var(--danger-text); background:var(--danger-bg); border:1px solid var(--danger); }
.banner .btn{ margin-left:var(--sp-sm); }
/* дії над відхиленими/конфліктними рядками (П2-B7) і конфліктами sync (K8) */
.row-actions{ display:inline-flex; gap:4px; margin-left:6px; vertical-align:middle; }
.srv-val{ font-size:var(--fs-micro); color:var(--conflict-text); white-space:pre-wrap; }
.tenant-pick .opt{ padding:8px 10px; cursor:pointer; border-top:1px solid var(--km-border); }
.banners{ max-width:1100px; margin:0 auto; padding:0 var(--sp-lg); }
.banners:empty{ display:none; }
.banners .banner{ margin-top:var(--sp-sm); margin-bottom:0; }

/* ── K11-№4 (AM-LOCK-02): «увага» — жовте, не червоне: операцію ЗАСТОСОВАНО, але з попередженням
      про чужу лізу; рішення людини не потрібне. Форма під чужою лізою до підтвердження — read-only. ── */
.chip--warn{ color:var(--conflict-text); background:var(--conflict-bg); }
.warn-tag{ font-size:var(--fs-micro); font-weight:var(--fw-bold); letter-spacing:.04em; padding:2px 7px; border-radius:var(--r-xs);
  color:var(--conflict-text); background:var(--conflict-bg); white-space:nowrap; }
[data-readonly="lease"] .toolbar{ opacity:.65; }
/* K11-№9: готові параметри affine2d — моноширинним, щоб копіювати в налаштування CRS без помилки знака */
.code-block{ font-family:ui-monospace,SFMono-Regular,Menlo,monospace; white-space:pre-wrap; word-break:break-all;
  background:var(--km-bg); border:1px solid var(--km-border); border-radius:var(--r-sm); padding:4px 8px; color:var(--text); }

/* ── K12-FE-B (Крок 12 «Вхід у полі»): екрани входу S-01a/b/c/d, шапка-меню, банери строку, S-23, «Стан пристрою» ──
      Цілі дотику: PIN-кнопки ≥ 56×56 px з проміжком ≥ 8 px (спека 3.1 №19; ТЗ FR-S00-02 ≥ 44; TC-J-03 рукавички; WCAG 2.5.5),
      плитки користувачів ≥ 72 px по висоті на всю ширину, посилання екранів входу — окремі кнопки ≥ 44 px (.tap44). */
.tap44{ min-height:44px; min-width:44px; }
.login-card .pw-row .btn--sm{ height:44px; min-height:44px; padding:0 var(--sp-md); white-space:nowrap; }
.login-card .fld input{ height:48px; font-size:var(--fs-base); }

/* PIN-панель: сітка 3×4 (1–9, ⌫, 0, ✓); приховане поле тримає фокус для апаратної клавіатури і читачів екрана
   (opacity:0, НЕ display:none — інакше фокус неможливий) */
.pinpad{ position:relative; display:flex; flex-direction:column; align-items:center; gap:var(--sp-sm); }
.pinpad__label{ font-size:var(--fs-sm); font-weight:var(--fw-semibold); color:var(--text-muted); }
.pinpad__hint{ font-size:var(--fs-xs); text-align:center; }
.pinpad__dots{ display:flex; gap:12px; margin:4px 0; }
.pinpad__dot{ width:16px; height:16px; border-radius:50%; border:2px solid var(--km-ink); background:transparent; transition:background .08s; }
.pinpad__dot.is-on{ background:var(--km-ink); }
.pinpad__input{ position:absolute; opacity:0; width:1px; height:1px; left:0; top:0; border:0; padding:0; margin:0; pointer-events:none; caret-color:transparent; }
.pinpad__input--text{ -webkit-text-security:disc; }
.pinpad__keys{ display:grid; grid-template-columns:repeat(3, 64px); gap:10px; }
.pinkey{ min-width:56px; min-height:56px; width:64px; height:64px; border-radius:var(--r-2xl); border:1.5px solid var(--km-border); background:var(--km-surface);
  font-family:var(--font); font-size:var(--fs-2xl); font-weight:var(--fw-bold); color:var(--text); cursor:pointer; box-shadow:var(--shadow-card); touch-action:manipulation; user-select:none; }
.pinkey:hover{ background:var(--km-bg); }
.pinkey:active{ background:var(--km-border); transform:translateY(1px); }
.pinkey:focus-visible{ outline:2px solid var(--km-blue); outline-offset:2px; }
.pinkey[disabled]{ opacity:.45; cursor:not-allowed; transform:none; }
.pinkey--ok{ background:var(--km-yellow); border-color:var(--km-yellow); box-shadow:0 2px 0 var(--km-yellow-press); }
.pinkey--ok:hover{ background:var(--km-yellow-hover); }
.pinkey--del{ font-size:var(--fs-xl); }
.pinpad__msg{ min-height:20px; font-size:var(--fs-xs); font-weight:var(--fw-semibold); text-align:center; }
.pinpad__msg--err{ color:var(--danger-text); }
.pinpad__msg--pause{ color:var(--conflict-text); font-variant-numeric:tabular-nums; }
.pinpad__msg--busy{ color:var(--text-muted); }
.pinpad.is-disabled .pinpad__dots{ opacity:.5; }
.pin-card .pin-term{ font-size:var(--fs-sm); margin:-4px 0 12px; }
.pin-card .pin-term[data-cert="expired"]{ color:var(--danger-text); font-weight:var(--fw-semibold); }
.pin-card .pin-term[data-cert="expiring"]{ color:var(--conflict-text); font-weight:var(--fw-semibold); }
.pin-locked{ font-weight:var(--fw-regular); }

/* S-01b плитки користувачів */
.who-list{ display:flex; flex-direction:column; gap:var(--sp-sm); }
.who-tile{ display:flex; align-items:center; gap:var(--sp-md); width:100%; min-height:72px; padding:var(--sp-sm) var(--sp-md); text-align:left;
  border:1.5px solid var(--km-border); border-radius:var(--r-2xl); background:var(--km-surface); font-family:var(--font); color:var(--text); cursor:pointer; box-shadow:var(--shadow-card); }
.who-tile:hover{ background:var(--km-bg); }
.who-tile:focus-visible{ outline:2px solid var(--km-blue); outline-offset:2px; border-color:var(--km-blue); }
.who-tile--locked{ background:var(--danger-wash); }
.who-tile__avatar{ flex:none; width:48px; height:48px; border-radius:50%; background:var(--km-ink); color:var(--km-yellow); display:grid; place-items:center; font-weight:var(--fw-black); font-size:var(--fs-lg); letter-spacing:.02em; }
.who-tile__body{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.who-tile__name{ font-weight:var(--fw-bold); font-size:var(--fs-base); }
.who-tile__meta{ font-size:var(--fs-xs); color:var(--text-muted); }
.who-tile__state{ font-size:var(--fs-dense); font-weight:var(--fw-semibold); color:var(--ok-text); }
.who-tile__state--expiring{ color:var(--conflict-text); }
.who-tile__state--expired, .who-tile__state--locked{ color:var(--danger-text); }
.who-tile__state--none{ color:var(--text-muted); }

/* шапка: меню користувача (Заблокувати / Змінити користувача / Змінити PIN / Стан пристрою / Пристрої / Вийти з пристрою) */
.user-menu-wrap{ position:relative; flex:none; }
.user-menu{ position:absolute; right:0; top:calc(100% + 6px); z-index:30; min-width:240px; background:var(--km-surface); color:var(--text);
  border:1px solid var(--km-border); border-radius:var(--r-lg); box-shadow:0 8px 24px rgba(26,26,26,.18); padding:6px; display:none; }
.user-menu.open{ display:block; }
.user-menu button{ display:block; width:100%; min-height:44px; text-align:left; background:transparent; border:0; border-radius:var(--r-sm); padding:0 var(--sp-md);
  font-family:var(--font); font-size:var(--fs-sm); font-weight:var(--fw-semibold); color:var(--text); cursor:pointer; }
.user-menu button:hover{ background:var(--km-bg); }
.user-menu button:focus-visible{ outline:2px solid var(--km-blue); outline-offset:-2px; }
.user-menu button.is-danger{ color:var(--danger-text); }
.user-menu .sep{ height:1px; background:var(--km-border); margin:4px 0; }

/* банери офлайн-строку (MSG-OFF-05/06/07) — стан не лише кольором, а й текстом; expired не закривається */
.banner--term-expired{ color:var(--danger-text); background:var(--danger-bg); border:1px solid var(--danger); }
.banner--term-last_day{ color:var(--danger-text); background:var(--danger-bg); border:1px solid var(--danger); }
.banner--term-warn{ color:var(--conflict-text); background:var(--conflict-bg); border:1px solid var(--conflict); }
.banner--term-info{ color:var(--text-muted); background:var(--km-surface-hover); border:1px solid var(--km-border); }
.banner .btn--xs{ margin-left:var(--sp-sm); vertical-align:middle; }
/* read-only-гейт мутацій при вичерпаному строку (К10): як [data-readonly="lease"], але з поясненням у title і банері */
[data-readonly-term="expired"] .toolbar{ opacity:.65; }
[data-readonly-term="expired"] [data-gated="offline_expired"]{ cursor:not-allowed; }

/* тост (успіх/інформація) */
.gf-toast{ position:fixed; left:50%; bottom:24px; transform:translateX(-50%); z-index:40; max-width:min(560px, 92vw); padding:var(--sp-sm) var(--sp-lg);
  border-radius:var(--r-full); background:var(--km-ink); color:var(--on-dark); font-size:var(--fs-sm); font-weight:var(--fw-semibold); box-shadow:0 8px 24px rgba(26,26,26,.25); }
.gf-toast--ok{ border-left:4px solid var(--ok); }
.gf-toast--warn{ border-left:4px solid var(--conflict); }

/* S-23 «Пристрої» і «Стан пристрою» */
.devices-table .dv-state{ white-space:nowrap; }
.dv-policy label + label{ margin-top:6px; }
.dv-state{ display:flex; flex-direction:column; gap:6px; }
.dv-state-row{ display:flex; gap:var(--sp-md); align-items:baseline; padding:6px 0; border-top:1px solid var(--km-border); font-size:var(--fs-sm); }
.dv-state-row > .mut{ flex:0 0 42%; }
.dv-state-row > b{ font-weight:var(--fw-semibold); min-width:0; }
.dv-state-slots{ margin:4px 0 0; padding-left:18px; font-weight:var(--fw-regular); }

/* ── K13-FE19 (К36): контрольна карта QAQC (qaqc-chart.mjs) + екран «Бібліотека стандартних зразків (CRM)» ── */
.qc-chart{ display:block; max-width:100%; background:var(--km-surface); }
.qc-zone--fail{ fill:var(--danger-bg); opacity:.5; }
.qc-zone--warn{ fill:var(--conflict-bg); opacity:.55; }
.qc-zone--in{ fill:var(--ok-bg); opacity:.4; }
.qc-frame{ stroke:var(--km-border); }
.qc-grid{ stroke:var(--km-border); stroke-dasharray:2 3; opacity:.6; }
.qc-tick{ font-size:10px; fill:var(--text-muted); font-family:var(--font); }
.qc-band line{ stroke-dasharray:5 4; stroke-width:1.2; }
.qc-band--warn line{ stroke:var(--conflict-text); }
.qc-band--fail line{ stroke:var(--danger); }
.qc-band text{ font-size:9.5px; font-family:var(--font); }
.qc-band--warn text{ fill:var(--conflict-text); }
.qc-band--fail text{ fill:var(--danger-text); }
.qc-line--certified line{ stroke:var(--km-ink); stroke-width:1.6; }
.qc-line text{ font-size:9.5px; fill:var(--text-muted); font-family:var(--font); }
.qc-path{ stroke:var(--km-blue); stroke-width:1; opacity:.5; }
.qc-pt{ cursor:pointer; stroke:var(--km-surface); stroke-width:1; }
.qc-pt--pass{ fill:var(--ok); }
.qc-pt--warning{ fill:var(--conflict); }
.qc-pt--fail{ fill:var(--danger); }
.qc-pt--na{ fill:var(--km-gray); }
.qc-pt--override{ stroke:var(--km-ink); stroke-width:1.6; }
.crm-focus{ outline:2px solid var(--km-blue); outline-offset:1px; background:var(--km-blue-tint); border-radius:var(--r-xs); }
/* FIX-13 R11B-01 (К36): точка партії, підсвічена лінком №18 «показати на карті» */
.qc-pt--focus{ stroke:var(--km-blue); stroke-width:2.5px; }
.crm-note-fixed{ font-size:var(--fs-dense); color:var(--danger-text); background:var(--danger-wash); border:1px dashed var(--danger); border-radius:var(--r-sm); padding:var(--sp-xs) var(--sp-sm); margin-top:var(--sp-xs); }
