/* jarvis-connected — jeden arkusz (1.6, ADR 0008). Zmienne CSS: motyw Jarvis (praca) i Edith
   (życie prywatne) przez [data-theme]; wariant ciemny przez prefers-color-scheme. Kolory
   accent/background muszą być równe THEME_COLORS w app/ui/theme.py (strażnik test_static_assets).
   Progi: telefon < 640 px (pasek dolny), tablet 640–1023 px (wąska kolumna), desktop ≥ 1024 px. */

:root,
[data-theme="jarvis"] {
  --bg: #f4f6fb;
  --surface: #ffffff;
  --surface-2: #eef1f7;
  --border: #d7dce8;
  --text: #1a202c;
  --muted: #5a6577;
  --accent: #2ecc71;
  --accent-soft: #d9f5e4;
  --on-accent: #0b2e1b;
  --link: #1b7f47;
  --danger: #b42318;
  --danger-soft: #fde8e6;
  --focus: #1b7f47;
  --shadow: 0 1px 2px rgba(16, 24, 40, 0.06);
  --radius: 10px;
  --topbar-h: 60px; /* 1.7a: 7 px luzu nad i pod toggle'em (44 px + ramka) */
  --sidenav-w: 240px;
  --tap: 44px;
}

[data-theme="edith"] {
  --bg: #f3f1ec;
  --surface: #fffdf9;
  --surface-2: #ece8df;
  --border: #d9d2c4;
  --text: #2c2a26;
  --muted: #625c51;
  --accent: #7ba892;
  --accent-soft: #e2ede6;
  --on-accent: #16261e;
  --link: #3d6f56;
  --danger: #a4463a;
  --danger-soft: #f6e4df;
  --focus: #3d6f56;
}

@media (prefers-color-scheme: dark) {
  :root,
  [data-theme="jarvis"] {
    --bg: #0f1420;
    --surface: #1a2130;
    --surface-2: #232c3f;
    --border: #34405a;
    --text: #e6eaf2;
    --muted: #a3adbf;
    --accent: #2ecc71;
    --accent-soft: #163526;
    --on-accent: #0b2e1b;
    --link: #6fd39a;
    --danger: #ff8a80;
    --danger-soft: #3a1f1c;
    --focus: #6fd39a;
    --shadow: none;
  }
  [data-theme="edith"] {
    --bg: #1d1b17;
    --surface: #2a2722;
    --surface-2: #35312a;
    --border: #4a453b;
    --text: #efeae0;
    --muted: #b5ad9f;
    --accent: #7ba892;
    --accent-soft: #22302a;
    --on-accent: #16261e;
    --link: #a3cdb7;
    --danger: #f2a094;
    --danger-soft: #3d2622;
    --focus: #a3cdb7;
    --shadow: none;
  }
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  background: var(--bg);
}

body {
  margin: 0;
  min-height: 100dvh;
  font: 16px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  color: var(--text);
  background: var(--bg);
  display: grid;
  grid-template-rows: var(--topbar-h) 1fr;
  grid-template-columns: 1fr;
  grid-template-areas: "top" "main";
  overflow-x: hidden;
}

@media (prefers-reduced-motion: no-preference) {
  a,
  button {
    transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
  }
}

a {
  color: var(--link);
  text-underline-offset: 2px;
}

:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

.skip-link {
  position: absolute;
  left: 8px;
  top: -100px;
  z-index: 100;
  padding: 8px 12px;
  background: var(--surface);
  border-radius: var(--radius);
}
.skip-link:focus {
  top: 8px;
}

/* --- nagłówek --- */
.topbar {
  grid-area: top;
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 8px;
  height: var(--topbar-h);
  padding: 0 12px;
  padding-left: max(12px, env(safe-area-inset-left));
  padding-right: max(12px, env(safe-area-inset-right));
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow);
}
.brand {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  padding: 0 4px;
  font-weight: 700;
  font-size: 1.1rem;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 40vw;
}
.brand::before {
  content: "";
  display: inline-block;
  width: 12px;
  height: 12px;
  margin-right: 8px;
  border-radius: 50%;
  background: var(--accent);
  flex: none;
}
.topbar-tools {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
/* konto = avatar z inicjałami (1.7a): bez adresu e-mail w nagłówku, stała szerokość */
.account.avatar {
  width: var(--tap);
  height: var(--tap);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--text);
  font-weight: 700;
  font-size: 0.9rem;
  letter-spacing: 0.5px;
  text-decoration: none;
}
.account.avatar:hover {
  background: var(--accent);
  color: var(--on-accent);
}

/* przełączniki: motyw i język */
.segmented {
  display: inline-flex;
  margin: 0;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2);
}
.seg {
  min-height: var(--tap);
  min-width: var(--tap);
  padding: 0 12px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.seg.is-active {
  background: var(--accent);
  color: var(--on-accent);
}
/* toggle w nagłówku (1.7a): aktywny segment to link Home, nieaktywny — formularz POST /ui/app */
.app-switch .seg-form {
  display: contents;
  margin: 0;
}
.app-switch .seg {
  margin: 0;
}

/* --- nawigacja --- */
.sidenav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: 4px;
}
.sidenav a,
.sidenav .nav-end button {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: var(--tap);
  padding: 0 14px;
  border-radius: var(--radius);
  color: var(--text);
  text-decoration: none;
  font-weight: 500;
  white-space: nowrap;
}
.ux-icon {
  width: 20px;
  height: 20px;
  flex: none;
}
.sidenav a[aria-current="page"] {
  background: var(--accent-soft);
  color: var(--text);
  font-weight: 700;
}
.sidenav a:hover {
  background: var(--surface-2);
}
/* 2.13: nagłówek grupy „Administracja” w kolumnie (tylko administrator; na telefonie ukryty jak
   każda pozycja poza `nav-primary`) */
.sidenav .nav-group span {
  display: block;
  padding: 12px 14px 4px;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}

/* telefon: pasek dolny — 4 pozycje główne (`nav-primary`) z ikonami, bez przewijania; reszta
   (admin, wylogowanie) w menu na stronie głównej (1.7a, uwaga U7) */
.sidenav {
  grid-area: nav;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 20;
  background: var(--surface);
  border-top: 1px solid var(--border);
  padding: 4px 4px;
  padding-bottom: max(4px, env(safe-area-inset-bottom));
}
.sidenav ul {
  justify-content: space-around;
}
.sidenav li:not(.nav-primary) {
  display: none;
}
.sidenav a {
  flex: 1 1 0;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  padding: 4px 4px;
  font-size: 0.7rem;
  line-height: 1.2;
  min-width: 0;
}
.sidenav a .ux-icon {
  width: 22px;
  height: 22px;
}
.sidenav a span {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}
body:has(.sidenav) .content {
  padding-bottom: calc(var(--tap) + 32px);
}

/* --- treść --- */
.content {
  grid-area: main;
  width: 100%;
  max-width: 840px;
  margin: 0 auto;
  padding: 16px;
  padding-left: max(16px, env(safe-area-inset-left));
  padding-right: max(16px, env(safe-area-inset-right));
  min-width: 0;
}
.content-anon {
  max-width: 480px;
}
h1 {
  font-size: 1.6rem;
  line-height: 1.25;
  margin: 8px 0 16px;
}
h2 {
  font-size: 1.2rem;
  margin: 24px 0 8px;
}
p {
  margin: 8px 0;
}
small {
  color: var(--muted);
}
code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.95em;
  padding: 2px 6px;
  border-radius: 6px;
  background: var(--surface-2);
  overflow-wrap: anywhere;
}
ul {
  padding-left: 20px;
}
.tiles {
  list-style: none;
  padding: 0;
  display: grid;
  gap: 8px;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
}
.tiles-heading {
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 24px 0 8px;
}
.tiles a {
  display: flex;
  align-items: center;
  gap: 8px; /* ikona nie przykleja się do napisu (rev 25, M-1) */
  min-height: var(--tap);
  padding: 12px 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
  text-decoration: none;
  font-weight: 600;
}

/* --- formularze --- */
form {
  margin: 12px 0;
}
form.inline {
  display: inline-block;
  margin: 2px 4px 2px 0;
}
label {
  display: block;
  font-weight: 500;
  margin: 8px 0 4px;
}
input[type="text"],
input[type="email"],
input[type="password"],
input[type="search"],
input[type="date"],
input[type="time"],
input[type="number"],
input[type="url"],
select,
textarea {
  display: block;
  width: 100%;
  min-height: var(--tap);
  padding: 8px 12px;
  margin-top: 4px;
  font: inherit;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
textarea {
  min-height: 96px;
  resize: vertical;
}
/* pole daty i godziny: Safari/iOS nadaje im własną szerokość i wyśrodkowanie — mają być jak każde inne pole
   (rev 23, uwaga właściciela; 2.14: `time` w Ustawieniach → Uwaga i w cronach) */
input[type="date"],
input[type="time"] {
  -webkit-appearance: none;
  appearance: none;
  min-width: 0;
  max-width: 100%;
  text-align: left;
}
/* iOS trzyma tekst daty/godziny w osobnym elemencie z własnym wyśrodkowaniem — `text-align` na polu go nie sięga (rev 24, M-3) */
input[type="date"]::-webkit-date-and-time-value,
input[type="time"]::-webkit-date-and-time-value {
  text-align: left;
}
/* 2.14 (UX-SYSTEM §13): liczba z jednostką po polu — pole rośnie, jednostka nie zawija się; pola crona (godzina + wyrażenie) w rzędzie od tabletu */
.ux-with-unit {
  display: flex;
  align-items: center;
  gap: 8px;
}
.ux-with-unit input {
  flex: 1 1 auto;
  width: auto;
  min-width: 0;
}
.ux-unit {
  flex: 0 0 auto;
  color: var(--muted, inherit);
  white-space: nowrap;
}
/* 2.14: sekcje persony na zakładce Asystent — dwa boty, ta sama ramka co pola */
.settings-persona {
  margin: 12px 0;
  padding: 4px 16px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.settings-persona legend {
  padding: 0 6px;
  font-weight: 600;
}
.settings-cron-fields {
  display: grid;
  gap: 0 16px;
  grid-template-columns: 1fr;
}
@media (min-width: 640px) {
  .settings-cron-fields {
    grid-template-columns: minmax(8rem, 1fr) 2fr;
  }
}
input[type="checkbox"] {
  width: 22px;
  height: 22px;
  margin: 0 8px 0 0;
  vertical-align: middle;
  accent-color: var(--accent);
}
label:has(> input[type="checkbox"]) {
  display: flex;
  align-items: center;
  min-height: var(--tap);
  font-weight: 400;
}
button,
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--tap);
  padding: 8px 16px;
  margin: 4px 4px 4px 0;
  font: inherit;
  font-weight: 600;
  color: var(--on-accent);
  background: var(--accent);
  border: 1px solid transparent;
  border-radius: var(--radius);
  text-decoration: none;
  cursor: pointer;
}
button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.btn-quiet,
form.inline button {
  background: var(--surface);
  color: var(--text);
  border-color: var(--border);
}
.btn-danger,
button.btn-danger {
  background: var(--danger);
  color: #fff;
}
.is-disabled {
  opacity: 0.5;
  pointer-events: none;
}
.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* komunikaty */
[role="alert"] {
  padding: 10px 12px;
  border-radius: var(--radius);
  background: var(--danger-soft);
  color: var(--danger);
  border: 1px solid transparent;
}
[role="status"] {
  padding: 10px 12px;
  border-radius: var(--radius);
  background: var(--accent-soft);
  color: var(--text);
}

/* --- tablet: nawigacja jako lewa kolumna --- */
@media (min-width: 640px) {
  body {
    grid-template-columns: var(--sidenav-w) 1fr;
    grid-template-rows: var(--topbar-h) 1fr;
    grid-template-areas: "top top" "nav main";
  }
  body:not(:has(.sidenav)) {
    grid-template-columns: 1fr;
    grid-template-areas: "top" "main";
  }
  .sidenav {
    position: sticky;
    top: var(--topbar-h);
    bottom: auto;
    left: auto;
    right: auto;
    align-self: start;
    height: calc(100dvh - var(--topbar-h));
    border-top: 0;
    border-right: 1px solid var(--border);
    padding: 12px 8px;
    overflow-x: hidden;
    overflow-y: auto;
  }
  .sidenav ul {
    flex-direction: column;
    min-width: 0;
  }
  .sidenav li:not(.nav-primary) {
    display: flex;
  }
  .sidenav li > a,
  .sidenav li > form {
    flex: 1 1 auto;
    min-width: 0; /* pozycja zwęża się do kolumny (180 px na tablecie) zamiast ją rozpychać */
  }
  .sidenav a {
    flex-direction: row;
    justify-content: flex-start;
    gap: 10px;
    padding: 8px 14px;
    font-size: 1rem;
    line-height: 1.3;
    white-space: normal; /* długie etykiety („Ustawienia instalacji”) łamią się zamiast wychodzić poza kolumnę */
  }
  .sidenav a .ux-icon {
    width: 20px;
    height: 20px;
  }
  .sidenav a span {
    overflow: visible;
  }
  body:has(.sidenav) .content {
    padding-bottom: 24px;
  }
  .content {
    padding: 24px;
  }
}

@media (min-width: 640px) and (max-width: 1023.98px) {
  :root {
    --sidenav-w: 180px;
  }
}

@media (min-width: 1024px) {
  .content {
    padding: 32px 40px;
  }
  .brand {
    max-width: none;
  }
}

/* widoczność wg progu: `.wide-only` od tabletu, `.phone-only` tylko telefon */
@media (max-width: 639.98px) {
  .wide-only {
    display: none !important;
  }
  .brand {
    font-size: 1rem;
    max-width: 34vw;
  }
  .seg {
    padding: 0 10px;
  }
}
@media (min-width: 640px) {
  .phone-only {
    display: none !important;
  }
  .sidenav .nav-end {
    margin-top: auto;
  }
  .sidenav ul {
    height: 100%;
  }
}
.sidenav .inline {
  margin: 0;
}
.sidenav li {
  display: flex;
  align-items: center;
}
.sidenav .nav-end button {
  margin: 0;
  border: 0;
  background: transparent;
  width: 100%;
  justify-content: flex-start;
}
.sidenav .nav-end button:hover {
  background: var(--surface-2);
}



/* ==========================================================================================
   System UX (1.7, ADR 0008, docs/UX-SYSTEM.md) — jedna sekcja per wzorzec z app/templates/ui/_ux.html.
   Kolory tylko ze zmiennych motywu; cele dotykowe ≥ var(--tap); karty < 640 px zamiast tabeli.
   ========================================================================================== */

/* --- lista: toolbar --- */
.ux-list {
  margin: 12px 0 24px;
}
.ux-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 0 0 12px;
}
.ux-toolbar label {
  margin: 0;
  font-weight: 500;
}
.ux-toolbar input,
.ux-toolbar select {
  margin-top: 0;
}
.ux-search {
  flex: 1 1 200px;
  min-width: 0;
}
.ux-per-page {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}
.ux-per-page select {
  width: auto;
}
.ux-toolbar .btn-quiet,
.ux-toolbar .btn {
  margin: 0;
}
.ux-toolbar .ux-primary {
  order: -1; /* akcja główna listy jako pierwsza w toolbarze (1.7a) */
}
@media (max-width: 639.98px) {
  .ux-toolbar .ux-primary {
    flex-basis: 100%;
  }
}
.ux-count {
  flex-basis: 100%;
  padding: 0;
  background: none;
  color: var(--muted);
}

/* --- lista: pasek akcji masowych (widoczny tylko z zaznaczeniem) --- */
.ux-bulk {
  margin: 0;
}
.ux-bulk-bar {
  display: none;
  position: sticky;
  top: var(--topbar-h);
  z-index: 10;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  margin: 0 0 8px;
  background: var(--accent-soft);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.ux-bulk:has(input[name="ids"]:checked) .ux-bulk-bar {
  display: flex;
  flex-wrap: wrap;
}
.ux-bulk-bar .btn,
.ux-bulk-bar button {
  margin: 0;
}
.ux-bulk-count {
  font-weight: 600;
  margin-right: auto;
}

/* --- lista: tabela --- */
.ux-table-wrap {
  overflow-x: auto;
  position: relative; /* 2.3: blok zawierający dla `.visually-hidden` w nagłówku kolumny akcji — inaczej
     pozycjonowany absolutnie napis leżał poza przewijanym opakowaniem i rozpychał stronę (7 kolumn na 834 px) */
  -webkit-overflow-scrolling: touch;
}
.ux-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.ux-table th,
.ux-table td {
  padding: 10px 12px;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--border);
}
.ux-table tbody tr:last-child td {
  border-bottom: 0;
}
.ux-table th {
  font-weight: 600;
  color: var(--muted);
  background: var(--surface-2);
  white-space: nowrap;
}
.ux-table tbody tr:hover {
  background: var(--surface-2);
}
.ux-table tr:has(input[name="ids"]:checked) {
  background: var(--accent-soft);
}
.ux-table .ux-col-select {
  width: 44px;
  padding: 4px 8px;
}
.ux-table .ux-col-select label {
  margin: 0;
  min-height: var(--tap);
  justify-content: center;
}
.ux-table .ux-col-select input[type="checkbox"] {
  margin: 0;
}
.ux-sort {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 28px;
  color: inherit;
  text-decoration: none;
}
.ux-sort::after {
  content: "\2195";
  opacity: 0.5;
}
.ux-sort.is-active {
  color: var(--text);
}
.ux-sort.is-active::after {
  opacity: 1;
}
.ux-sort.is-asc::after {
  content: "\2191";
}
.ux-sort.is-desc::after {
  content: "\2193";
}
.ux-table tbody tr:has(.ux-row-link) {
  cursor: pointer; /* cały wiersz otwiera rekord — app.js klika w .ux-row-link (1.7a) */
}
/* 2.14: kolumny z identyfikatorami bez spacji (klucz promptu, id modelu) łamią się zamiast rozpychać tabelę na tablecie */
.ux-table .col-key,
.ux-table .col-model {
  overflow-wrap: anywhere;
}
/* akcje na wierszu (1.8): ikony 44 px, kolumna ostatnia do prawej; karta: prawy górny róg obok checkboxa */
.ux-table .ux-col-actions {
  width: 1%;
  white-space: nowrap;
  text-align: right;
  padding: 2px 8px;
}
.ux-row-action,
.ux-row-action-form {
  display: inline-flex;
  vertical-align: middle;
}
.ux-row-action-form {
  margin: 0;
}
.ux-row-action {
  align-items: center;
  justify-content: center;
  min-width: var(--tap);
  min-height: var(--tap);
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  color: var(--muted);
  text-decoration: none;
  cursor: pointer;
}
.ux-row-action:hover {
  background: var(--surface-2);
  color: var(--text);
}
.ux-row-action.is-danger:hover {
  color: var(--danger);
  background: var(--danger-soft);
}
.ux-row-link {
  display: block;
  min-height: 24px;
  color: var(--text);
  font-weight: 600;
  text-decoration: none;
  overflow-wrap: anywhere;
}
.ux-row-link:hover {
  text-decoration: underline;
}
.ux-table td small {
  display: block;
}

/* karty zamiast tabeli na telefonie (ADR 0008 §3) */
@media (max-width: 639.98px) {
  .ux-table,
  .ux-table tbody,
  .ux-table tr,
  .ux-table td {
    display: block;
  }
  .ux-table {
    border: 0;
    background: none;
  }
  .ux-table tr {
    position: relative;
    display: flex; /* karta: kolejność komórek przez `order` — tytuł, pod nim meta (data), reszta */
    flex-direction: column;
    margin: 0 0 8px;
    padding: 4px 0 8px; /* dolny odstęp na karcie, nie na `td:last-child` — po `order` ostatnia w DOM ≠ ostatnia wizualnie (rev 24, M-4) */
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
  }
  .ux-table td {
    display: flex;
    gap: 12px;
    padding: 6px 12px;
    border-bottom: 0;
  }
  .ux-table td::before {
    content: attr(data-label);
    flex: 0 0 96px; /* stała szerokość etykiety = wartości w jednej linii pionowej (1.7a, uwaga U4) */
    color: var(--muted);
    font-size: 0.9rem;
  }
  /* nagłówek karty: pierwsza komórka (link rekordu) bez etykiety, na całą szerokość; miejsce na checkbox */
  .ux-table td.ux-cell-main {
    display: block;
    order: -2;
    padding: 10px 12px 2px;
  }
  .ux-table tr:has(.ux-col-select) td.ux-cell-main {
    padding-right: 56px;
  }
  /* akcje w prawym górnym rogu karty: 1–4 ikony po 44 px z odstępem 4 px = `--actions` × 48 − 4;
     checkbox i prawy margines nagłówka liczone z tej samej zmiennej (rev 25, I-1) */
  .ux-table tbody tr {
    --actions: 2;
  }
  .ux-table tbody tr:has(td.ux-col-actions > :first-child:last-child) {
    --actions: 1;
  }
  .ux-table tbody tr:has(td.ux-col-actions > :nth-child(3)) {
    --actions: 3;
  }
  .ux-table tbody tr:has(td.ux-col-actions > :nth-child(4)) {
    --actions: 4;
  }
  .ux-table td.ux-col-actions {
    position: absolute;
    top: 4px;
    right: 4px;
    width: auto;
    padding: 0;
    display: flex;
    gap: 4px;
  }
  .ux-table td.ux-col-actions::before {
    content: none;
  }
  .ux-table tr:has(.ux-col-actions) .ux-col-select {
    right: calc(var(--actions) * 48px + 4px); /* checkbox na lewo od akcji, 4 px odstępu */
  }
  .ux-table tr:has(.ux-col-actions) td.ux-cell-main {
    padding-right: calc(var(--actions) * 48px + 8px);
  }
  .ux-table tr:has(.ux-col-actions):has(.ux-col-select) td.ux-cell-main {
    padding-right: calc(var(--actions) * 48px + 54px);
  }
  /* od TRZECIEJ akcji ikony schodzą pod treść karty (wiersz wyrównany do prawej), a róg zostaje dla checkboxa —
     4 ikony w rogu zostawiały tytułowi 28 px na 320 px (rev 26, I-1) */
  .ux-table tbody tr:has(td.ux-col-actions > :nth-child(3)) td.ux-col-actions {
    position: static; /* komórka akcji jest ostatnia w DOM, treść ma `order` ujemny — bez `order` */
    justify-content: flex-end;
    padding: 0 8px 4px;
  }
  .ux-table tbody tr:has(td.ux-col-actions > :nth-child(3)) .ux-col-select {
    right: 4px;
  }
  .ux-table tbody tr:has(td.ux-col-actions > :nth-child(3)) td.ux-cell-main {
    padding-right: 12px;
  }
  .ux-table tbody tr:has(td.ux-col-actions > :nth-child(3)):has(.ux-col-select) td.ux-cell-main {
    padding-right: 56px;
  }
  .ux-table td.ux-cell-main::before {
    content: none;
  }
  /* meta (np. data) pod tytułem, bez etykiety */
  .ux-table td.ux-cell-meta {
    order: -1; /* tuż pod tytułem, bez etykiety (uwaga właściciela 2026-09-27) */
    padding-top: 0;
    padding-bottom: 8px;
    color: var(--muted);
    font-size: 0.9rem;
  }
  .ux-table td.ux-cell-meta::before {
    content: none;
  }
  .ux-table .ux-col-select {
    position: absolute;
    top: 4px;
    right: 4px;
    width: auto;
    padding: 0;
  }
  .ux-table .ux-col-select::before {
    content: none;
  }
  /* nagłówek tabeli = pasek sortowania nad kartami (tylko kolumny sortowalne + „zaznacz wszystkie") */
  .ux-table thead {
    display: block;
  }
  .ux-table thead tr {
    position: static;
    display: flex;
    flex-direction: row; /* pasek chipów w wierszu — karty (`tbody tr`) są kolumną flex */
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 8px;
    margin: 0 0 8px;
    padding: 0;
    background: none;
    border: 0;
  }
  .ux-table th {
    display: inline-flex;
    align-items: center;
    padding: 0;
    border: 0;
    background: none;
  }
  .ux-table th:not(.ux-col-select):not(:has(.ux-sort)) {
    display: none;
  }
  .ux-table th.ux-col-select {
    position: static;
    width: auto;
  }
  .ux-table th .ux-sort {
    min-height: var(--tap);
    padding: 0 12px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface);
    color: var(--text);
  }
  .ux-table th .ux-sort.is-active {
    background: var(--accent-soft);
  }
}

/* --- lista: stronicowanie i pusty stan --- */
.ux-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 12px 0;
}
.ux-pagination .btn-quiet {
  margin: 0;
}
.ux-page-of {
  color: var(--muted);
  padding: 0 8px;
}
.ux-empty {
  padding: 32px 16px;
  text-align: center;
  background: var(--surface);
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  color: var(--muted);
}
.ux-empty-title {
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--text);
  margin: 0 0 4px;
}
.ux-loading {
  padding: 32px 16px;
  text-align: center;
  color: var(--muted);
  background: linear-gradient(90deg, var(--surface) 25%, var(--surface-2) 50%, var(--surface) 75%);
  background-size: 200% 100%;
  border-radius: var(--radius);
}
@media (prefers-reduced-motion: no-preference) {
  .ux-loading {
    animation: ux-shimmer 1.4s linear infinite;
  }
}
@keyframes ux-shimmer {
  to {
    background-position: -200% 0;
  }
}

/* --- rekord: pasek z powrotem i akcjami, zakładki --- */
.ux-record-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 0 0 8px;
}
.ux-record-bar .btn,
.ux-record-bar .btn-quiet {
  margin: 0;
}
.ux-back {
  flex: none;
}
.ux-record-title {
  flex: 1 1 200px;
  min-width: 0;
  margin: 0;
  font-size: 1.4rem;
  overflow-wrap: anywhere;
}
.ux-record-actions {
  display: flex;
  gap: 8px;
  margin-left: auto;
}
/* --- zakładki strony (2.13, UX-SYSTEM §12): jedno makro `page_tabs` dla stron i rekordu; pasek przewija się
   poziomo SAM na telefonie (strona nigdy), zakładka to link z podkreśleniem w kolorze świata, focus widoczny,
   kontrast AA z tych samych zmiennych w jasnym i ciemnym motywie. --- */
.ux-tabs {
  display: flex;
  flex-wrap: nowrap;
  gap: 4px;
  margin: 0 0 16px;
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  max-width: 100%;
}
.ux-tabs::-webkit-scrollbar {
  display: none;
}
/* od tabletu: pasek, który się nie mieści (9 zakładek Ustawień), zawija się w drugi rząd — żadna
   zakładka nie jest ukryta za krawędzią; przewijanie palcem tylko na telefonie */
@media (min-width: 640px) {
  .ux-tabs {
    flex-wrap: wrap;
    overflow-x: visible;
    scroll-snap-type: none;
  }
}
.ux-tab {
  display: inline-flex;
  align-items: center;
  flex: none;
  scroll-snap-align: start;
  min-height: var(--tap);
  padding: 0 14px;
  color: var(--muted);
  text-decoration: none;
  font-weight: 600;
  white-space: nowrap;
  border-bottom: 3px solid transparent;
  border-radius: var(--radius) var(--radius) 0 0;
  margin-bottom: -1px;
}
.ux-tab:hover {
  color: var(--text);
  background: var(--surface-2);
}
.ux-tab:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: -2px;
}
.ux-tab.is-active {
  color: var(--text);
  border-bottom-color: var(--accent);
}
.ux-tab.is-disabled {
  color: var(--muted);
  opacity: 0.6;
  cursor: not-allowed;
}
.ux-record-body {
  min-width: 0;
}

/* --- formularz: pole z pomocą i błędem inline --- */
.ux-form {
  max-width: 640px;
}
.ux-field {
  margin: 0 0 12px;
}
.ux-field small {
  display: block;
  margin-top: 4px;
}
.ux-field.has-error input,
.ux-field.has-error textarea,
.ux-field.has-error select {
  border-color: var(--danger);
}
.ux-field-error {
  margin: 6px 0 0;
  padding: 6px 10px;
}

/* --- potwierdzenie: natywny <dialog> --- */
.ux-dialog {
  width: min(480px, calc(100% - 32px));
  padding: 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25);
}
.ux-dialog::backdrop {
  background: rgba(0, 0, 0, 0.45);
}
.ux-dialog[open]:not(:modal) {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 40;
  margin: 0;
}
.ux-dialog h2 {
  margin: 0 0 8px;
}
.ux-dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 16px;
}
.ux-dialog-actions form {
  margin: 0;
}
.ux-dialog-actions button {
  margin: 0;
}

/* --- toast (znika sam po 6 s) i baner (zostaje, ma akcję) --- */
.ux-toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--tap) + 24px + env(safe-area-inset-bottom));
  z-index: 30;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: min(480px, calc(100% - 32px));
  padding: 10px 12px 10px 16px;
  background: var(--text);
  color: var(--bg);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
}
.ux-toast-close {
  min-height: var(--tap);
  min-width: var(--tap);
  padding: 0;
  margin: 0;
  background: transparent;
  color: inherit;
  border: 0;
  font-size: 1.3rem;
  line-height: 1;
}
@media (min-width: 640px) {
  .ux-toast {
    bottom: 24px;
  }
}
@media (prefers-reduced-motion: no-preference) {
  .ux-toast {
    animation: ux-toast-out 400ms ease 6s forwards;
  }
}
@keyframes ux-toast-out {
  to {
    opacity: 0;
    visibility: hidden;
  }
}
.ux-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 8px 0 12px;
  padding: 10px 12px;
  border-left: 4px solid var(--accent);
  border-radius: var(--radius);
  background: var(--accent-soft);
  color: var(--text);
}
.ux-banner.is-danger {
  border-left-color: var(--danger);
  background: var(--danger-soft);
  color: var(--danger);
}
.ux-banner form.inline {
  margin: 0 0 0 auto;
}
.ux-banner form.inline button {
  margin: 0;
}

/* --- karta KPI --- */
.ux-kpi-grid {
  display: grid;
  gap: 8px;
  grid-template-columns: repeat(auto-fit, minmax(90px, 1fr)); /* 3 równe ramki także na 320 px (1.7a, U6; rev 23, M-6) */
  margin: 8px 0 16px;
}
@media (max-width: 639.98px) {
  .ux-kpi {
    padding: 10px 10px;
  }
  .ux-kpi-value {
    font-size: 1.6rem;
  }
  .ux-kpi-label,
  .ux-kpi-delta {
    font-size: 0.85rem;
  }
}
.ux-kpi {
  padding: 12px 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.ux-kpi p {
  margin: 0;
}
.ux-kpi-value {
  font-size: 2rem;
  font-weight: 700;
  line-height: 1.1;
}
.ux-kpi.is-ok .ux-kpi-value {
  color: var(--link);
}
.ux-kpi.is-danger .ux-kpi-value {
  color: var(--danger);
}
.ux-kpi-label {
  color: var(--muted);
  font-weight: 500;
}
.ux-kpi-label a {
  color: inherit;
}
.ux-kpi-delta {
  font-size: 0.9rem;
  color: var(--muted);
  margin-top: 4px;
}

/* --- pigułki filtrów --- */
.ux-pills {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 8px 0;
  padding: 0;
}
.ux-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--tap);
  max-width: 100%;
  padding: 6px 14px;
  text-align: left;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text);
  text-decoration: none;
  font-weight: 500;
}
.ux-pill-clear {
  background: transparent;
  color: var(--link);
  border-style: dashed;
}

/* --- panel boczny: desktop kolumna po prawej, telefon cały ekran --- */
.ux-panel {
  position: fixed;
  top: var(--topbar-h);
  right: 0;
  bottom: 0;
  z-index: 25;
  width: min(420px, 100%);
  overflow-y: auto;
  background: var(--surface);
  border-left: 1px solid var(--border);
  box-shadow: -8px 0 24px rgba(0, 0, 0, 0.12);
}
.ux-panel-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
}
.ux-panel-bar h2 {
  flex: 1;
  margin: 0;
  font-size: 1.1rem;
}
.ux-panel-bar .btn-quiet {
  margin: 0;
  min-width: var(--tap);
}
.ux-panel-body {
  padding: 12px 16px;
}

/* --- dzwonek uwagi (szkielet) --- */
.ux-bell {
  position: relative;
  flex: none;
}
.ux-bell summary {
  list-style: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  min-width: var(--tap);
  min-height: var(--tap);
  border-radius: 999px;
  cursor: pointer;
  font-size: 1.2rem;
}
.ux-bell summary::-webkit-details-marker {
  display: none;
}
.ux-bell[open] summary,
.ux-bell summary:hover {
  background: var(--surface-2);
}
.ux-bell-count {
  position: absolute;
  top: 4px;
  right: 2px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--danger);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}
.ux-bell-panel {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 30;
  width: min(300px, calc(100vw - 24px));
  padding: 16px;
  background: var(--surface);
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
}
/* --- menu języka: flaga w nagłówku, rozwijana lista języków (1.7a, uwaga U8) --- */
.ux-lang {
  position: relative;
  flex: none;
}
.ux-lang summary {
  list-style: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--tap);
  min-height: var(--tap);
  border-radius: 999px;
  cursor: pointer;
}
.ux-lang summary::-webkit-details-marker {
  display: none;
}
.ux-lang[open] summary,
.ux-lang summary:hover {
  background: var(--surface-2);
}
.ux-flag {
  width: 24px;
  height: 16px;
  border-radius: 3px;
  border: 1px solid var(--border);
  object-fit: cover;
  flex: none;
}
.ux-lang-panel {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 30;
  min-width: 180px;
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
}
.ux-lang-panel form {
  margin: 0;
}
.ux-lang-item {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 10px;
  width: 100%;
  min-height: var(--tap);
  margin: 0;
  padding: 0 12px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-weight: 500;
  text-align: left;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}
.ux-lang-item:hover {
  background: var(--surface-2);
}
.ux-lang-item.is-active {
  background: var(--accent-soft);
  font-weight: 700;
}
main .ux-bell {
  display: inline-block;
  vertical-align: middle;
}
main .ux-bell-panel {
  right: auto;
  left: 0;
}

/* --- prompty (2.2): treść domyślna, diff i podgląd renderu --- */
.prompt-source,
.prompt-diff {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  padding: 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-size: 0.9rem;
}
/* 2.13: karta promptu — pigułki języka nad zakładkami treści, licznik znaków pod podglądem */
.prompt-langs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  margin: 0 0 8px;
}
.prompt-langs .ux-pill.is-active {
  font-weight: 700;
  background: var(--accent-soft);
}
.prompt-stats {
  display: block;
  margin: 4px 0 0;
}

/* 2.3: filtr statusów kolejki zadań (`/admin/jobs`) — rząd cichych przycisków, aktywny podświetlony */
.ux-status-links {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 8px;
}
.ux-status-links .is-active {
  background: var(--accent-soft);
  color: var(--accent-text);
}

/* 2.4 — /settings/telegram: dwie karty (Jarvis, Edith) w kolorach świata */
.telegram-cards { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.telegram-card { border: 1px solid var(--border); border-left: 4px solid var(--accent); border-radius: var(--radius); padding: 1rem; background: var(--surface); }
.telegram-card h2 { margin-top: 0; }
.telegram-status.is-paired strong { color: var(--accent); }
.telegram-status.is-error strong { color: var(--danger, #b00020); }
.telegram-actions { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.telegram-connect summary { cursor: pointer; font-weight: 600; min-height: 44px; display: flex; align-items: center; }

/* --- Silnik uwagi (2.5): lista pozycji `/attention`, `/attention/policies`; dzwonek z listą --- */
.attention-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.attention-item { border: 1px solid var(--border); border-radius: var(--radius); padding: 12px 16px; background: var(--surface); }
.attention-item.is-question { border-left: 4px solid var(--accent); }
.attention-item.is-reminder, .attention-item.is-ritual { border-left: 4px solid var(--muted); }
.attention-item-title { font-size: 1.05rem; margin: 0 0 4px; }
.attention-item-body { margin: 0 0 6px; white-space: pre-wrap; }
.attention-item-meta { margin: 0 0 8px; color: var(--muted); }
.attention-item-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.attention-item-actions form.inline { display: inline-flex; gap: 6px; align-items: center; }
.attention-snooze label { display: inline-flex; gap: 6px; align-items: center; }
.attention-policy-form label { display: inline-flex; gap: 6px; align-items: center; }
.attention-empty { color: var(--muted); }
.ux-bell-list { list-style: none; margin: 0 0 8px; padding: 0; display: grid; gap: 6px; }
.ux-bell-list a { display: block; }

/* 2.6: kod parowania urządzenia na /settings/devices — duży, z odstępem między znakami */
.devices-code code { font-size: 2rem; letter-spacing: 0.25em; padding: 0.25rem 0.5rem; }

/* 2.9: karta transkrypcji — tekst z zachowaniem łamania, segmenty z czasem, filtry stanu/źródła */
.transcript-text { white-space: pre-wrap; overflow-wrap: anywhere; font: inherit; margin: 0 0 12px; }
.transcript-segments { padding-left: 1.25rem; display: grid; gap: 4px; }
.transcript-time { font-variant-numeric: tabular-nums; color: var(--muted, inherit); margin-right: 0.5rem; }
.transcript-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 8px 0 12px; }
.transcripts-filters .ux-pill.is-active { font-weight: 600; }

/* 2.11: rekord błędu (/admin/logs/{id}) i rekord aktywności asystenta — lista pól i traceback */
.ux-fields { display: grid; grid-template-columns: minmax(8rem, max-content) 1fr; gap: 4px 16px; margin: 0 0 12px; }
.ux-fields dt { color: var(--muted, inherit); }
.ux-fields dd { margin: 0; overflow-wrap: anywhere; }
.error-message { font-weight: 600; overflow-wrap: anywhere; }
.error-traceback { white-space: pre-wrap; overflow-wrap: anywhere; font-size: 0.85rem; max-height: 60vh; overflow: auto; }
