/* ===== Reset & Base ===== */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

:root {
  /* --- Pact24 brand book (RGB values lifted from ci.pdf):
     brand-red:   #ED1C24  (CMYK 0,100,100,0  · RGB 237,28,36)
     brand-gray:  #808285  (CMYK 0,0,0,60     · RGB 128,130,133)
     brand-black: #231F20  (CMYK 0,0,0,100    · RGB 35,31,32)
     Everything below derives from those three.
     --blue is kept as a token name for back-compat; semantically it is the
     brand accent (red). --red stays as a deeper destructive/danger color so
     "delete" / "offline" doesn't collide with brand-primary chrome.
  */
  --font: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --bg: #FAFAFA;
  --text: #231F20;
  --text-secondary: #808285;
  --border: rgba(35, 31, 32, 0.09);
  --white: #ffffff;
  --black: #231F20;
  /* brand-primary (accent) */
  --brand-red: #ED1C24;
  --brand-red-dark: #C40F17;
  --brand-red-soft: #FCE4E5;
  --brand-gray: #808285;
  --brand-black: #231F20;
  /* legacy token aliases — code across the app references --blue for the
     accent color, so we keep the name and point it at brand-red. */
  --blue: #ED1C24;
  --blue-soft: #FCE4E5;
  /* status colors — green and yellow are needed for "online" / "warning"
     UX but aren't in the two-color brand. Picked muted neutrals so they
     read calm next to the brand red. */
  --green: #2E8456;
  --green-soft: #E4F0EA;
  --yellow: #CA8A04;
  --red: #A8362E;
  --gray-50: #F6F6F6;
  --gray-100: #F0F0F0;
  --gray-200: #E6E6E7;
  --gray-300: #C8C9CB;
  --radius: 14px;
  --radius-sm: 10px;
  --radius-full: 9999px;
  --shadow: 0 1px 0 rgba(35,31,32,0.02), 0 1px 2px rgba(35,31,32,0.04);
  --shadow-md: 0 1px 0 rgba(35,31,32,0.02), 0 8px 24px -12px rgba(35,31,32,0.12);
  --transition: 0.22s cubic-bezier(0.2, 0.7, 0.2, 1);
}

html {
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  min-height: 100vh;
}

a {
  color: var(--blue);
  text-decoration: none;
  transition: opacity var(--transition);
}
a:hover { opacity: 0.75; }

/* ===== App shell (sidebar + main) ===== */
.app {
  display: grid;
  grid-template-columns: 232px 1fr;
  min-height: 100vh;
}

@media (max-width: 880px) {
  .app { grid-template-columns: 1fr; }
}

/* ===== Sidebar ===== */
.sidebar {
  position: sticky;
  top: 0;
  height: 100vh;
  padding: 18px 14px 14px;
  background: var(--gray-100);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 4px;
  z-index: 50;
}

@media (max-width: 880px) {
  .sidebar { position: static; height: auto; }
}

.brand {
  display: flex;
  align-items: center;
  padding: 6px 10px 16px;
  color: var(--text);
  margin-top: 2px;
}
.brand:hover { opacity: 1; }

.brand__logo {
  height: 28px;
  width: auto;
  display: block;
  object-fit: contain;
  /* The master PNG ships with the brand gray + brand red baked in;
     no additional tint needed. */
}

.nav-section {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: 13.5px;
  font-weight: 500;
  transition: background var(--transition), color var(--transition);
}
.nav-item:hover {
  background: rgba(11, 11, 14, 0.045);
  opacity: 1;
}
.nav-item__icon {
  width: 18px;
  height: 18px;
  color: var(--text-secondary);
  flex-shrink: 0;
  transition: color var(--transition);
}
.nav-item:hover .nav-item__icon { color: var(--text); }

.nav-item--active {
  background: var(--white);
  color: var(--text);
  box-shadow: 0 0 0 1px var(--border) inset, 0 1px 2px rgba(11, 11, 14, 0.03);
}
.nav-item--active .nav-item__icon { color: var(--blue); }
.nav-item--active::before {
  content: "";
  position: absolute;
  left: -14px;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 18px;
  border-radius: 0 3px 3px 0;
  background: var(--blue);
}

.nav-count {
  margin-left: auto;
  font-size: 11px;
  font-weight: 500;
  color: var(--text-secondary);
  padding: 1px 7px;
  border-radius: var(--radius-full);
  background: rgba(35, 31, 32, 0.05);
  line-height: 1.4;
}
.nav-item--active .nav-count {
  background: var(--blue-soft);
  color: var(--brand-red);
}

.sidebar__spacer { flex: 1; }

/* user-card details/menu */
.sidebar__user {
  position: relative;
  margin-top: 4px;
}
.sidebar__user[open] > summary {
  background: var(--gray-200);
}

.sidebar__user-summary {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  background: rgba(11, 11, 14, 0.03);
  border: 1px solid var(--border);
  cursor: pointer;
  transition: background var(--transition);
  list-style: none;
}
.sidebar__user-summary::-webkit-details-marker { display: none; }
.sidebar__user-summary:hover { background: rgba(11, 11, 14, 0.06); }

.avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--blue), var(--brand-red-dark));
  color: var(--white);
  display: grid;
  place-items: center;
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.02em;
  flex-shrink: 0;
}

.sidebar__user-info {
  flex: 1;
  min-width: 0;
  line-height: 1.25;
}
.sidebar__user-name {
  font-size: 12.5px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sidebar__user-meta {
  font-size: 11px;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sidebar__user-chevron {
  color: var(--text-secondary);
  flex-shrink: 0;
  transition: transform var(--transition);
}
.sidebar__user[open] .sidebar__user-chevron {
  transform: rotate(180deg);
}

.sidebar__user-menu {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 0;
  right: 0;
  padding: 6px;
  background: var(--white);
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-md);
  display: flex;
  flex-direction: column;
  gap: 2px;
  z-index: 100;
}

.sidebar__user-menu-section {
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 4px;
}
.sidebar__user-menu-section:last-child {
  border-bottom: none;
  margin-bottom: 0;
}

.sidebar__user-menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  font-size: 13px;
  color: var(--text);
  border-radius: 8px;
  transition: background var(--transition);
}
.sidebar__user-menu-item:hover {
  background: var(--gray-100);
  opacity: 1;
}
.sidebar__user-menu-item--danger { color: var(--red); }
.sidebar__user-menu-item--danger:hover {
  background: rgba(168, 54, 46, 0.08);
}

.sidebar__user-menu-item svg {
  color: var(--text-secondary);
  flex-shrink: 0;
}
.sidebar__user-menu-item--danger svg { color: var(--red); }

/* admin company switcher inside the user menu */
.sidebar__user-menu .company-session-switcher {
  flex-direction: column;
  align-items: stretch !important;
  gap: 6px !important;
}
.sidebar__user-menu .company-session-switcher label {
  font-size: 10.5px !important;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-secondary) !important;
}
.sidebar__user-menu .nav-company-select {
  width: 100%;
  font-size: 12.5px;
  padding: 6px 8px;
}

/* ===== Settings sub-nav: keep .nav-link for /settings/* tabs ===== */
.nav-link {
  color: var(--text-secondary);
  font-size: 13px;
  font-weight: 500;
  padding: 6px 14px;
  border-radius: var(--radius-full);
  transition: all var(--transition);
}
.nav-link:hover {
  color: var(--text);
  background: var(--gray-200);
  opacity: 1;
}
.nav-link--active {
  color: var(--text);
  background: var(--gray-200);
}
.nav-link--icon {
  padding: 6px 10px;
  display: inline-flex;
  align-items: center;
}

/* ===== Per-row "Akcje" dropdown on the Devices index ===== */
.row-actions-menu {
  position: relative;
  display: inline-block;
}
.row-actions-menu > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.row-actions-menu > summary::-webkit-details-marker { display: none; }
.row-actions-menu[open] > summary {
  color: var(--text);
  background: var(--gray-200);
}
.row-actions-menu__panel {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  min-width: 220px;
  padding: 6px;
  background: var(--white);
  border-radius: var(--radius-sm);
  border: 1px solid var(--gray-200);
  box-shadow: var(--shadow-md);
  display: flex;
  flex-direction: column;
  gap: 2px;
  z-index: 100;
  text-align: left;
}
.row-actions-menu__item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 12px;
  font-size: 13px;
  color: var(--text);
  background: transparent;
  border: none;
  text-align: left;
  border-radius: 8px;
  cursor: pointer;
  transition: background var(--transition);
}
.row-actions-menu__item > svg { flex-shrink: 0; }
.row-actions-menu__item:hover:not(:disabled) {
  background: var(--gray-100);
  opacity: 1;
}
.row-actions-menu__item:disabled {
  color: var(--text-secondary);
  cursor: not-allowed;
  opacity: 0.6;
}
.row-actions-menu__item--danger {
  color: var(--red);
}
.row-actions-menu__item--danger:hover:not(:disabled) {
  background: rgba(168, 54, 46, 0.08);
  color: var(--red);
}

/* Inline icon-button cluster on campaigns table rows. Hidden by default;
   revealed on row hover or on keyboard focus inside the row. */
.row-actions-cluster {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  justify-content: flex-end;
  opacity: 0;
  transition: opacity var(--transition);
}
tr:hover .row-actions-cluster,
tr:focus-within .row-actions-cluster {
  opacity: 1;
}

/* Two-line table cell content: bold primary line + muted secondary line. */
.row-title {
  font-weight: 500;
  color: var(--text);
}
.row-sub {
  font-size: 12px;
  color: var(--text-secondary);
  margin-top: 2px;
}

/* Settings sub-nav (tabs under page header on /settings/* pages) */
.settings-tabs {
  display: flex;
  gap: 4px;
  margin-top: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--gray-200);
}

/* ===== Locale toggle ===== */
.locale-toggle {
  font-size: 11px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 6px;
  border: 1px solid var(--gray-300);
  color: var(--text-secondary);
  text-decoration: none;
  transition: all var(--transition);
  letter-spacing: 0.02em;
}
.locale-toggle:hover {
  background: var(--gray-100);
  color: var(--text);
  border-color: var(--gray-300);
  opacity: 1;
}

/* ===== Main Content ===== */
.main-content {
  max-width: 1200px;
  margin: 0 auto;
  padding: 32px 24px 64px;
}

/* Unauthenticated pages (login + password reset). Vertically stacks the
   brand logo, the form card, and any footer link with consistent gaps. */
.auth-shell {
  max-width: 440px;
  padding-top: 64px;
}

.auth-locale {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 24px;
}

.auth-brand {
  display: flex;
  justify-content: center;
  margin-bottom: 28px;
}
.auth-brand:hover { opacity: 1; }
.auth-brand__logo {
  height: 48px;
  width: auto;
  display: block;
}

.auth-card-wrap {
  max-width: 400px;
  margin: 0 auto;
}

.auth-title {
  text-align: center;
  font-size: 22px;
  font-weight: 500;
  letter-spacing: -0.015em;
  margin-bottom: 24px;
}

/* Wraps the topbar + scrolling main content so they share the same column. */
.main-col {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* Sticky topbar with breadcrumb (left), search placeholder + help (right). */
.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  height: 60px;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 48px;
  background: color-mix(in srgb, var(--bg) 80%, transparent);
  -webkit-backdrop-filter: saturate(140%) blur(14px);
  backdrop-filter: saturate(140%) blur(14px);
  border-bottom: 1px solid var(--border);
}
@media (max-width: 1100px) { .topbar { padding: 0 32px; } }
@media (max-width: 880px)  { .topbar { padding: 0 20px; } }

.crumb {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--text-secondary);
  min-width: 0;
}
.crumb__base    { color: var(--text-secondary); }
.crumb__sep     { color: var(--gray-300); display: inline-flex; flex-shrink: 0; }
.crumb__current { color: var(--text); font-weight: 500; }

.topbar__search {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  width: 280px;
  height: 34px;
  padding: 0 12px;
  border-radius: var(--radius-full);
  background: var(--gray-50);
  border: 1px solid var(--border);
  color: var(--text-secondary);
  font-size: 13px;
  cursor: text;
  transition: border-color var(--transition), background var(--transition);
}
.topbar__search:hover { border-color: var(--gray-300); }
.topbar__search { font: inherit; text-align: left; }
.topbar__search > svg { flex-shrink: 0; }
.topbar__search-placeholder {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.topbar__search kbd {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 10.5px;
  padding: 1.5px 6px;
  border-radius: 5px;
  background: var(--white);
  border: 1px solid var(--border);
  color: var(--text-secondary);
  flex-shrink: 0;
}

.topbar__icon-btn {
  width: 34px;
  height: 34px;
  border-radius: var(--radius-full);
  color: var(--text-secondary);
  display: grid;
  place-items: center;
  transition: background var(--transition), color var(--transition);
  text-decoration: none;
  flex-shrink: 0;
}
.topbar__icon-btn:hover {
  background: rgba(35, 31, 32, 0.05);
  color: var(--text);
  opacity: 1;
}

/* Notification bell — replaces the old mailto question icon in the
   topbar. The <details> shell is what makes click-to-toggle work
   without JS; the .topbar__bell-panel under it is absolutely
   positioned so it doesn't shift the topbar layout. */
.topbar__bell { position: relative; }
.topbar__bell-summary {
  list-style: none;
  cursor: pointer;
  position: relative;
}
.topbar__bell-summary::-webkit-details-marker,
.topbar__bell-summary::marker { display: none; }

.topbar__bell-badge {
  position: absolute;
  top: 2px;
  right: 2px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: var(--radius-full);
  background: #ED1C24; /* same red as the dot indicator on player offline */
  color: #fff;
  font-size: 10px;
  font-weight: 600;
  line-height: 16px;
  text-align: center;
}
.topbar__bell-badge--hidden { display: none; }

.topbar__bell-panel {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  width: 360px;
  max-width: calc(100vw - 24px);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.08);
  z-index: 50;
  overflow: hidden;
}
.topbar__bell-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}
.topbar__bell-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}
.topbar__bell-clear-btn,
.topbar__bell-clear-btn button {
  background: none;
  border: none;
  color: var(--text-secondary);
  font-size: 12px;
  cursor: pointer;
  padding: 0;
}
.topbar__bell-clear-btn:hover,
.topbar__bell-clear-btn button:hover { color: var(--text); }

.topbar__bell-list {
  max-height: 420px;
  overflow-y: auto;
}
.topbar__bell-empty {
  padding: 24px 12px;
  text-align: center;
  font-size: 13px;
  color: var(--text-secondary);
}

/* The row is a container <div> holding two sibling forms: the mark-read
   "main" button (icon + body) and the "remove" × button. The flex layout
   that used to live on the row itself now sits on the main button. */
.topbar__bell-row {
  display: flex;
  align-items: stretch;
  width: 100%;
  border-bottom: 1px solid var(--border);
}
.topbar__bell-row:hover { background: rgba(35,31,32,0.04); }
.topbar__bell-row--unread { background: rgba(237,28,36,0.04); }

.topbar__bell-row-main { flex: 1 1 auto; min-width: 0; display: flex; }
.topbar__bell-row-main button {
  display: flex;
  width: 100%;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  text-align: left;
  background: none;
  border: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
  text-decoration: none;
}

.topbar__bell-row-remove { flex: 0 0 auto; display: flex; }
.topbar__bell-row-remove button {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 10px;
  background: none;
  border: none;
  color: var(--text-secondary);
  cursor: pointer;
}
.topbar__bell-row-remove button:hover,
.topbar__bell-row-remove button:focus-visible { color: #ED1C24; }

.topbar__bell-row-icon { flex-shrink: 0; color: var(--text-secondary); margin-top: 2px; }
.topbar__bell-row-body { flex: 1; min-width: 0; }
.topbar__bell-row-title { font-size: 13px; font-weight: 500; color: var(--text); }
.topbar__bell-row-time  { font-size: 11px; color: var(--text-secondary); margin-top: 2px; }

@media (max-width: 880px) {
  .topbar__search { width: auto; flex: 1; }
  .topbar__search-placeholder { display: none; }
  .topbar__search kbd { display: none; }
}

/* Command palette (⌘K) — global search overlay. */
.cmdk {
  position: fixed;
  inset: 0;
  z-index: 9000;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding: 12vh 16px 16px;
  animation: cmdk-fade 140ms ease-out;
}
.cmdk[hidden] { display: none; }
.cmdk__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(35, 31, 32, 0.42);
  backdrop-filter: blur(2px);
}
.cmdk__panel {
  position: relative;
  width: min(640px, 100%);
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.22);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  max-height: 76vh;
}
.cmdk__input-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  color: var(--text-secondary);
}
.cmdk__input {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  font: inherit;
  font-size: 15px;
  color: var(--text);
}
.cmdk__close {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: var(--text-secondary);
}
.cmdk__close kbd {
  font-family: var(--font-mono);
  font-size: 10.5px;
  padding: 1.5px 6px;
  border-radius: 5px;
  background: var(--gray-50);
  border: 1px solid var(--border);
  color: var(--text-secondary);
}
.cmdk__results {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 6px 0;
}
.cmdk__group + .cmdk__group { border-top: 1px solid var(--border); }
.cmdk__group-label {
  padding: 10px 16px 4px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-secondary);
}
.cmdk__item {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 9px 16px;
  text-decoration: none;
  color: var(--text);
  font-size: 14px;
  transition: background var(--transition);
}
.cmdk__item:hover,
.cmdk__item[data-active] {
  background: var(--gray-50);
}
.cmdk__item-primary { font-weight: 500; }
.cmdk__item-secondary {
  margin-left: auto;
  color: var(--text-secondary);
  font-size: 12.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 55%;
}
.cmdk__empty {
  padding: 28px 16px;
  text-align: center;
  color: var(--text-secondary);
  font-size: 13px;
}
.cmdk__hint {
  padding: 8px 14px;
  border-top: 1px solid var(--border);
  font-size: 11.5px;
  color: var(--text-secondary);
  background: var(--gray-50);
}
body.cmdk-open { overflow: hidden; }

@keyframes cmdk-fade {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}

/* Main content area below the topbar. */
.main {
  min-width: 0;
  padding: 36px 48px 80px;
  max-width: 1240px;
  width: 100%;
  animation: page-rise 480ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

@media (max-width: 1100px) {
  .main { padding: 32px 32px 64px; }
}
@media (max-width: 880px) {
  .main { padding: 24px 20px 64px; }
}

@keyframes page-rise {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

/* ===== Typography ===== */
h1 {
  font-size: 32px;
  font-weight: 700;
  letter-spacing: -0.03em;
  margin-bottom: 8px;
}

h2 {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.02em;
  margin-top: 32px;
  margin-bottom: 12px;
}

h3 {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-bottom: 4px;
}

p { margin-bottom: 8px; }

small { font-size: 13px; color: var(--text-secondary); }

/* ===== Buttons ===== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-family: var(--font);
  font-size: 14px;
  font-weight: 500;
  padding: 10px 24px;
  border-radius: var(--radius-full);
  border: none;
  cursor: pointer;
  transition: all var(--transition);
  text-decoration: none;
  line-height: 1;
}

.btn--primary {
  background: var(--black);
  color: var(--white);
}
.btn--primary:hover {
  background: #333;
  opacity: 1;
}

.btn--secondary {
  background: var(--gray-200);
  color: var(--text);
}
.btn--secondary:hover {
  background: var(--gray-300);
  opacity: 1;
}

.btn--blue {
  background: var(--blue);
  color: var(--white);
}
.btn--blue:hover {
  background: var(--brand-red-dark);
  opacity: 1;
}

.btn--ghost {
  background: var(--gray-50);
  color: var(--text);
  border: 1px solid var(--border);
}
.btn--ghost > svg { color: var(--text-secondary); }
.btn--ghost:hover {
  background: var(--white);
  border-color: var(--gray-300);
  color: var(--text);
  opacity: 1;
}

.btn--danger {
  color: var(--red);
  background: transparent;
}
.btn--danger:hover {
  background: #fff5f5;
  opacity: 1;
}

.btn--sm {
  font-size: 12px;
  padding: 6px 14px;
}

/* Turbo submit spinner — applied automatically by Turbo during submission */
form.turbo-submitting button[type="submit"],
form[aria-busy="true"] button[type="submit"] {
  position: relative;
  color: transparent !important;
  pointer-events: none;
}
form.turbo-submitting button[type="submit"]::after,
form[aria-busy="true"] button[type="submit"]::after {
  content: "";
  position: absolute;
  width: 16px;
  height: 16px;
  top: 50%;
  left: 50%;
  margin: -8px 0 0 -8px;
  border: 2px solid rgba(255, 255, 255, 0.3);
  border-top-color: white;
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.btn__spinner {
  animation: spin 0.6s linear infinite;
  flex-shrink: 0;
}

.btn--disabled,
.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.6;
  cursor: not-allowed;
}

/* ===== Cards ===== */
.card {
  background: var(--white);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  padding: 20px;
  transition: box-shadow var(--transition);
}
.card:hover {
  box-shadow: var(--shadow-md);
}

.card--flat {
  box-shadow: none;
}
.card--flat:hover {
  box-shadow: none;
}

/* ===== Device Template Card (TV / Radio picker) ===== */
.device-template-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 28px 20px;
  cursor: pointer;
  text-align: center;
  color: var(--text-secondary);
  transition: box-shadow var(--transition), border-color var(--transition), color var(--transition), transform var(--transition);
}
.device-template-card:hover {
  color: var(--text);
  border-color: var(--gray-300);
  transform: translateY(-1px);
}
.device-template-card__input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  width: 0;
  height: 0;
}
.device-template-card__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 88px;
  height: 88px;
  border-radius: var(--radius);
  background: var(--gray-100);
  color: var(--text);
  transition: background var(--transition), color var(--transition);
}
.device-template-card:hover .device-template-card__icon {
  background: var(--gray-200);
}
.device-template-card__name {
  font-size: 17px;
  letter-spacing: -0.01em;
  color: var(--text);
}
.device-template-card:has(.device-template-card__input:checked) {
  border-color: var(--blue);
  box-shadow: 0 0 0 2px var(--blue) inset, var(--shadow-md);
  color: var(--text);
}
.device-template-card:has(.device-template-card__input:checked) .device-template-card__icon {
  background: var(--blue);
  color: var(--white);
}
.device-template-card__input:focus-visible + .device-template-card__icon {
  outline: 2px solid var(--blue);
  outline-offset: 3px;
}


/* ===== Grid ===== */
.grid {
  display: grid;
  gap: 16px;
}
.grid--2 { grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }

/* ===== Tables ===== */
.table-wrap {
  background: var(--white);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  /* Was `overflow: hidden`. Switched so action-icon tooltips popping above
     the first row aren't clipped by the wrap's rounded boundary. Cells
     have no border-radius of their own, so the visual rounded corners
     stay intact. */
  overflow: visible;
}

table {
  width: 100%;
  border-collapse: collapse;
}

th {
  text-align: left;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-secondary);
  padding: 12px 20px;
  border-bottom: 1px solid var(--border);
  background: var(--gray-50);
}

td {
  padding: 12px 16px;
  border-bottom: 1px solid var(--gray-200);
  font-size: 14px;
}

tr:last-child td {
  border-bottom: none;
}

tr:hover td {
  background: var(--gray-50);
}

/* ===== Priority Slider ===== */
input[type="number"].priority-slider__number {
  width: 48px;
  min-width: 48px;
  max-width: 48px;
  height: 32px;
  text-align: center;
  font-size: 16px;
  font-weight: 400;
  padding: 0 2px;
  border: 1px solid var(--gray-300);
  border-radius: 6px;
  font-family: var(--font);
  color: #000000;
  background: #ffffff;
  line-height: 32px;
  box-shadow: none;
  outline: none;
}
input[type="number"].priority-slider__number:focus {
  border-color: var(--gray-300);
  outline: none;
  box-shadow: none;
  color: #000000;
  background: #ffffff;
}
input[type="number"].priority-slider__number:active {
  outline: none;
  box-shadow: none;
}
/* Keep native stepper arrows visible */
input[type="number"].priority-slider__number::-webkit-inner-spin-button {
  -webkit-appearance: inner-spin-button;
  opacity: 1;
  height: 26px;
  cursor: pointer;
}

.priority-slider__header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}

.priority-slider__label {
  font-size: 14px;
  font-weight: 500;
}

.priority-slider__track-wrap {
  position: relative;
  height: 28px;
  display: flex;
  align-items: center;
}

.priority-slider__ramp-bg,
.priority-slider__ramp-fill {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: 14px;
  transform: translateY(-50%);
  border-radius: 3px;
  overflow: hidden;
  pointer-events: none;
}
.priority-slider__ramp-bg::before,
.priority-slider__ramp-fill::before {
  content: "";
  display: block;
  width: 100%;
  height: 100%;
  clip-path: polygon(0 90%, 100% 0, 100% 100%, 0 100%);
}
.priority-slider__ramp-bg::before {
  background: var(--gray-200);
}
.priority-slider__ramp-fill {
  z-index: 1;
  width: 50%;
}
.priority-slider__ramp-fill::before {
  background: var(--blue);
  opacity: 0.5;
}

.priority-slider__range {
  position: relative;
  width: 100%;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  margin: 0;
  height: 28px;
  cursor: pointer;
  z-index: 2;
  outline: none;
  border: none;
}
.priority-slider__range:focus {
  outline: none;
  box-shadow: none;
}

.priority-slider__range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--white);
  border: 2px solid var(--blue);
  box-shadow: 0 1px 3px rgba(0,0,0,0.12);
  cursor: grab;
}
.priority-slider__range:active::-webkit-slider-thumb {
  cursor: grabbing;
  background: var(--gray-50);
}

.priority-slider__range::-moz-range-thumb {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--white);
  border: 2px solid var(--blue);
  box-shadow: 0 1px 3px rgba(0,0,0,0.12);
  cursor: grab;
}
.priority-slider__range::-moz-range-track {
  background: transparent;
  border: none;
}
.priority-slider__range:focus::-moz-range-thumb {
  outline: none;
  box-shadow: 0 1px 3px rgba(0,0,0,0.12);
}

.priority-slider__labels {
  display: flex;
  justify-content: space-between;
  font-size: 10px;
  color: var(--gray-300);
  margin-top: -2px;
  line-height: 1;
}

/* ===== Location Picker ===== */
.loc-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}

.search-wrap {
  position: relative;
  max-width: 300px;
  flex: 1;
}
.search-wrap__input {
  width: 100%;
  padding-right: 30px;
}
.search-wrap__clear {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  width: 20px;
  height: 20px;
  border: none;
  background: var(--gray-200);
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
  padding: 0;
  transition: all var(--transition);
}
.search-wrap__clear:hover {
  background: var(--gray-300);
  color: var(--text);
}

.loc-toolbar__search {
  max-width: 300px;
  font-family: var(--font);
  font-size: 13px;
  padding: 6px 10px;
  border: 1px solid var(--gray-300);
  border-radius: 6px;
  background: var(--white);
  color: var(--text);
  outline: none;
}
.loc-toolbar__search:focus {
  border-color: var(--blue);
}
.loc-toolbar__search::placeholder {
  color: var(--gray-300);
}

.loc-toolbar__actions {
  display: flex;
  gap: 8px;
}

.loc-toolbar__link {
  font-family: var(--font);
  font-size: 12px;
  font-weight: 500;
  color: var(--blue);
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px 0;
  white-space: nowrap;
}
.loc-toolbar__link:hover {
  opacity: 0.7;
}

.loc-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 6px;
}

.loc-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border-radius: 4px;
  border: 1px solid var(--gray-200);
  cursor: pointer;
  transition: all var(--transition);
  background: var(--white);
}
.loc-item:hover {
  border-color: var(--gray-300);
  background: var(--gray-50);
}
.loc-item:has(.loc-item__check:checked) {
  background: rgba(237, 28, 36, 0.06);
  border-color: rgba(237, 28, 36, 0.25);
}
.loc-item:has(.loc-item__check:checked) .loc-item__name {
  color: var(--blue);
  font-weight: 500;
}

.loc-item__check {
  margin: 0;
  flex-shrink: 0;
}

.loc-item__name {
  font-size: 13px;
  font-weight: 400;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

/* ===== Device-kind scope cards (campaign form) ===== */
.scope-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}
.scope-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--gray-200);
  cursor: pointer;
  transition: all var(--transition);
  background: var(--white);
}
.scope-card:hover {
  border-color: var(--gray-300);
  background: var(--gray-50);
}
.scope-card:has(input:checked) {
  background: rgba(237, 28, 36, 0.06);
  border-color: rgba(237, 28, 36, 0.25);
}
.scope-card__head {
  display: flex;
  align-items: center;
  gap: 8px;
}
.scope-card__icon {
  color: var(--text-secondary);
  flex-shrink: 0;
}
/* The shared DEVICE_SCOPE_ICONS svgs carry only a viewBox (no width/height) so
   each call site sizes them; the form's scope cards render them at 24px. */
.scope-card__icon svg {
  width: 24px;
  height: 24px;
}
.scope-card:has(input:checked) .scope-card__icon,
.scope-card:has(input:checked) .scope-card__title {
  color: var(--brand-red);
}
.scope-card__title {
  font-weight: 500;
  color: var(--text);
}
.scope-card__help {
  font-size: 13px;
  color: var(--text-secondary);
  margin: 0;
}
@media (max-width: 640px) {
  .scope-grid { grid-template-columns: 1fr; }
}

/* ===== Location filters (campaign form) ===== */
.loc-filters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 12px 16px;
  margin-bottom: 16px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
}

.loc-filters__field {
  min-width: 0;
}

.loc-filters__label {
  display: block;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  margin-bottom: 4px;
}

.loc-filters__hint {
  display: block;
  margin-top: 4px;
  font-size: 11px;
  color: var(--text-secondary);
  line-height: 1.4;
}

/* ===== Tag select ===== */
.tag-select {
  position: relative;
  width: 100%;
}

.tag-select__box {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  min-height: 38px;
  padding: 4px 8px;
  border: 1px solid var(--gray-300);
  border-radius: 6px;
  background: var(--white);
  cursor: text;
  transition: border-color var(--transition);
}

.tag-select--open .tag-select__box {
  border-color: var(--blue);
}

.tag-select__pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 4px 2px 8px;
  background: #3b8bd5;
  color: var(--white);
  border-radius: 4px;
  font-size: 13px;
  line-height: 1.4;
}

.tag-select__pill-label {
  white-space: nowrap;
}

.tag-select__pill-x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border: none;
  background: rgba(255, 255, 255, 0.2);
  color: var(--white);
  border-radius: 3px;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  font-family: inherit;
}

.tag-select__pill-x:hover {
  background: rgba(255, 255, 255, 0.4);
}

.tag-select__input {
  flex: 1 1 120px;
  min-width: 120px;
  border: none !important;
  outline: none !important;
  font-size: 13px;
  font-family: var(--font);
  background: transparent;
  padding: 4px 0;
  color: var(--text);
  max-width: none !important;
  width: auto !important;
}

.tag-select__input::placeholder {
  color: var(--gray-300);
}

.tag-select__dropdown {
  position: absolute;
  top: calc(100% + 2px);
  left: 0;
  right: 0;
  z-index: 50;
  margin: 0;
  padding: 4px 0;
  list-style: none;
  background: var(--white);
  border: 1px solid var(--gray-300);
  border-radius: 6px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08);
  max-height: 240px;
  overflow-y: auto;
}

.tag-select__option {
  padding: 8px 14px;
  cursor: pointer;
  font-size: 13px;
  color: var(--text);
}

.tag-select__option:hover {
  background: rgba(237, 28, 36, 0.08);
}

.tag-select__empty {
  padding: 8px 14px;
  font-size: 13px;
  color: var(--text-secondary);
  cursor: default;
  list-style: none;
}

.tag-select__source {
  display: none;
}

/* ===== Forms ===== */
fieldset {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
  background: var(--white);
}

legend {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  padding: 0 8px;
}

label {
  font-size: 14px;
  font-weight: 500;
  color: var(--text);
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="number"],
input[type="date"],
input[type="time"],
input[type="url"],
input[type="search"],
select,
textarea {
  width: 100%;
  max-width: 400px;
  font-family: var(--font);
  font-size: 15px;
  padding: 10px 14px;
  border: 1px solid var(--gray-300);
  border-radius: var(--radius-sm);
  background: var(--white);
  color: var(--text);
  transition: border-color var(--transition), box-shadow var(--transition);
  outline: none;
}

input:focus, select:focus, textarea:focus {
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(237, 28, 36, 0.15);
}

input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--blue);
  margin-right: 6px;
  vertical-align: middle;
}

input[type="radio"] {
  accent-color: var(--blue);
  margin-right: 6px;
}

input[type="file"] {
  font-family: var(--font);
  font-size: 14px;
}

input[type="submit"] {
  font-family: var(--font);
  font-size: 14px;
  font-weight: 500;
  padding: 10px 24px;
  border-radius: var(--radius-full);
  border: none;
  background: var(--black);
  color: var(--white);
  cursor: pointer;
  transition: all var(--transition);
}
input[type="submit"]:hover {
  background: #333;
}

/* ===== Flash messages ===== */
.flash {
  padding: 12px 20px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  font-weight: 500;
  margin-bottom: 24px;
}

.flash--notice {
  background: #f0fdf4;
  color: #166534;
  border: 1px solid #bbf7d0;
}

.flash--alert {
  background: #fef2f2;
  color: #991b1b;
  border: 1px solid #fecaca;
}

/* ===== Status dots ===== */
.status-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 6px;
}
.status-dot--active { background: var(--green); }
.status-dot--pending { background: var(--yellow); }
.status-dot--draft { background: var(--gray-300); }
.status-dot--archived { background: var(--text-secondary); }

/* ===== Clock-skew badge (kiosk BIOS-battery health) ===== */
.clock-skew {
  display: inline-block;
  font-size: 0.8em;
  margin-top: 2px;
  padding: 1px 6px;
  border-radius: 4px;
  font-weight: 500;
}
.clock-skew--ok { background: #e6f4ea; color: #137333; }
.clock-skew--warning { background: #fef7e0; color: #7a5300; }
.clock-skew--danger { background: #fce8e6; color: #a50e0e; }

/* ===== Media grid ===== */
.media-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
  text-align: center;
  transition: all var(--transition);
}
.media-card:hover {
  box-shadow: var(--shadow-md);
}

.media-card img {
  max-width: 100%;
  height: auto;
  border-radius: var(--radius-sm);
  margin-bottom: 8px;
}

/* ===== File upload zone ===== */
.file-upload-zone {
  text-align: center;
  padding: 8px 0 4px;
}

.file-upload-zone__input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.file-upload-zone__label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 28px;
  border: 1.5px solid var(--black);
  border-radius: var(--radius-full);
  background: var(--white);
  color: var(--black);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: all var(--transition);
  -webkit-font-smoothing: antialiased;
}

.file-upload-zone__label:hover {
  background: var(--black);
  color: var(--white);
}

.file-upload-zone__label:hover .file-upload-zone__icon {
  color: var(--white);
}

.file-upload-zone__icon {
  display: flex;
  align-items: center;
  color: var(--black);
  transition: color var(--transition);
}

.file-upload-zone__text {
  line-height: 1;
}

.file-upload-zone__hint {
  margin-top: 10px;
  font-size: 13px;
  color: var(--text-secondary);
}

.file-upload-zone__input:focus + .file-upload-zone__label {
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(237, 28, 36, 0.15);
}

.file-upload-zone--dragover {
  background: rgba(237, 28, 36, 0.08);
  outline: 2px dashed var(--blue);
  outline-offset: -4px;
  border-radius: var(--radius-sm);
}

/* ===== Single-photo upload (location/device) ===== */
.photo-upload {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.photo-upload__preview {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 220px;
  max-height: 360px;
  border: 1.5px dashed var(--gray-200);
  border-radius: var(--radius-sm);
  background: var(--gray-50);
  color: var(--text-secondary);
  font-size: 13px;
  overflow: hidden;
}

.photo-upload__remove {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1px solid var(--gray-200);
  background: rgba(255, 255, 255, 0.92);
  color: var(--text-secondary);
  font-size: 20px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  text-decoration: none;
  transition: all var(--transition);
}

.photo-upload__remove:hover {
  background: #fee2e2;
  color: var(--red);
  border-color: #fecaca;
}

.photo-upload__preview--filled {
  border-style: solid;
  background: var(--white);
  padding: 0;
}

.photo-upload__preview img {
  display: block;
  max-width: 100%;
  max-height: 360px;
  object-fit: contain;
}

.photo-upload__placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 24px;
  text-align: center;
}

.photo-upload__placeholder-icon {
  color: var(--text-secondary);
  opacity: 0.6;
}

/* ===== Upload previews ===== */
.upload-previews {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 16px;
}

.upload-previews:empty {
  display: none;
}

.upload-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border: 1px solid var(--gray-200);
  border-radius: var(--radius-sm);
  background: var(--gray-50);
  transition: all var(--transition);
  position: relative;
}

.upload-card--completed {
  border-color: #bbf7d0;
  background: #f0fdf4;
}

.upload-card__thumb {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  overflow: hidden;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--gray-200);
}

.upload-card__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.upload-card__thumb--video {
  background: linear-gradient(135deg, #eff6ff, #dbeafe);
  color: #2563eb;
}

.upload-card__thumb--audio {
  background: linear-gradient(135deg, #faf5ff, #f3e8ff);
  color: #7c3aed;
}

.upload-card__info {
  flex: 1;
  min-width: 0;
}

.upload-card__name {
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.upload-card__size {
  font-size: 11px;
  color: var(--text-secondary);
  margin-bottom: 4px;
}

.upload-card__progress-wrap {
  height: 4px;
  border-radius: 2px;
  background: var(--gray-200);
  overflow: hidden;
}

.upload-card__progress-bar {
  height: 100%;
  width: 0%;
  background: var(--blue);
  border-radius: 2px;
  transition: width 0.15s ease;
}

.upload-card--completed .upload-card__progress-bar {
  background: var(--green);
}

.upload-card__status {
  font-size: 11px;
  color: var(--text-secondary);
  margin-top: 2px;
}

.upload-card__status--error {
  color: var(--red);
}

.upload-card__remove {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--text-secondary);
  font-size: 16px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: all var(--transition);
  font-family: var(--font);
}

.upload-card__remove:hover {
  background: #fee2e2;
  color: var(--red);
}

/* ===== Toast ===== */
.toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%) translateY(20px);
  background: var(--black);
  color: var(--white);
  padding: 12px 24px;
  border-radius: var(--radius-full);
  font-size: 14px;
  font-weight: 500;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
  z-index: 200;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease, transform 0.3s ease;
  -webkit-font-smoothing: antialiased;
}

.toast--visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  pointer-events: auto;
}

/* ===== Location Map ===== */
.location-map {
  height: 360px;
  margin-top: 16px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  overflow: hidden;
  box-shadow: var(--shadow-md);
}

/* ===== Locations Overview Map ===== */
.location-overview-map__card {
  padding: 0;
  overflow: hidden;
}

.location-overview-map {
  width: 100%;
  height: 420px;
  background: var(--bg);
}

@media (max-width: 768px) {
  .location-overview-map { height: 280px; }
}

.map-info {
  font-family: 'Geist', system-ui, sans-serif;
  font-size: 13px;
  line-height: 1.45;
  color: var(--text, #231f20);
  padding: 2px 4px 4px;
  min-width: 180px;
}

.map-info__title {
  display: block;
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 4px;
}

.map-info__address {
  color: var(--brand-gray);
  margin-bottom: 8px;
}

.map-info__link {
  display: inline-block;
  font-weight: 500;
  color: var(--brand-red);
  text-decoration: none;
}

.map-info__link:hover { text-decoration: underline; }

/* ===== File Manager ===== */
.fm__layout {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 24px;
  min-height: 500px;
}

@media (max-width: 768px) {
  .fm__layout { grid-template-columns: 1fr; }
}

.fm__sidebar {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.fm__sidebar-section {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.fm__sidebar-title {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-secondary);
  padding: 0 10px;
  margin-bottom: 4px;
}

.fm__sidebar-link {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  text-decoration: none;
  transition: background var(--transition);
}
.fm__sidebar-link:hover {
  background: var(--gray-100);
  opacity: 1;
}
.fm__sidebar-link--active {
  background: var(--gray-200);
}
.fm__sidebar-link svg {
  flex-shrink: 0;
  color: var(--text-secondary);
}
.fm__sidebar-link--active svg {
  color: var(--blue);
}

.fm__main {
  min-width: 0;
}

.fm__toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}

/* Bulk bar */
.fm__bulk-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 16px;
  margin-bottom: 16px;
  background: var(--brand-red-soft);
  border: 1px solid var(--brand-red);
  border-radius: var(--radius-sm);
}
.fm__bulk-text {
  font-size: 13px;
  color: var(--brand-red-dark);
}

/* File card */
.fm__file-card {
  position: relative;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  transition: all var(--transition);
}
.fm__file-card:hover {
  box-shadow: var(--shadow-md);
  border-color: var(--gray-300);
  transform: translateY(-1px);
}

.fm__file-check {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 2;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(255,255,255,0.9);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 3px rgba(0,0,0,0.15);
  opacity: 0;
  transition: opacity var(--transition);
}
.fm__file-card:hover .fm__file-check {
  opacity: 1;
}
.fm__file-check input {
  margin: 0;
  width: 14px;
  height: 14px;
}
/* Always show if checked */
.fm__file-check:has(input:checked) {
  opacity: 1;
}

.fm__file-thumb {
  width: 100%;
  aspect-ratio: 1;
  overflow: hidden;
  background: var(--gray-50);
}
.fm__file-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.fm__file-info {
  padding: 8px 10px;
}

.fm__file-name {
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: text;
  padding: 2px 0;
  border-radius: 3px;
  transition: background var(--transition);
}
.fm__file-name:hover {
  background: var(--gray-100);
}

.fm__file-meta {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 8px;
  align-items: center;
  margin-top: 4px;
  font-size: 11px;
  color: var(--text-secondary);
}

.fm__file-meta__badge {
  align-self: center;
}

.fm__file-meta__values {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.fm__file-meta__values > span {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fm__file-meta__status {
  margin-top: 2px;
}

.fm__file-actions {
  position: absolute;
  top: 8px;
  right: 8px;
  opacity: 0;
  transition: opacity var(--transition);
}
.fm__file-card:hover .fm__file-actions {
  opacity: 1;
}

/* Inline rename input */
.rename-input {
  font-family: var(--font);
  font-size: 12px;
  font-weight: 500;
  padding: 2px 4px;
  border: 1px solid var(--blue);
  border-radius: 4px;
  outline: none;
  width: 100%;
  box-shadow: 0 0 0 3px rgba(237, 28, 36, 0.15);
}

/* ===== Tabs ===== */
.tabs {
  display: flex;
  border-bottom: 1px solid var(--border);
  margin: -20px -20px 20px -20px;
  padding: 0 8px;
  gap: 0;
}

.tabs__tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 12px 18px;
  font-family: var(--font);
  font-size: 13px;
  font-weight: 500;
  color: var(--text-secondary);
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: 8px 8px 0 0;
  cursor: pointer;
  transition: all var(--transition);
  -webkit-font-smoothing: antialiased;
  position: relative;
  bottom: -1px;
}

.tabs__tab:hover {
  color: var(--text);
  background: var(--gray-50);
}

.tabs__tab--active {
  color: var(--text);
  background: var(--white);
  border-bottom-color: var(--blue);
}

.tabs__tab--active:hover {
  background: var(--white);
}

.tabs__tab svg {
  opacity: 0.5;
}
.tabs__tab--active svg {
  opacity: 1;
  color: var(--blue);
}

.tabs__panel {
  transition: opacity 0.2s ease;
}

.tabs__panel--visible {
  opacity: 1;
}

.tabs__panel--hidden {
  display: none;
  opacity: 0;
}

/* ===== File Browser ===== */
.browser__toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}

.browser__breadcrumbs {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  min-width: 0;
  overflow-x: auto;
}

.browser__crumb {
  color: var(--text-secondary);
  text-decoration: none;
  white-space: nowrap;
  padding: 2px 6px;
  border-radius: 4px;
  transition: all var(--transition);
}
.browser__crumb:hover {
  background: var(--gray-100);
  color: var(--text);
  opacity: 1;
}
.browser__crumb--active {
  color: var(--text);
  font-weight: 500;
}

.browser__crumb-sep {
  color: var(--gray-300);
  font-size: 12px;
}

/* Browser grid */
.browser__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 10px;
}

.browser__folder-card-wrap {
  position: relative;
}

.fm__folder-check {
  position: absolute;
  top: 6px;
  left: 6px;
  z-index: 2;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(255,255,255,0.9);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 3px rgba(0,0,0,0.15);
  opacity: 0;
  transition: opacity var(--transition);
}
.browser__folder-card-wrap:hover .fm__folder-check {
  opacity: 1;
}
.fm__folder-check:has(input:checked) {
  opacity: 1;
}
.fm__folder-check input {
  margin: 0;
  width: 14px;
  height: 14px;
}

.browser__folder-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 16px 8px 12px;
  border-radius: var(--radius);
  border: 1px solid transparent;
  text-decoration: none;
  color: var(--text);
  transition: all var(--transition);
  text-align: center;
}
.browser__folder-card:hover {
  background: var(--gray-100);
  border-color: var(--gray-200);
  opacity: 1;
}

.browser__folder-icon {
  color: #5A7BB0;
}

.browser__folder-name {
  font-size: 12px;
  font-weight: 500;
  line-height: 1.3;
  word-break: break-word;
}

.browser__folder-count {
  font-size: 11px;
  color: var(--text-secondary);
}

/* Browser list */
.browser__list {
  display: flex;
  flex-direction: column;
}

.browser__list-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 8px;
  transition: background var(--transition);
  text-decoration: none;
  color: var(--text);
  cursor: pointer;
}
.browser__list-row:hover {
  background: var(--gray-100);
  opacity: 1;
}

.browser__list-row--folder {
  font-weight: 500;
}

.browser__list-icon {
  flex-shrink: 0;
  width: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.browser__list-icon--folder {
  color: #5A7BB0;
}

.browser__list-name {
  flex: 1;
  font-size: 13px;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.browser__list-meta {
  font-size: 11px;
  color: var(--text-secondary);
  flex-shrink: 0;
}

.browser__list-check {
  flex-shrink: 0;
}

/* Browser empty */
.browser__empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 32px;
  color: var(--text-secondary);
  font-size: 13px;
}

/* ===== Selection Tray ===== */
.tray__list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.tray__item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 8px;
  background: var(--gray-50);
  transition: background var(--transition);
}
.tray__item:hover {
  background: var(--gray-100);
}

.tray__pos {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--gray-200);
  color: var(--text-secondary);
  font-size: 11px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.tray__name {
  flex: 1;
  font-size: 13px;
  font-weight: 500;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tray__actions {
  display: flex;
  gap: 2px;
  flex-shrink: 0;
  opacity: 0;
  transition: opacity var(--transition);
}
.tray__item:hover .tray__actions {
  opacity: 1;
}

.tray__btn {
  width: 24px;
  height: 24px;
  border: none;
  border-radius: 4px;
  background: transparent;
  color: var(--text-secondary);
  font-size: 10px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all var(--transition);
  font-family: var(--font);
}
.tray__btn:hover {
  background: var(--gray-200);
  color: var(--text);
}
.tray__btn--remove:hover {
  background: #fee2e2;
  color: var(--red);
}

/* ===== Badges ===== */
.badge {
  display: inline-block;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.05em;
  padding: 2px 6px;
  border-radius: 4px;
  text-transform: uppercase;
  -webkit-font-smoothing: antialiased;
}
.badge--green  { background: #dcfce7; color: #166534; }
.badge--blue   { background: #dbeafe; color: #1e40af; }
.badge--purple { background: #f3e8ff; color: #6b21a8; }
.badge--gray   { background: #e5e7eb; color: #374151; }
.badge--red    { background: #fee2e2; color: #991b1b; }

.media-picker__badge {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 1;
}

/* ===== Media preview (video) ===== */
.media-preview {
  position: relative;
  width: 100%;
  aspect-ratio: 1;
  overflow: hidden;
  border-radius: var(--radius-sm);
  background: #000;
}

.media-preview__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.media-preview__overlay {
  position: absolute;
  bottom: 6px;
  right: 6px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.4);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
}

.media-preview__duration {
  position: absolute;
  bottom: 6px;
  left: 6px;
  padding: 2px 6px;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.65);
  color: #fff;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.02em;
}

/* ===== Media placeholders ===== */
.media-placeholder {
  width: 100%;
  aspect-ratio: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: var(--gray-100);
  color: var(--text-secondary);
  border-radius: var(--radius-sm);
  font-size: 11px;
  font-weight: 500;
}

.media-placeholder--audio {
  background: linear-gradient(135deg, #faf5ff, #f3e8ff);
  color: #7c3aed;
}

.media-placeholder--video {
  background: linear-gradient(135deg, #eff6ff, #dbeafe);
  color: #2563eb;
}

/* Small fixed-size variant used by the campaign report row (helpers'
   medium_report_thumbnail dash fallback). Overrides the base 100%-of-
   container sizing with a 56x56 cell that matches .report-media__thumb. */
.media-placeholder--sm {
  width: 56px;
  height: 56px;
  aspect-ratio: unset;
  font-size: 18px;
  line-height: 1;
  gap: 0;
}

/* ===== Utilities ===== */
.flex { display: flex; }
.flex-wrap { flex-wrap: wrap; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-6 { gap: 6px; }
.gap-8 { gap: 8px; }
.gap-12 { gap: 12px; }
.gap-16 { gap: 16px; }
.gap-24 { gap: 24px; }
.mt-16 { margin-top: 16px; }
.mt-24 { margin-top: 24px; }
.mt-32 { margin-top: 32px; }
.mb-8 { margin-bottom: 8px; }
.mb-16 { margin-bottom: 16px; }
.mb-24 { margin-bottom: 24px; }
.text-right { text-align: right; }
.text-center { text-align: center; }
.text-secondary { color: var(--text-secondary); }
.text-sm { font-size: 13px; }

/* ===== Page header ===== */
.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 24px;
}
.page-header h1 { margin-bottom: 0; }

/* ===== Toolbar ===== */
.toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 24px;
  flex-wrap: wrap;
}
.toolbar__spacer { flex: 1; min-width: 0; }

/* ===== Filter pills (Filtry / Sortuj on campaigns toolbar) ===== */
.filter-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: var(--radius-full);
  border: 1px solid var(--border);
  background: var(--white);
  color: var(--text);
  font-size: 12.5px;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  list-style: none;
  transition: border-color var(--transition), background var(--transition);
}
.filter-pill::-webkit-details-marker { display: none; }
.filter-pill > svg { color: var(--text-secondary); flex-shrink: 0; }
.filter-pill > strong { font-weight: 500; color: var(--text); }
.filter-pill:hover { border-color: var(--gray-300); }
.filter-pill--active,
.filter-pill-menu[open] > .filter-pill {
  background: var(--gray-50);
  border-color: var(--gray-300);
}
.filter-pill__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: var(--radius-full);
  background: var(--brand-red);
  color: var(--white);
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 500;
  margin-left: 2px;
}

.filter-pill-menu {
  position: relative;
  display: inline-block;
}
.filter-pill-menu__panel {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  min-width: 240px;
  padding: 12px;
  background: var(--white);
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-md);
  z-index: 100;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.filter-pill-menu__panel--sort {
  min-width: 220px;
  padding: 6px;
  gap: 2px;
}

.filter-pill-menu__label {
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-secondary);
  padding: 4px 8px 2px;
}

.filter-pill-menu__input {
  width: 100%;
  max-width: none;
  padding: 8px 10px;
  font-size: 13px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.filter-pill-menu__input:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px var(--brand-red-soft);
}

.filter-pill-menu__form {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.filter-pill-menu__actions {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-top: 4px;
}

.filter-pill-menu__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 10px;
  font-size: 13px;
  color: var(--text);
  border-radius: 7px;
  transition: background var(--transition);
  text-decoration: none;
}
.filter-pill-menu__item:hover {
  background: var(--gray-100);
  opacity: 1;
}
.filter-pill-menu__item--active {
  color: var(--brand-red);
  font-weight: 500;
}
.filter-pill-menu__item--active svg { color: var(--brand-red); }

/* ===== Segmented Control ===== */
.segmented-control {
  display: inline-flex;
  background: var(--gray-200);
  border-radius: var(--radius-sm);
  padding: 3px;
  gap: 2px;
  margin-bottom: 24px;
}

.segmented-control__btn {
  font-family: var(--font);
  font-size: 13px;
  font-weight: 500;
  padding: 6px 14px;
  border-radius: 8px;
  color: var(--text-secondary);
  text-decoration: none;
  transition: all var(--transition);
  white-space: nowrap;
  -webkit-font-smoothing: antialiased;
}
.segmented-control__btn:hover {
  color: var(--text);
  opacity: 1;
}
.segmented-control__btn--active {
  background: var(--white);
  color: var(--text);
  box-shadow: 0 1px 3px rgba(0,0,0,0.08);
}
.segmented-control__btn--active:hover {
  opacity: 1;
}

/* ===== Segmented control — pill variant (campaigns index) =====
   Pill-shaped, hairline border, with inline monospace counts next to
   each label. Counts turn brand-red when the segment is active. */
.seg {
  display: inline-flex;
  padding: 3px;
  background: var(--gray-50);
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
}

.seg__btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 12px;
  border-radius: var(--radius-full);
  font-family: var(--font);
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text-secondary);
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--transition), color var(--transition);
  -webkit-font-smoothing: antialiased;
}
.seg__btn:hover {
  color: var(--text);
  opacity: 1;
}
.seg__btn--active {
  background: var(--white);
  color: var(--text);
  box-shadow: 0 1px 2px rgba(35, 31, 32, 0.06);
}
.seg__btn--active:hover {
  opacity: 1;
}

.seg__count {
  font-family: var(--font-mono);
  font-feature-settings: 'tnum';
  font-variant-numeric: tabular-nums;
  font-size: 10.5px;
  color: var(--text-secondary);
}
.seg__btn--active .seg__count {
  color: var(--brand-red);
}

/* ===== View Toggle ===== */
.view-toggle {
  display: inline-flex;
  background: var(--gray-200);
  border-radius: var(--radius-sm);
  padding: 3px;
  gap: 2px;
}

.view-toggle__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 30px;
  border-radius: 7px;
  color: var(--text-secondary);
  transition: all var(--transition);
  text-decoration: none;
}
.view-toggle__btn:hover {
  color: var(--text);
  opacity: 1;
}
.view-toggle__btn--active {
  background: var(--white);
  color: var(--text);
  box-shadow: 0 1px 3px rgba(0,0,0,0.08);
}
.view-toggle__btn--active:hover {
  opacity: 1;
}

/* ===== Table avatar ===== */
.table-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  object-fit: cover;
  display: block;
  border: 1px solid var(--gray-200);
}

.table-avatar--empty {
  background: var(--gray-100);
  display: flex;
  align-items: center;
  justify-content: center;
}

.table-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 6px;
  transition: all var(--transition);
  text-decoration: none;
}
.table-action {
  color: var(--text-secondary);
}
.table-action:hover {
  background: var(--gray-100);
  color: var(--text);
  opacity: 1;
}
/* Edit is a non-destructive action — keep it neutral so it doesn't
   visually compete with the brand-red Delete next to it. */
.table-action--edit {
  color: var(--text-secondary);
}
.table-action--edit:hover {
  background: var(--gray-100);
  color: var(--text);
}
/* Delete is destructive — use the loud brand red so the warning signal
   is unambiguous (matches the old behavior before the rebrand swap
   accidentally made Edit red and Delete muted). */
.table-action--delete {
  color: var(--brand-red);
}
.table-action--delete:hover {
  background: var(--brand-red-soft);
  color: var(--brand-red-dark);
}
.table-action--start {
  color: var(--green);
}
.table-action--start:hover {
  background: rgba(46, 132, 86, 0.1);
}
.table-action--pause {
  color: var(--yellow);
}
.table-action--pause:hover {
  background: rgba(202, 138, 4, 0.12);
}

/* CSS-only tooltip on .table-action[data-tooltip]. Renders the attribute
   text as a small dark chip above the icon, with a tiny arrow. ~400 ms
   reveal delay so accidental flyovers don't trigger; hide is immediate. */
.table-action[data-tooltip],
.device-scope-icon[data-tooltip] {
  position: relative;
}
.table-action[data-tooltip]::after,
.table-action[data-tooltip]::before,
.device-scope-icon[data-tooltip]::after,
.device-scope-icon[data-tooltip]::before {
  position: absolute;
  left: 50%;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.18s ease 0s;
}
.table-action[data-tooltip]::after,
.device-scope-icon[data-tooltip]::after {
  content: attr(data-tooltip);
  bottom: calc(100% + 6px);
  transform: translateX(-50%);
  padding: 5px 9px;
  background: var(--text);
  color: var(--bg);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: -0.005em;
  white-space: nowrap;
  border-radius: 6px;
  box-shadow: var(--shadow-md);
  z-index: 100;
}
.table-action[data-tooltip]::before,
.device-scope-icon[data-tooltip]::before {
  content: "";
  bottom: calc(100% + 2px);
  transform: translateX(-50%);
  border: 4px solid transparent;
  border-top-color: var(--text);
}
.table-action[data-tooltip]:hover::after,
.table-action[data-tooltip]:hover::before,
.table-action[data-tooltip]:focus-visible::after,
.table-action[data-tooltip]:focus-visible::before,
.device-scope-icon[data-tooltip]:hover::after,
.device-scope-icon[data-tooltip]:hover::before,
.device-scope-icon[data-tooltip]:focus-visible::after,
.device-scope-icon[data-tooltip]:focus-visible::before {
  opacity: 1;
  transition-delay: 0.4s;
}

/* Single device-kind-scope icon shown in the campaigns list "Urządzenia"
   column. Sizes the shared 24px scope SVG down to row scale. */
.device-scope-icon {
  display: inline-flex;
  align-items: center;
  color: var(--text-secondary);
}
.device-scope-icon svg {
  width: 18px;
  height: 18px;
}

.btn--outline-success {
  background: transparent;
  color: var(--green);
  border: 1px solid var(--green);
}
.btn--outline-success:hover {
  background: rgba(46, 132, 86, 0.08);
  opacity: 1;
}

.btn--outline-warning {
  background: transparent;
  color: var(--yellow);
  border: 1px solid var(--yellow);
}
.btn--outline-warning:hover {
  background: rgba(255, 159, 10, 0.08);
  opacity: 1;
}

/* ===== Empty state ===== */
.empty-state {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 60px 24px;
  text-align: center;
}

.empty-state__icon {
  font-size: 48px;
  margin-bottom: 16px;
  opacity: 0.3;
  line-height: 1;
}

.empty-state__text {
  color: var(--text-secondary);
  font-size: 16px;
  margin-bottom: 20px;
}

.empty-state__action {
  margin-bottom: 0;
}

/* ===== Sort chevron ===== */
.sort-chevron {
  vertical-align: middle;
  margin-left: 2px;
}

/* ===== Sort links ===== */
.sort-link {
  color: var(--text-secondary);
  text-decoration: none;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  transition: color var(--transition);
}
.sort-link:hover {
  color: var(--text);
  opacity: 1;
}
.sort-link--active {
  color: var(--text);
}

/* ===== Pills ===== */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  font-weight: 400;
  padding: 3px 10px 3px 8px;
  border-radius: var(--radius-full);
  letter-spacing: 0;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.pill--green  { background: var(--green-soft); color: var(--green); }
.pill--yellow { background: #F6EEDA; color: #CA8A04; }
.pill--gray   { background: var(--gray-200); color: var(--text-secondary); }
.pill--red    { background: #F6E4E1; color: #A8362E; }
.pill--rose   { background: #F6E4E1; color: #A8362E; }
.pill--blue   { background: #E6ECF6; color: #2A5DB0; }

.pill .status-dot { margin-right: 0; }

.status-dot--scheduled { background: #2A5DB0; }
.status-dot--expired   { background: #A8362E; opacity: 0.8; }

/* ===== Stat cards ===== */
.stat-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  padding: 20px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  text-decoration: none;
  color: var(--text);
  transition: all var(--transition);
  cursor: pointer;
}
.stat-card:hover {
  box-shadow: var(--shadow-md);
  border-color: var(--gray-300);
  transform: translateY(-1px);
  opacity: 1;
}

.stat-card__icon {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 4px;
}
.stat-card--draft .stat-card__icon {
  background: rgba(237, 28, 36, 0.08);
  color: var(--blue);
}
.stat-card--active .stat-card__icon {
  background: rgba(46, 132, 86, 0.08);
  color: var(--green);
}
.stat-card--paused .stat-card__icon {
  background: rgba(255, 159, 10, 0.08);
  color: var(--yellow);
}
.stat-card--locations .stat-card__icon {
  background: rgba(237, 28, 36, 0.08);
  color: var(--blue);
}
.stat-card--online .stat-card__icon {
  background: rgba(46, 132, 86, 0.08);
  color: var(--green);
}
.stat-card--offline .stat-card__icon {
  background: rgba(255, 59, 48, 0.08);
  color: var(--red);
}

/* Per-device-kind icon tints. iOS system-palette picks (purple/cyan/orange)
   that don't collide with the existing semantic colours: blue=locations/
   drafts, green=online/active, red=offline, yellow=paused. */
.stat-card--device-player .stat-card__icon {
  background: rgba(175, 82, 222, 0.08);
  color: #af52de;
}
.stat-card--device-radio .stat-card__icon {
  background: rgba(90, 200, 250, 0.08);
  color: #5ac8fa;
}
.stat-card--device-receipt_screen .stat-card__icon {
  background: rgba(255, 149, 0, 0.08);
  color: #ff9500;
}

/* Inert stat cards have no link target — the dashboard's device-kind
   sections render as <div>, not <a>, because there's no global devices
   index page to navigate to. Cancels the hover lift + pointer cursor
   so the user doesn't expect a click target. Card chrome (padding,
   border, icon tint, typography) stays identical to the link cards. */
.stat-card--inert {
  cursor: default;
}
.stat-card--inert:hover {
  box-shadow: none;
  border-color: var(--border);
  transform: none;
}

.stat-card__value {
  font-size: 32px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1;
}

.stat-card__label {
  font-size: 13px;
  color: var(--text-secondary);
  font-weight: 500;
}

/* ===== Location card ===== */
.location-card {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.location-card__header {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}

.location-card__icon {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-sm);
  background: var(--gray-100);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 18px;
}

.location-card__devices {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.device-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid var(--gray-200);
}
.device-row:last-child { border-bottom: none; }

/* ===== Campaign card ===== */
.campaign-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  height: 100%;
}

.campaign-card__actions {
  margin-top: auto;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding-top: 8px;
}

.campaign-card__top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}

.campaign-card__meta {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
}

.campaign-card__meta-item {
  font-size: 13px;
  color: var(--text-secondary);
}
.campaign-card__meta-item strong {
  color: var(--text);
}

.campaign-card__locations {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.location-tag {
  font-size: 11px;
  font-weight: 500;
  padding: 2px 8px;
  border-radius: var(--radius-full);
  background: var(--gray-100);
  color: var(--text-secondary);
  border: 1px solid var(--gray-200);
}

/* ===== Form sections ===== */
.form-section {
  margin-bottom: 40px;
}

.form-section__title {
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin-bottom: 6px;
}

.form-section__subtitle {
  font-size: 14px;
  color: var(--text-secondary);
  margin-bottom: 20px;
}

/* ===== Media picker ===== */
.media-picker {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 12px;
}

.media-picker__item {
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  border: 2px solid transparent;
  transition: all var(--transition);
  cursor: pointer;
  background: var(--white);
}

.media-picker__item:hover {
  box-shadow: var(--shadow-md);
}

.media-picker__item--selected {
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(237, 28, 36, 0.15);
}

.media-picker__thumb {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  display: block;
  background: var(--gray-100);
}

.media-picker__placeholder {
  width: 100%;
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--gray-100);
  color: var(--text-secondary);
  font-size: 12px;
}

.media-picker__check {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(255,255,255,0.9);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 3px rgba(0,0,0,0.15);
}

.media-picker__check input[type="checkbox"] {
  margin: 0;
  width: 14px;
  height: 14px;
}

.media-picker__label {
  padding: 8px 10px;
  font-size: 12px;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ===== Assigned media (edit view) ===== */
.assigned-media {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 12px;
}

.assigned-media__item {
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--white);
  border: 1px solid var(--border);
  transition: all var(--transition);
}
.assigned-media__item:hover { box-shadow: var(--shadow-md); }

.assigned-media__thumb {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  display: block;
}

.assigned-media__info {
  padding: 8px 10px;
}

.assigned-media__thumb-wrap {
  position: relative;
}

.assigned-media__download {
  position: absolute;
  right: 6px;
  bottom: 6px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.55);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  opacity: 0;
  transition: opacity var(--transition), background var(--transition);
  z-index: 2;
}
.assigned-media__item:hover .assigned-media__download {
  opacity: 1;
}
.assigned-media__download:hover {
  background: rgba(0, 0, 0, 0.8);
}

.assigned-media__remove {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: rgba(0,0,0,0.5);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  text-decoration: none;
  opacity: 0;
  transition: opacity var(--transition);
  line-height: 1;
  z-index: 3;
}
.assigned-media__item:hover .assigned-media__remove {
  opacity: 1;
}
.assigned-media__remove:hover {
  background: var(--red);
  opacity: 1;
}

.status-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin-right: 8px;
  vertical-align: middle;
  flex-shrink: 0;
}
.status-dot--online  { background-color: #28a745; }
.status-dot--warning { background-color: #f0ad4e; }
.status-dot--offline { background-color: #dc3545; }

/* Per-kind device glyph cluster on the locations grid card + table. The glyph
   inherits its colour from .dev-glyph--<status>; the count badge sits over the
   icon's top-right corner and tints to match via currentColor. */
.dev-cluster { display: inline-flex; align-items: center; gap: 6px; }
.dev-glyph { position: relative; display: inline-flex; line-height: 0; }
.dev-glyph--healthy { color: #28a745; }
.dev-glyph--warning { color: #f0ad4e; }
.dev-glyph--offline { color: #dc3545; }
.dev-glyph__count {
  position: absolute;
  top: -5px;
  right: -7px;
  min-width: 14px;
  height: 14px;
  padding: 0 3px;
  border-radius: 999px;
  background: currentColor;
  color: #fff;
  font-size: 10px;
  font-weight: 600;
  line-height: 14px;
  text-align: center;
}

.devices-filters {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 16px;
}
.devices-filters__row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.devices-filters__label {
  font-size: 0.85em;
  color: var(--text-secondary);
  min-width: 88px;
}

.badge--default-always {
  display: inline-block;
  padding: 2px 8px;
  font-size: 0.75em;
  font-weight: 600;
  border-radius: 4px;
  background-color: #dbeafe;
  color: #1e40af;
}
.badge--default-fallback {
  display: inline-block;
  padding: 2px 8px;
  font-size: 0.75em;
  font-weight: 600;
  border-radius: 4px;
  background-color: #fef3c7;
  color: #92400e;
}

/* ===== Device preview ===== */
.preview-stage {
  position: relative;
  min-height: 80vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 24px;
  padding: 40px 20px;
  isolation: isolate;
}
.preview-stage::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at center, #1a1f2c 0%, #0a0d14 100%);
  filter: blur(40px);
  opacity: 0.55;
  z-index: -1;
}

.preview-device-name {
  margin: 0;
  font-size: 28px;
  font-weight: 600;
  color: var(--text);
  text-align: center;
}

.preview-tv {
  position: relative;
  width: min(80vw, 960px);
  aspect-ratio: 16 / 9;
}
/* Totem (portrait): flip the bezel to a vertical 9:16 frame, narrow it to fit
   the stage height, and move the speaker out of the now-tall right edge. */
.preview-tv--portrait {
  width: auto;
  height: min(70vh, 640px);
  aspect-ratio: 9 / 16;
}
.preview-tv--portrait .preview-speaker {
  right: auto;
  left: 12px;
}
.preview-tv__bezel {
  position: absolute;
  inset: 0;
  background: #0a0a0a;
  border-radius: 18px;
  padding: 14px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4), inset 0 2px 6px rgba(255, 255, 255, 0.08);
}
.preview-tv__screen {
  position: absolute;
  inset: 14px;
  background: #000;
  border-radius: 6px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(255, 255, 255, 0.65);
  font-size: 14px;
}
.preview-tv__screen img,
.preview-tv__screen video {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.preview-radio {
  width: min(60vw, 640px);
  aspect-ratio: 2 / 1;
  background: #0a0a0a;
  border-radius: 24px;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);
}
.preview-radio__waveform {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  width: 72%;
  height: 55%;
}

.preview-radio__bar {
  flex: 1 1 4px;
  max-width: 6px;
  min-width: 3px;
  height: 100%;
  background: var(--blue);
  transform-origin: center;
  transform: scaleY(0.9);
  opacity: 0.85;
  border-radius: 2px;
}

.preview-radio--playing .preview-radio__bar {
  animation: preview-radio-wave var(--duration, 1000ms) ease-in-out infinite;
  animation-delay: var(--delay, 0ms);
}

@keyframes preview-radio-wave {
  0%, 100% { transform: scaleY(0.9); }
  25%      { transform: scaleY(0.25); }
  50%      { transform: scaleY(1); }
  75%      { transform: scaleY(0.45); }
}

@media (prefers-reduced-motion: reduce) {
  .preview-radio--playing .preview-radio__bar {
    animation: none;
  }
}

.preview-speaker {
  position: absolute;
  right: 16px;
  bottom: 16px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.15);
  color: white;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--transition);
  backdrop-filter: blur(8px);
  z-index: 2;
}
.preview-speaker:hover { background: rgba(255, 255, 255, 0.28); }
.preview-speaker--unmuted { background: var(--blue); }

.preview-caption {
  text-align: center;
  color: var(--text);
}
.preview-location-name {
  font-size: 18px;
  font-weight: 500;
}
.preview-location-address {
  font-size: 14px;
  color: #3a3a3f;
}

.preview-empty {
  color: rgba(255, 255, 255, 0.65);
  font-size: 14px;
}

.preview-campaigns-wrap {
  margin-top: 4px;
  text-align: center;
  max-width: 540px;
}
.preview-campaigns-title {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #3a3a3f;
  margin-bottom: 6px;
}
.preview-campaigns {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 8px;
  justify-content: center;
}
.preview-campaign {
  font-size: 13px;
  padding: 4px 10px;
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.5);
  color: #3a3a3f;
  border: 1px solid rgba(0, 0, 0, 0.08);
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.preview-campaign--active {
  background: var(--blue);
  color: white;
  border-color: var(--blue);
  font-weight: 500;
}

/* ===== Scale preview (tabbed, per display mode) ===== */
.scale-preview-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 16px;
}
.scale-preview-tab {
  font-size: 14px;
  padding: 6px 14px;
  border-radius: var(--radius-full);
  background: rgba(0, 0, 0, 0.04);
  color: var(--text-secondary, #555);
  border: 1px solid rgba(0, 0, 0, 0.08);
  cursor: pointer;
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.scale-preview-tab--active {
  background: var(--blue);
  color: white;
  border-color: var(--blue);
  font-weight: 500;
}
.scale-preview-stage {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  max-width: 520px;
  margin: 0 auto;
  aspect-ratio: 16 / 10;
  background: radial-gradient(ellipse at center, #1a1f2c 0%, #0a0d14 100%);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.scale-preview-stage img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}
.scale-preview-empty {
  color: #6b7280;
  font-size: 14px;
  padding: 24px;
  text-align: center;
}
.scale-preview-dims {
  text-align: center;
  margin: 8px 0 0;
}
.scale-preview-caption {
  text-align: center;
  margin: 4px 0 0;
  font-size: 15px;
  font-weight: 500;
  color: var(--blue);
}

.preview-close {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.75);
  color: #1d1d1f;
  text-decoration: none;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.15);
  backdrop-filter: blur(8px);
  transition: background var(--transition), transform var(--transition);
  z-index: 3;
}
.preview-close:hover {
  background: rgba(255, 255, 255, 0.95);
  transform: scale(1.05);
}
.preview-audio-placeholder,
.preview-unknown {
  color: rgba(255, 255, 255, 0.85);
  font-size: 14px;
  padding: 24px;
  text-align: center;
}

/* ----- Cashregister kiosk preview ---------------------------------------
 * Sister to .preview-tv. Renders a mini-kiosk: TV stage on the left,
 * themed receipt pane on the right, operator-driven state controls below.
 * The pane reuses the live cashregister CSS (.receipt-lines, .receipt-line,
 * .receipt-running-total, .receipt-summary*) so the visual treatment stays
 * locked to production. Theme variables (--theme-bg/-fg/-accent,
 * --theme-summary-bg/-fg) are set by cashregister_preview_controller on
 * the root element.
 */
.preview-cashregister {
  --theme-bg: #ffffff;
  --theme-fg: #1f1f1f;
  --theme-accent: #0a6cff;
  --theme-summary-bg: #0a6cff;
  --theme-summary-fg: #ffffff;
  position: relative;
  width: min(95vw, 1200px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.preview-cashregister__chassis {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  display: flex;
  background: #0a0a0a;
  border-radius: 18px;
  padding: 14px;
  box-shadow:
    0 20px 60px rgba(0, 0, 0, 0.4),
    inset 0 2px 6px rgba(255, 255, 255, 0.08);
  overflow: hidden;
}

.preview-cashregister__tv {
  position: relative;
  background: #000;
  border-radius: 6px;
  overflow: hidden;
  flex-basis: calc(100% - var(--receipt-basis, 50%));
  flex-grow: 0;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: flex-basis 400ms ease;
}
/* Margin between TV and receipt only when the receipt pane is visible —
   in FULLSCREEN the receipt collapses to 0% and a constant right-margin
   would leave a stripe of bezel showing. */
.preview-cashregister:not([data-mode="fullscreen"]) .preview-cashregister__tv {
  margin-right: 6px;
}
.preview-cashregister__tv .preview-tv__screen {
  position: absolute;
  inset: 0;
  background: #000;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(255, 255, 255, 0.65);
  font-size: 14px;
  overflow: hidden;
}
.preview-cashregister__tv .preview-tv__screen img,
.preview-cashregister__tv .preview-tv__screen video {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.preview-cashregister__receipt {
  position: relative;
  background: var(--theme-bg);
  color: var(--theme-fg);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: 6px;
  flex-basis: var(--receipt-basis, 50%);
  flex-grow: 0;
  flex-shrink: 0;
  transition: flex-basis 400ms ease;
}

/* State control bar — three pill buttons below the chassis. */
.preview-state-controls {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: center;
}
.preview-state-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  border-radius: var(--radius-full);
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.85);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  backdrop-filter: blur(8px);
  transition: background var(--transition), color var(--transition), border-color var(--transition), transform var(--transition);
}
.preview-state-btn:hover {
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
}
.preview-state-btn[aria-pressed="true"] {
  background: var(--blue);
  border-color: var(--blue);
  color: #fff;
  box-shadow: 0 6px 18px -8px rgba(10, 108, 255, 0.6);
}
.preview-state-btn__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.7;
}
.preview-state-btn[aria-pressed="true"] .preview-state-btn__dot {
  opacity: 1;
}

/* ===== Cashregister (Ekran z paragonem) ===== */
/*
 * Theme palette is written by receipt_controller as CSS variables on the
 * --theme-* root. Defaults below match ReceiptTheme.fetch("standard") so a
 * theme-less mount still renders sensibly.
 */
.cashregister {
  --theme-bg: #ffffff;
  --theme-fg: #1f1f1f;
  --theme-accent: #0a6cff;
  --theme-summary-bg: #0a6cff;
  --theme-summary-fg: #ffffff;
  display: flex;
  position: relative;
  width: 100vw;
  height: 100vh;
  background: #000;
  font-family: var(--font);
  cursor: none;
}
.cashregister__tv {
  position: relative;
  background: #000;
  /* --receipt-basis is owned by receipt_controller: set inline on the
     .cashregister root (boot value 0% = FULLSCREEN), and toggled by the
     state machine on every mode change. A [data-mode="fullscreen"] CSS
     rule here can't override the variable because inline styles on the
     same element win on specificity. */
  flex-basis: calc(100% - var(--receipt-basis, 50%));
  flex-grow: 0;
  flex-shrink: 0;
  transition: flex-basis 400ms ease;
}
.cashregister__receipt {
  position: relative;
  background: var(--theme-bg);
  color: var(--theme-fg);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  flex-basis: var(--receipt-basis, 50%);
  flex-grow: 0;
  flex-shrink: 0;
  transition: flex-basis 400ms ease;
}
.receipt-lines {
  list-style: none;
  margin: 0;
  padding: 24px;
  flex: 1;
  /* Stays scrollable so receipt_controller.renderLines can pin the latest
     line into view via scrollTop = scrollHeight; the scrollbar gutter is
     hidden below so the customer never sees it. */
  overflow-y: auto;
  scrollbar-width: none; /* Firefox + standard */
  font-size: 1.25rem;
}
.receipt-lines::-webkit-scrollbar { /* Chromium / Iron */
  width: 0;
  height: 0;
}
.receipt-line {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 12px;
  padding: 6px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--theme-fg) 12%, transparent);
}
.receipt-line__qty   { font-variant-numeric: tabular-nums; opacity: 0.7; }
.receipt-line__name  { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.receipt-line__total { font-variant-numeric: tabular-nums; font-weight: 600; }

/* Promo signals — applied when the pos-agent matcher flags a line. */
.receipt-line[data-promo="matched"] .receipt-line__qty {
  /* Left-edge accent so the customer scans which lines are "in the promo"
     at a glance even when the inline badge gets text-overflow-clipped. */
  box-shadow: -3px 0 0 0 color-mix(in srgb, var(--theme-accent, #1f7a3a) 75%, transparent);
}
.receipt-line__badge {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--theme-accent, #1f7a3a) 18%, var(--theme-bg, #fff));
  color: color-mix(in srgb, var(--theme-accent, #1f7a3a) 90%, var(--theme-fg, #111));
  font-size: 0.72em;
  font-weight: 700;
  letter-spacing: 0.02em;
  vertical-align: 0.1em;
  font-variant-numeric: normal;
}

/* Computed-promo breakdown (Opust / Cena końcowa) — shown live for a promo
   the POS only applies at the summary screen (min-receipt). Renders as a
   full-width block under the qty/name/total row; the regular total above it
   is struck through to signal it's superseded by the computed final price. */
.receipt-line__total--struck {
  text-decoration: line-through;
  opacity: 0.55;
  font-weight: 500;
}
.receipt-line__promo {
  grid-column: 1 / -1;
  margin-top: 4px;
  padding-left: 12px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.receipt-line__promo-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 0.92em;
}
.receipt-line__promo-label { opacity: 0.85; }
.receipt-line__promo-amount { font-variant-numeric: tabular-nums; }
.receipt-line__promo-row--discount {
  color: color-mix(in srgb, var(--theme-accent, #1f7a3a) 80%, var(--theme-fg, #111));
}
.receipt-line__promo-row--final { font-weight: 700; }

/* Hint banner ("Dodaj 1 szt., aby aktywować…") shown above the lines
   list during RECEIPT mode. Controller toggles data-visible. */
.receipt-promo-banner {
  display: none;
  align-items: center;
  gap: 10px;
  margin: 8px 24px 4px;
  padding: 10px 16px;
  border-radius: 8px;
  background: color-mix(in srgb, var(--theme-accent, #1f7a3a) 14%, var(--theme-bg, #fff));
  color: color-mix(in srgb, var(--theme-fg, #111) 85%, var(--theme-accent, #1f7a3a));
  font-size: 1.05rem;
  font-weight: 500;
  line-height: 1.3;
}
.receipt-promo-banner[data-visible="true"] { display: flex; }
.receipt-promo-banner__icon { font-size: 1.2em; flex-shrink: 0; }
.receipt-promo-banner__text { flex: 1; }

/* Running savings — sits below the "Razem" amount. Smaller than the
   running total but visually paired with it (same right-edge alignment,
   same tabular numerics). Hidden when no savings accrued. */
.receipt-running-savings {
  flex-shrink: 0;
  padding: 6px 24px 12px;
  background: color-mix(in srgb, var(--theme-bg) 92%, var(--theme-fg) 8%);
  font-size: 1.05rem;
  font-variant-numeric: tabular-nums;
  grid-template-columns: 1fr auto auto;
  gap: 6px;
  display: none;
  color: color-mix(in srgb, var(--theme-accent, #1f7a3a) 85%, var(--theme-fg, #111));
}
.receipt-running-savings[data-visible="true"] { display: grid; }
.receipt-running-savings__label { text-align: left; opacity: 0.85; font-weight: 600; }
.receipt-running-savings__amount { text-align: right; font-weight: 700; }
.receipt-running-savings__currency { opacity: 0.7; }

.receipt-running-total {
  flex-shrink: 0;
  padding: 12px 24px;
  border-top: 1px solid color-mix(in srgb, var(--theme-fg) 18%, transparent);
  background: color-mix(in srgb, var(--theme-bg) 92%, var(--theme-fg) 8%);
  font-size: 1.5rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  grid-template-columns: 1fr auto;
  gap: 16px;
  display: none;
}
.receipt-running-total[data-visible="true"] { display: grid; }
.receipt-running-total__label  { text-align: left;  opacity: 0.7; }
.receipt-running-total__amount { text-align: right; font-weight: 700; }

/* ---- SUMMARY: receipt-artefact card -------------------------------------
 *
 * The summary moment is a "printed receipt" sitting on a theme-coloured
 * field. Two type families do the work: a serif display face for the
 * warmth-words ("Dziękujemy", "Zapraszamy ponownie") and a monospace face
 * for the numerics so amounts column on the baseline. No web fonts are
 * loaded — kiosks run offline — so both stacks fall back to fonts
 * shipped on the Windows kiosk image (Cambria/Constantia, Consolas).
 *
 * Entry is a single orchestrated landing: backdrop → card → thanks → label
 * → total → rows (staggered) → welcome. Welcome lands at ~900ms — comfortably
 * inside any realistic summary_duration_seconds. The model validation floor
 * is 0.3s but that's only set by tests; field default is 30s.
 *
 * Anchored on the `[data-visible="true"]` flip — the controller already
 * drives that. Keyframes deliberately stay on transform + opacity only
 * (no `filter:blur`, no `letter-spacing` tween) to keep the entry on the
 * compositor and avoid paint/layout cost on entry-level kiosk GPUs.
 */
.receipt-summary {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse at 50% 40%, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.28) 78%),
    var(--theme-summary-bg);
  color: var(--theme-summary-fg);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 32px;
  z-index: 5;
}
.receipt-summary[data-visible="true"] {
  display: flex;
  animation: receipt-backdrop-in 200ms ease-out both;
}

.receipt-summary__card {
  /* Paper palette is intentionally hard-coded, not theme-derived: every
     real receipt is printed on warm off-white stock regardless of the
     shop's brand colour, and the theme-summary-bg is still visible as
     the frame around the card. */
  --paper:       #fffdf4;
  --paper-edge:  #f3eedd;
  --ink:         #1a1612;
  --ink-soft:    #6a6258;
  --rule:        rgba(26, 22, 18, 0.16);
  --rule-strong: rgba(26, 22, 18, 0.42);

  --serif: "Cormorant Garamond", "Cormorant", "Hoefler Text", "Iowan Old Style",
           "Palatino Linotype", "Book Antiqua", Cambria, Constantia, Georgia, serif;
  --mono:  "JetBrains Mono", "IBM Plex Mono", "SF Mono", Menlo, Consolas,
           "DejaVu Sans Mono", "Courier New", monospace;

  width: min(560px, 92%);
  padding: 56px 56px 44px;
  border-radius: 10px;
  background-color: var(--paper);
  /* Faint paper grain — two offset dot patterns. Cheap and ships nowhere
     near the kiosk's GPU budget. */
  background-image:
    radial-gradient(rgba(26, 22, 18, 0.045) 1px, transparent 1.4px),
    radial-gradient(rgba(26, 22, 18, 0.025) 1px, transparent 1.4px),
    linear-gradient(180deg, var(--paper) 0%, var(--paper-edge) 100%);
  background-size: 7px 7px, 13px 13px, 100% 100%;
  background-position: 0 0, 3px 5px, 0 0;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.85) inset,
    0 0 0 1px rgba(26, 22, 18, 0.05),
    0 28px 70px -22px rgba(0, 0, 0, 0.55),
    0 10px 28px -14px rgba(0, 0, 0, 0.45);

  color: var(--ink);
  font-family: var(--serif);
  display: flex;
  flex-direction: column;
  gap: 28px;
  text-align: center;
  position: relative;

  animation: receipt-card-in 380ms cubic-bezier(0.16, 0.84, 0.32, 1) 60ms both;
}

.receipt-summary__thanks {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(2.6rem, 5.2vw, 3.6rem);
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--ink);
  animation: receipt-thanks-in 280ms cubic-bezier(0.2, 0.7, 0.3, 1) 200ms both;
}

.receipt-summary__total-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

/* Small-caps label flanked by rules — "— RAZEM —" editorial framing. */
.receipt-summary__label {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  font-family: var(--serif);
  font-variant: small-caps;
  font-weight: 600;
  letter-spacing: 0.18em;
  font-size: 0.95rem;
  color: var(--ink-soft);
  text-transform: lowercase;
  animation: receipt-thanks-in 240ms ease-out 320ms both;
}
.receipt-summary__label::before,
.receipt-summary__label::after {
  content: "";
  flex: 0 0 auto;
  width: 56px;
  height: 0;
  border-top: 1px solid var(--rule-strong);
}

.receipt-summary__total {
  font-family: var(--mono);
  font-weight: 600;
  font-size: clamp(3.4rem, 7.6vw, 5rem);
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  display: inline-flex;
  align-items: baseline;
  justify-content: center;
  gap: 0.18em;
  animation: receipt-total-in 360ms cubic-bezier(0.16, 0.84, 0.32, 1) 400ms both;
}

/* Big "Oszczędziłeś X zł" highlight shown on the summary card between
   the totals rows and the goodbye line. Same monospace numeric stack
   as the total so amounts align visually, but smaller and tinted
   with the theme's accent so it reads as a feel-good moment rather
   than another row of bookkeeping. Hidden when no savings accrued —
   non-promo carts look exactly as they did before the matcher. */
.receipt-summary__savings {
  display: none;
  margin: 22px auto 0;
  padding: 14px 20px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--theme-accent, #1f7a3a) 16%, var(--theme-bg, #fff));
  color: color-mix(in srgb, var(--theme-accent, #1f7a3a) 90%, var(--ink, #111));
  text-align: center;
  font-family: var(--mono);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  font-size: clamp(1.6rem, 3.2vw, 2.4rem);
  line-height: 1.1;
}
.receipt-summary__savings[data-visible="true"] { display: block; }
.receipt-summary__savings-label {
  display: block;
  font-family: var(--serif, serif);
  font-style: italic;
  font-weight: 500;
  font-size: 0.62em;
  letter-spacing: 0.02em;
  margin-bottom: 4px;
  opacity: 0.85;
}
.receipt-summary__savings-amount { font-weight: 700; }
.receipt-summary__savings-currency {
  font-family: var(--serif, serif);
  font-style: italic;
  font-weight: 500;
  font-size: 0.5em;
  margin-left: 0.18em;
  opacity: 0.75;
  transform: translateY(-0.4em);
  display: inline-block;
}
.receipt-summary__currency {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 500;
  font-size: 0.36em;
  color: var(--ink-soft);
  letter-spacing: 0;
  transform: translateY(-0.55em);
}

.receipt-summary__rows {
  margin: 0;
  padding: 26px 0 0;
  border-top: 1.5px dashed var(--rule-strong);
  display: flex;
  flex-direction: column;
  gap: 14px;
  text-align: left;
}

/* Three-column grid: label · leader · value. The middle column is the
   only flex column (1fr); the leader pseudo-element lives there with a
   dotted border-bottom, so dots appear only in the gap between label
   and value by construction — no background-masking, no rectangles
   showing through on textured surfaces. */
.receipt-summary__row {
  display: grid;
  grid-template-columns: max-content 1fr max-content;
  align-items: baseline;
  font-size: 1.25rem;
  /* Per-row stagger driven by source order — payment-type row may be
     hidden at runtime; nth-child still lays the rhythm down because we
     count from the DOM, not the layout. */
  animation: receipt-row-in 240ms cubic-bezier(0.2, 0.7, 0.3, 1) both;
}
.receipt-summary__row:nth-child(1) { animation-delay: 540ms; }
.receipt-summary__row:nth-child(2) { animation-delay: 600ms; }
.receipt-summary__row:nth-child(3) { animation-delay: 660ms; }
.receipt-summary__row:nth-child(4) { animation-delay: 720ms; }

.receipt-summary__row::after {
  content: "";
  grid-column: 2;
  height: 2px;
  margin: 0 12px;
  /* radial-gradient produces a more visible dot pattern than
     border-bottom: dotted does at hairline thicknesses — Chromium packs
     border-dots tightly at 1.5px and the leader reads as a solid rule.
     This tiles dots at 8px intervals, matching the receipt-printer
     aesthetic we had before the rectangles issue. */
  background-image: radial-gradient(var(--rule-strong) 1px, transparent 1.4px);
  background-size: 8px 2px;
  background-repeat: repeat-x;
  align-self: center;
  transform: translateY(0.18em);
}

.receipt-summary__row dt {
  grid-column: 1;
  margin: 0;
  font-family: var(--serif);
  font-variant: small-caps;
  font-weight: 600;
  letter-spacing: 0.14em;
  font-size: 0.95rem;
  color: var(--ink-soft);
  white-space: nowrap;
}
.receipt-summary__row dd {
  grid-column: 3;
  margin: 0;
  font-family: var(--mono);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  font-size: 1.25rem;
  color: var(--ink);
}

.receipt-summary__welcome {
  padding-top: 22px;
  border-top: 1.5px dashed var(--rule-strong);
  font-family: var(--serif);
  font-style: italic;
  font-weight: 500;
  font-size: 1.5rem;
  color: var(--ink-soft);
  animation: receipt-welcome-in 260ms ease-out 820ms both;
}

@keyframes receipt-backdrop-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes receipt-card-in {
  from { opacity: 0; transform: translateY(28px) scale(0.97); }
  to   { opacity: 1; transform: translateY(0)    scale(1);    }
}
@keyframes receipt-thanks-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0);   }
}
@keyframes receipt-total-in {
  from { opacity: 0; transform: scale(0.9); }
  to   { opacity: 1; transform: scale(1);   }
}
@keyframes receipt-row-in {
  from { opacity: 0; transform: translateX(-10px); }
  to   { opacity: 1; transform: translateX(0);     }
}
@keyframes receipt-welcome-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0);   }
}

.pos-source-status {
  position: absolute;
  bottom: 12px;
  right: 12px;
  z-index: 4;
  font-size: 0.75rem;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  padding: 4px 8px;
  border-radius: 4px;
  pointer-events: none;
  opacity: 0.7;
  transition: opacity 0.4s ease-out;
}
.pos-source-status[data-visible="false"] { opacity: 0; }
.pos-source-status[data-level="error"] { background: rgba(180, 30, 30, 0.85); opacity: 0.95; }
.pos-source-status[data-level="warn"]  { background: rgba(180, 130, 30, 0.85); opacity: 0.9; }
.pos-source-status[data-level="error"][data-visible="false"],
.pos-source-status[data-level="warn"][data-visible="false"] { opacity: 0; }

/* Themes — just decorations / filters; palette already lives in CSS vars. */
.cashregister.theme-mourning_grey,
.theme-mourning_grey { filter: grayscale(0.95); }

/* ============================================================
   Quiet Studio additions: dashboard hero, fleet panel, pills,
   monospace numeric helpers.
   ============================================================ */

/* Tabular numerics anywhere `.num` is applied. */
.num,
.stat-card__value {
  font-family: var(--font-mono);
  font-feature-settings: 'tnum';
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

/* ---- Dashboard hero ---- */
.page-hero {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 32px;
}

.page-hero__main { min-width: 0; }

.page-hero__eyebrow {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.page-hero__title {
  margin: 8px 0 6px;
  font-size: 36px;
  font-weight: 300;        /* matches the brand wordmark's light weight */
  letter-spacing: -0.02em;
  line-height: 1.05;
  color: var(--text);
}
.page-hero__icon {
  color: var(--brand-red);
  vertical-align: -3px;
  margin-right: 10px;
}
.page-hero__title em {
  /* "24" in the brand logo is a colour change, not italic. We mirror
     that treatment for the user's name in the greeting. */
  font-style: normal;
  font-weight: 400;
  color: var(--brand-red);
}

.page-hero__sub {
  color: var(--text-secondary);
  font-size: 14px;
}

/* ---- Dashboard sections ---- */
.dash-section {
  margin-top: 40px;
}
.dash-section__title {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.005em;
  margin: 0 0 14px;
  color: var(--text);
}

/* Cover thumbnail of the location's uploaded photo on the show page. */
.location-photo {
  width: 100%;
  max-width: 480px;
  height: 200px;
  object-fit: cover;
  border-radius: 8px;
  margin-bottom: 16px;
}

/* Read-only key/value list, used on the location show page. */
.detail-list {
  margin: 0;
}
.detail-list__row {
  display: grid;
  grid-template-columns: 180px 1fr;
  gap: 16px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
}
.detail-list__row:last-child {
  border-bottom: none;
}
.detail-list__row dt {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-secondary);
}
.detail-list__row dd {
  margin: 0;
  font-size: 14px;
  color: var(--text);
}
@media (max-width: 640px) {
  .detail-list__row {
    grid-template-columns: 1fr;
    gap: 4px;
  }
}

/* Plain stacked list of records (e.g. the campaigns assigned to a location on
   the show page). Each row separated by a hairline, last row borderless. */
.record-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.record-list__item {
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
}
.record-list__item:last-child {
  border-bottom: none;
}
/* Empty-state line shown in place of the list when there are no records. */
.record-list__empty {
  margin: 0;
  font-size: 13px;
  color: var(--text-secondary);
}

/* Sub-heading above each fleet-version table on /locations management.
   Smaller than .dash-section__title so it sits as a third-level header
   inside a section grid cell. */
.fleet-table__title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  margin: 0 0 10px;
  letter-spacing: -0.005em;
}

/* Optional right-side "Otwórz urządzenia →" link next to a section title. */
.dash-section__header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 14px;
}
.dash-section__header .dash-section__title {
  margin: 0;
}

.dash-section__link {
  font-size: 13px;
  font-weight: 500;
  color: var(--brand-red);
  text-decoration: none;
  white-space: nowrap;
  transition: opacity var(--transition);
}
.dash-section__link:hover {
  opacity: 0.7;
}

.dash-stats {
  /* tighter than .grid--3 default minmax — three even columns */
  grid-template-columns: repeat(3, 1fr);
}
@media (max-width: 880px) {
  .dash-stats { grid-template-columns: 1fr; }
}

/* ---- Campaigns stat cards (new chip-first layout) ----
   Replaces the icon-first .stat-card design for the three campaign tiles
   on the dashboard. Locations status block still uses .stat-card. */
.stat-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
}
@media (max-width: 880px) {
  .stat-row { grid-template-columns: 1fr; }
}

.stat {
  position: relative;
  overflow: hidden;
  display: block;
  padding: 20px 22px 18px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: inherit;
  text-decoration: none;
  transition: border-color var(--transition), transform var(--transition), box-shadow var(--transition);
}
.stat:hover {
  border-color: var(--gray-300);
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
  opacity: 1;
}

.stat__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 14px;
}

.stat__label {
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  letter-spacing: -0.005em;
}

.stat__chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px;
  border-radius: var(--radius-full);
  font-size: 11px;
  font-weight: 500;
  white-space: nowrap;
}
.stat__chip .dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
}

.stat--ok   .stat__chip { background: var(--green-soft); color: var(--green); }
.stat--ok   .stat__chip .dot {
  background: var(--green);
  box-shadow: 0 0 0 3px rgba(46, 132, 86, 0.18);
  animation: stat-pulse 2.4s ease-out infinite;
}
.stat--info .stat__chip { background: #E6ECF6; color: #2A5DB0; }
.stat--info .stat__chip .dot { background: #2A5DB0; }
.stat--warn .stat__chip { background: #F6EEDA; color: #CA8A04; }
.stat--warn .stat__chip .dot { background: #CA8A04; }
.stat--bad  .stat__chip { background: var(--brand-red-soft); color: var(--brand-red); }
.stat--bad  .stat__chip .dot { background: var(--brand-red); }

@keyframes stat-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(46, 132, 86, 0.35); }
  70%  { box-shadow: 0 0 0 7px rgba(46, 132, 86, 0); }
  100% { box-shadow: 0 0 0 0 rgba(46, 132, 86, 0); }
}

.stat__value {
  font-family: var(--font-mono);
  font-feature-settings: 'tnum';
  font-variant-numeric: tabular-nums;
  font-size: 44px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--text);
}

.stat__delta {
  margin-top: 8px;
  font-size: 12.5px;
  color: var(--text-secondary);
  line-height: 1.45;
}
.stat__delta strong { color: var(--text); font-weight: 600; }

/* ---- Sieć urządzeń panel ---- */
.fleet-panel {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
/* The device-fleet panel carries one card per device kind (5: players, totems,
   radios, cashregisters, scales). The modules panel reuses .fleet-panel but has
   its own card count, so the wider grid is scoped to the fleet variant only. */
.fleet-panel--devices { grid-template-columns: repeat(5, 1fr); }
@media (max-width: 1180px) {
  .fleet-panel { grid-template-columns: 1fr 1fr; }
  .fleet-panel--devices { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 640px) {
  .fleet-panel { grid-template-columns: 1fr; }
}

.fleet-cell {
  padding: 20px 22px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  border-right: 1px solid var(--border);
}
.fleet-cell:last-child { border-right: none; }
@media (max-width: 880px) {
  .fleet-cell { border-right: none; border-bottom: 1px solid var(--border); }
  .fleet-cell:last-child { border-bottom: none; }
}

.fleet-cell__head {
  display: flex;
  align-items: center;
  gap: 10px;
}
.fleet-cell__icon {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  display: grid;
  place-items: center;
  background: var(--gray-100);
  color: var(--text-secondary);
  flex-shrink: 0;
}
/* harmonious per-kind tints — no rainbow */
.fleet-cell--player .fleet-cell__icon   { background: #ECF1EE; color: #2B6757; }
.fleet-cell--totem .fleet-cell__icon    { background: #EDECF6; color: #4B3F8F; }
.fleet-cell--radio .fleet-cell__icon    { background: #EEEAE0; color: #7A5C1F; }
.fleet-cell--receipt_screen .fleet-cell__icon { background: #E9EEF6; color: #2A5DB0; }
.fleet-cell--scale .fleet-cell__icon    { background: #E4EFF1; color: #216C79; }
.fleet-cell--module .fleet-cell__icon   { background: #E6F2EF; color: #1F7A5C; }

.fleet-cell__name {
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: -0.005em;
}
.fleet-cell__count {
  margin-left: auto;
  font-size: 12px;
  color: var(--text-secondary);
}

.fleet-cell__bar {
  height: 6px;
  border-radius: var(--radius-full);
  background: var(--gray-200);
  overflow: hidden;
  display: flex;
}
.fleet-cell__bar-fill {
  height: 100%;
  transition: width 800ms cubic-bezier(0.2, 0.7, 0.2, 1);
}
.fleet-cell__bar-fill--on  { background: var(--green); }
.fleet-cell__bar-fill--off { background: var(--red); }

.fleet-cell__legend {
  display: flex;
  gap: 16px;
  font-size: 12px;
  color: var(--text-secondary);
}
.fleet-cell__legend .num { color: var(--text); font-weight: 500; }
.fleet-cell__legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  display: inline-block;
}
.dot--on  { background: var(--green); }
.dot--off { background: var(--red); }

/* ---- Status pill variants (semantic aliases over the base .pill) ---- */
.pill--ok   { background: var(--green-soft); color: var(--green); }
.pill--ok .dot   { background: var(--green); }
.pill--info { background: #E6ECF6; color: #2A5DB0; }
.pill--info .dot { background: #2A5DB0; }
.pill--warn { background: #F6EEDA; color: #CA8A04; }
.pill--warn .dot { background: #CA8A04; }
.pill--bad  { background: #F6E4E1; color: #A8362E; }
.pill--bad .dot  { background: #A8362E; }
.pill--mute { background: var(--gray-200); color: var(--text-secondary); }
.pill--mute .dot { background: var(--text-secondary); }

/* ===== Campaign report media table — thumbnails =====
   Used by app/views/campaigns/report.html.erb (.report-media__preview-col
   on the first th/td) and by app/helpers/campaigns_helper.rb's
   medium_report_thumbnail helper. The dash fallback reuses
   .media-placeholder + .media-placeholder--sm for visual consistency
   with the rest of the app. */
.report-media__preview-col {
  width: 72px;
  padding-right: 8px;
}
.report-media__thumb {
  width: 56px;
  height: 56px;
  object-fit: cover;
  border-radius: 4px;
  display: block;
  background: var(--gray-100);
}


/* ============================================================
   KASA — redesigned customer receipt screen (design-lab preview)
   Reachable at /devices/:identifier/receipt_design. Fully namespaced
   under `.kasa` so it never collides with the live `.cashregister`
   layout or other app styles. Themed entirely via CSS variables that
   kasa_controller.js writes from the device's ReceiptTheme tokens.
   ============================================================ */
.kasa {
  /* font stacks: kiosks fall back to installed fonts; the lab loads
     web fonts (Fraunces / Bricolage Grotesque / Spline Sans Mono). */
  --k-display:"Fraunces", Cambria, Georgia, serif;
  --k-ui:"Bricolage Grotesque", system-ui, sans-serif;
  --k-mono:"Spline Sans Mono","JetBrains Mono", Consolas, monospace;
  --k-ease:cubic-bezier(0.16,0.84,0.32,1);
  /* token fallbacks (Lewiatan) — JS overrides per theme */
  --brand:#1f62b0; --brand-deep:#0e306c; --brand-bright:#2e7bd6; --brand-glow:#7fb2ee;
  --accent:#ffd200; --accent-light:#ffec4d; --accent-deep:#d6a400;
  --panel-a:#1f62b0; --panel-b:#123a82; --panel-c:#0e2a60; --panel-d:#08193c;
  --panel-glow:rgba(46,123,214,0.26);
  --ink:#14213d; --ink-soft:#5b6b86; --ink-faint:#9aa8be;
  --paper:#fbfbf6; --paper-warm:#eef2f8; --paper-edge:#e1e8f2; --card:#ffffff;
  --rule:rgba(20,33,61,0.10); --rule-strong:rgba(20,33,61,0.26);
  --brick:#d6402b; --coin-ink:#6b5400;

  position:relative; display:flex; width:100%; height:100%;
  overflow:hidden; font-family:var(--k-ui);
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
}

/* ---- stage (left: media + communication) ---- */
.kasa-stage {
  position:relative; flex:1 1 auto; min-width:0;
  display:flex; flex-direction:column;
  background:
    radial-gradient(120% 90% at 18% 12%, var(--panel-a) 0%, transparent 55%),
    radial-gradient(130% 100% at 86% 92%, var(--panel-b) 0%, transparent 60%),
    linear-gradient(160deg, var(--panel-c) 0%, var(--panel-d) 100%);
  overflow:hidden; transition:flex-basis 480ms var(--k-ease);
}
.kasa-stage::before { content:""; position:absolute; inset:-20%;
  background-image:radial-gradient(rgba(255,255,255,0.05) 1px, transparent 1.4px);
  background-size:26px 26px; animation:kasa-drift 60s linear infinite; pointer-events:none; }
@keyframes kasa-drift { to { transform:translate(26px,26px);} }
/* The idle stage is intentionally brand-free — fullscreen shows ONLY the
   campaign image/video (no overlaid badge). */

.kasa-mediaframe { flex:1; display:grid; place-items:center; padding:0; min-height:0; transition:padding 480ms var(--k-ease); }
.kasa-media { position:relative; overflow:hidden; width:100%; height:100%; border-radius:0; box-shadow:none;
  transition:border-radius 480ms var(--k-ease), box-shadow 480ms var(--k-ease); }
.kasa-media__art { position:absolute; inset:0;
  background:
    radial-gradient(58% 78% at 72% 22%, var(--accent-light) 0%, transparent 58%),
    radial-gradient(80% 95% at 22% 88%, var(--brand-bright) 0%, transparent 62%),
    linear-gradient(135deg, var(--brand) 0%, var(--brand-deep) 100%);
  animation:kasa-kenburns 18s ease-in-out infinite alternate; }
@keyframes kasa-kenburns { from { transform:scale(1) translate(0,0);} to { transform:scale(1.12) translate(-2%,1%);} }
/* Live kiosk only: the kasa scene is a direct child of <body> in the
   cashregister layout, whereas the admin lab nests it inside .kasa-lab. So
   `body > .kasa` targets the kiosk alone — hide the cursor there (matches the
   legacy .cashregister) without hiding it in the operator preview. */
body > .kasa { cursor:none; }
/* Live kiosk only: stop the two full-stage infinite animations. The ken-burns
   __art layer sits behind opaque campaign media (never seen) and the drifting
   grain is imperceptible — but both keep the compositor busy 24/7 on weak kiosk
   GPUs. The small loyalty/pay flourishes stay; the admin lab keeps full motion. */
body > .kasa .kasa-media__art { animation:none; }
body > .kasa .kasa-stage::before { animation:none; }
/* Live kiosk only: the real campaign media (player_controller targets) fills
   .kasa-media on top of the animated __art backdrop. `contain` letterboxes
   onto the gradient so portrait/odd-ratio media still looks intentional. The
   lab keeps its static __art/__copy/__tag ad and renders none of these. */
.kasa-media__el { position:absolute; inset:0; width:100%; height:100%; object-fit:contain; z-index:1; }
/* No `display:flex` here: player_controller toggles inline display:block/none on
   this target, which would win over a flex rule. Centre via absolute positioning
   instead so it holds whatever display the controller sets. */
.kasa-media__nocontent { position:absolute; left:0; right:0; top:50%; transform:translateY(-50%); z-index:2; text-align:center;
  color:rgba(255,255,255,0.82); font-family:var(--k-ui); font-size:1.4rem; letter-spacing:0.02em; }
.kasa-media__offline { position:absolute; top:14px; right:14px; z-index:3; width:12px; height:12px; border-radius:50%;
  background:#ef4444; box-shadow:0 0 0 5px rgba(239,68,68,0.18); }
/* Lab-only demo photo filling the media frame (cover) behind the ad copy/tag.
   The live kiosk renders player img/video (.kasa-media__el) here instead. */
.kasa-media__photo { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; z-index:0; }
.kasa-media__copy { position:absolute; left:0; right:0; bottom:0; padding:46px; color:#fff; text-align:left; z-index:2; }
/* Scrim under the headline so white copy stays legible over the photo. */
.kasa-media__copy::before { content:""; position:absolute; inset:-60px 0 0 0; z-index:-1;
  background:linear-gradient(to top, rgba(6,14,28,0.88) 8%, rgba(6,14,28,0.45) 50%, transparent); }
.kasa-media__copy .kicker { text-transform:uppercase; letter-spacing:0.32em; font-size:13px; opacity:0.8; margin-bottom:12px; }
.kasa-media__copy h2 { font-family:var(--k-display); font-weight:300; font-size:clamp(34px,4vw,62px); line-height:0.98; letter-spacing:-0.02em; }
.kasa-media__copy h2 em { font-style:italic; font-weight:500; color:var(--accent-light); }
.kasa-media__tag { position:absolute; top:26px; right:26px; font-family:var(--k-display); font-weight:700; font-size:30px; color:#14213d;
  background:var(--accent-light); padding:8px 16px; border-radius:14px; transform:rotate(4deg); box-shadow:0 10px 24px -8px rgba(0,0,0,0.5); }

.kasa-comm { flex-shrink:0; max-height:0; opacity:0; overflow:hidden;
  transition:max-height 480ms var(--k-ease), opacity 360ms var(--k-ease), padding 480ms var(--k-ease); }
.kasa-comm--top, .kasa-comm--bottom { padding:0 34px; }
/* Promo zone holds a STACK of promo cards (one per active promotion action).
   Scrolls if a basket triggers more than fit; on a kiosk the realistic count
   (a few) fits and the media frame above flexes smaller to make room. The cap
   is the viewport-relative 54vh (matching the serving .kasa-comm--bottom max),
   NOT max-height:100% — a percentage max-height doesn't resolve against the
   content-driven (indefinite-height) comm parent, so the scroll would never
   bound and overflowing cards would clip silently. */
.kasa-promos { display:flex; flex-direction:column; gap:10px; max-height:54vh; overflow-y:auto; scrollbar-width:none; }
.kasa-promos::-webkit-scrollbar { width:0; height:0; }

.kasa-loyalty { display:flex; align-items:center; gap:20px; padding:18px 22px; border-radius:20px;
  background:linear-gradient(180deg, rgba(255,255,255,0.10), rgba(255,255,255,0.04)); border:1px solid rgba(255,255,255,0.14); color:#eaf6ee; }
.kasa-loyalty__card { position:relative; width:96px; height:62px; flex-shrink:0; border-radius:11px; overflow:hidden;
  background:linear-gradient(135deg, var(--accent) 0%, var(--accent-deep) 100%); box-shadow:0 10px 22px -8px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.3); }
.kasa-loyalty__card::before { content:""; position:absolute; left:10px; top:14px; width:22px; height:16px; border-radius:3px; background:rgba(255,255,255,0.45); }
.kasa-loyalty__beam { position:absolute; inset:0; background:linear-gradient(100deg, transparent 40%, rgba(255,255,255,0.55) 50%, transparent 60%); transform:translateX(-120%); animation:kasa-beam 2.6s ease-in-out infinite; }
@keyframes kasa-beam { 0%,60% { transform:translateX(-120%);} 85%,100% { transform:translateX(120%);} }
.kasa-loyalty__body { flex:1; }
.kasa-loyalty__title { font-family:var(--k-display); font-style:italic; font-weight:500; font-size:24px; line-height:1.05; }
.kasa-loyalty__sub { font-size:15px; color:rgba(234,246,238,0.7); margin-top:3px; }
.kasa-loyalty__arrow { font-size:30px; color:var(--accent-light); animation:kasa-nudge 1.4s ease-in-out infinite; }
@keyframes kasa-nudge { 0%,100% { transform:translateX(0);} 50% { transform:translateX(6px);} }
.kasa-loyalty[data-state="welcome"] .kasa-loyalty__beam, .kasa-loyalty[data-state="welcome"] .kasa-loyalty__arrow { display:none; }

/* Compact card — sized so several stack in the promo zone without overflowing. */
.kasa-promo { display:flex; align-items:center; gap:15px; padding:13px 17px; border-radius:16px; flex-shrink:0;
  background:linear-gradient(180deg, rgba(246,206,94,0.18), rgba(246,206,94,0.07)); border:1px solid rgba(246,206,94,0.34); color:#fdf6e5; position:relative; overflow:hidden; }
.kasa-promo__icon { width:44px; height:44px; flex-shrink:0; display:grid; place-items:center; border-radius:13px;
  background:linear-gradient(160deg, var(--accent) 0%, var(--accent-deep) 100%); font-size:23px; box-shadow:0 8px 18px -10px rgba(0,0,0,0.6); }
.kasa-promo__body { flex:1; min-width:0; }
.kasa-promo__eyebrow { text-transform:uppercase; letter-spacing:0.16em; font-size:11px; color:var(--accent-light); margin-bottom:3px; }
.kasa-promo__title { font-family:var(--k-display); font-weight:500; font-size:18px; line-height:1.15; letter-spacing:-0.01em; }
.kasa-promo__title b { color:var(--accent-light); font-weight:700; }
.kasa-promo__note { font-size:12px; color:rgba(253,246,229,0.62); margin-top:4px; }
.kasa-meter { margin-top:8px; height:10px; border-radius:999px; background:rgba(0,0,0,0.28); overflow:hidden; }
.kasa-meter__fill { height:100%; border-radius:999px; width:0%; background:linear-gradient(90deg, var(--accent), var(--accent-light)); box-shadow:0 0 12px color-mix(in srgb, var(--accent) 60%, transparent); transition:width 640ms var(--k-ease); }
.kasa-meter__row { display:flex; justify-content:space-between; align-items:baseline; margin-top:5px; font-size:12px; color:rgba(253,246,229,0.75); }
.kasa-meter__row b { font-family:var(--k-mono); font-weight:700; color:#fff; }
.kasa-dots { display:flex; gap:7px; margin-top:8px; }
.kasa-dots i { width:12px; height:12px; border-radius:50%; background:rgba(0,0,0,0.3); border:1.5px solid color-mix(in srgb, var(--accent-light) 50%, transparent); }
.kasa-dots i.on { background:var(--accent-light); border-color:var(--accent-light); box-shadow:0 0 10px color-mix(in srgb, var(--accent-light) 70%, transparent); }
.kasa-promo[data-done="true"] { background:linear-gradient(180deg, color-mix(in srgb, var(--brand-bright) 24%, transparent), color-mix(in srgb, var(--brand-bright) 10%, transparent)); border-color:color-mix(in srgb, var(--brand-glow) 55%, transparent); }
.kasa-promo[data-done="true"] .kasa-promo__icon { background:linear-gradient(160deg, var(--brand-bright), var(--brand)); }
.kasa-promo[data-done="true"] .kasa-promo__eyebrow, .kasa-promo[data-done="true"] .kasa-promo__title b { color:var(--brand-glow); }
.kasa-promo[data-done="true"] .kasa-meter__fill { background:linear-gradient(90deg, var(--brand-bright), var(--brand-glow)); }

/* ---- loyalty-card-gated promos ----
   A promo (or a card-only price) available ONLY with the customer's loyalty
   card. The "card flag" is a cobalt pill carrying a yellow mini-card glyph + the
   brand; card-gated cards also get an accent rail on the left edge. */
.kasa-cardflag { display:inline-flex; align-items:center; gap:7px; padding:3px 10px 3px 6px; border-radius:999px;
  background:linear-gradient(135deg, var(--brand-bright), var(--brand-deep)); color:#fff;
  font-family:var(--k-display); font-style:italic; font-weight:600; font-size:12.5px; letter-spacing:-0.01em; white-space:nowrap;
  box-shadow:0 4px 11px -5px rgba(0,0,0,0.6), inset 0 1px 0 rgba(255,255,255,0.22); }
.kasa-cardflag svg { width:23px; height:16px; flex-shrink:0; }
.kasa-cardflag .body { fill:var(--accent); } .kasa-cardflag .chip { fill:var(--brand-deep); } .kasa-cardflag .stripe { fill:var(--accent-deep); }
.kasa-promo__flagrow { margin-bottom:6px; }

/* variant (a): existing promo cards, gated — accent rail + the flag chip */
.kasa-promo--card { border-color:color-mix(in srgb, var(--accent) 50%, transparent); padding-left:21px;
  background:linear-gradient(180deg, rgba(246,206,94,0.22), rgba(246,206,94,0.08)); }
.kasa-promo--card::before, .kasa-promo--price::before { content:""; position:absolute; left:0; top:0; bottom:0; width:5px;
  background:linear-gradient(180deg, var(--accent-light), var(--accent-deep)); }

/* variant (b): card-only price — regular price struck → special card price */
.kasa-promo--price { align-items:stretch; padding:15px 18px 15px 21px;
  background:linear-gradient(165deg, color-mix(in srgb, var(--brand-bright) 30%, transparent), color-mix(in srgb, var(--brand-deep) 16%, transparent));
  border-color:color-mix(in srgb, var(--brand-glow) 45%, transparent); }
.kasa-promo--price .kasa-promo__icon { align-self:flex-start; background:linear-gradient(160deg, var(--brand-bright), var(--brand-deep)); color:#fff; }
.kasa-price { display:flex; align-items:center; gap:14px; margin-top:9px; flex-wrap:wrap; }
.kasa-price__was { font-family:var(--k-mono); font-size:18px; color:rgba(253,246,229,0.55); text-decoration:line-through; text-decoration-color:rgba(253,246,229,0.4); }
.kasa-price__arrow { color:var(--accent-light); font-size:18px; }
.kasa-price__now { display:inline-flex; align-items:baseline; gap:5px; padding:5px 14px; border-radius:13px;
  background:linear-gradient(135deg, var(--accent-light), var(--accent)); color:var(--brand-deep);
  box-shadow:0 8px 20px -8px color-mix(in srgb, var(--accent) 55%, transparent), inset 0 1px 0 rgba(255,255,255,0.5); }
.kasa-price__now b { font-family:var(--k-mono); font-weight:700; font-size:30px; line-height:1; letter-spacing:-0.02em; }
.kasa-price__now span { font-family:var(--k-mono); font-weight:700; font-size:15px; }
.kasa-price__save { font-size:12px; color:var(--accent-light); font-weight:600; align-self:center; }
.kasa-promo__note .scan { color:var(--accent-light); }

/* scene mode: idle vs serving.
   idle    → media fills the stage edge-to-edge (fullscreen, set on the base
             .kasa-media rule: full width/height, no radius/shadow).
   serving → the same media animates into a centred window on the left stage,
             framed to match the receipt panel's rounded cards (22px radius,
             themed accent hairline + deep shadow) so the two sides read as one
             cohesive scene. The mediaframe centres it (place-items:center);
             generous padding floats it clear of the loyalty/promo comm zones. */
.kasa[data-mode="serving"] .kasa-mediaframe { padding:30px 44px; }
/* The media fills the padded frame (keeps the base 100%×100% — do NOT switch to
   width/height:auto: the media's children are absolutely positioned, so an
   auto-sized box with aspect-ratio collapses to 0 and the window vanishes). The
   frame padding + the loyalty/promo zones above & below centre it on the stage;
   a light inner hairline + dark outer ring + deep shadow make it read as a
   deliberate framed screen on any media. */
.kasa[data-mode="serving"] .kasa-media {
  border-radius:22px;
  border:1px solid rgba(255,255,255,0.22);
  box-shadow:0 40px 80px -26px rgba(0,0,0,0.85), 0 0 0 1px rgba(0,0,0,0.28), inset 0 1px 0 rgba(255,255,255,0.20); }
.kasa[data-mode="serving"] .kasa-comm { max-height:240px; opacity:1; }
.kasa[data-mode="serving"] .kasa-comm--top { padding-top:80px; }
/* The promo zone may carry several cards — let it grow (up to ~half the stage,
   then scroll) so all active promotions show. It only takes the height its
   cards need, so a single promo keeps the media large; more promos shrink the
   media frame (flex:1 above) to fit. */
.kasa[data-mode="serving"] .kasa-comm--bottom { max-height:54vh; padding-top:6px; padding-bottom:22px; }

/* ---- receipt (right) ---- */
.kasa-receipt { position:relative; flex:0 0 0; max-width:720px; width:46%;
  display:flex; flex-direction:column;
  background:radial-gradient(rgba(32,32,26,0.030) 1px, transparent 1.5px), linear-gradient(180deg, var(--paper) 0%, var(--paper-warm) 100%);
  background-size:8px 8px, 100% 100%; color:var(--ink); box-shadow:-40px 0 80px -30px rgba(0,0,0,0.55);
  overflow:hidden; flex-basis:0; opacity:0; transition:flex-basis 480ms var(--k-ease), opacity 360ms var(--k-ease); }
.kasa[data-mode="serving"] .kasa-receipt { flex-basis:46%; opacity:1; }

.kasa-cart { flex-shrink:0; display:flex; align-items:center; gap:18px; padding:30px 38px 22px; border-bottom:1.5px solid var(--rule); position:relative; }
.kasa-cart__icon { position:relative; width:56px; height:56px; flex-shrink:0; display:grid; place-items:center; border-radius:16px; background:linear-gradient(160deg, var(--brand) 0%, var(--brand-deep) 100%); color:#fff; box-shadow:0 10px 22px -10px color-mix(in srgb, var(--brand) 70%, transparent), inset 0 1px 0 rgba(255,255,255,0.25); }
.kasa-cart__icon svg { width:30px; height:30px; }
.kasa-cart__count { display:flex; align-items:baseline; gap:10px; }
.kasa-cart__count b { font-family:var(--k-display); font-weight:600; font-size:46px; line-height:1; letter-spacing:-0.02em; font-variant-numeric:tabular-nums; }
.kasa-cart__count span { font-size:17px; color:var(--ink-soft); }
.kasa-cart__spacer { flex:1; }
.kasa-cart__loyalty { display:flex; flex-direction:column; align-items:flex-end; gap:6px; font-size:12px; color:var(--ink-faint); text-transform:uppercase; letter-spacing:0.18em; }
.kasa-cart__loyalty b { font-family:var(--k-display); font-size:18px; color:var(--brand); letter-spacing:0; text-transform:none; }
.kasa-cart__loyalty-caption { font-size:11px; color:var(--ink-faint); text-transform:uppercase; letter-spacing:0.18em; }

/* ---- brand logo (receipt header + summary card) ----
   Two render paths from devices/_kasa_logo:
   • --brand: the official Lewiatan logo (current brand mark) as a contained
     background image from --kasa-lewiatan-logo, sized by height with the
     artwork's intrinsic aspect ratio (450×146 ≈ 3.08:1). Transparent PNG, so
     drop-shadow follows the swoosh silhouette. Authentic colours — not tinted.
   • --word: themed text wordmark (leaf mark + brand name) for other themes —
     tinted entirely from theme tokens. */
.kasa-logo { display:inline-flex; align-items:center; gap:9px; line-height:1; }
.kasa-logo__mark { flex-shrink:0; overflow:visible; }
.kasa-logo__leaf { fill:var(--accent); }
.kasa-logo__vein { stroke:var(--brand-deep); stroke-width:2.2; stroke-linecap:round; }
.kasa-logo__word { font-family:var(--k-display); font-style:italic; font-weight:600; letter-spacing:-0.01em; color:var(--brand); white-space:nowrap; text-transform:none; }
.kasa-logo__art { display:block; flex-shrink:0; width:auto; aspect-ratio:450 / 146;
  background:var(--kasa-lewiatan-logo) center/contain no-repeat; }
.kasa-logo--receipt .kasa-logo__mark { width:25px; height:25px; }
.kasa-logo--receipt .kasa-logo__word { font-size:21px; }
.kasa-logo--receipt .kasa-logo__art { height:40px; }
.kasa-logo--summary { align-self:center; gap:13px; flex-shrink:0; animation:kasa-rise 460ms var(--k-ease) 60ms both; }
.kasa-logo--summary .kasa-logo__mark { width:42px; height:42px; }
.kasa-logo--summary .kasa-logo__word { font-size:clamp(28px,4.5vw,38px); }
.kasa-logo--summary .kasa-logo__art { height:clamp(40px,6vh,56px); filter:drop-shadow(0 8px 16px rgba(0,0,0,0.28)); }
.kasa-tick { animation:kasa-tick 420ms var(--k-ease); }
@keyframes kasa-tick { 0% { transform:scale(1);} 35% { transform:scale(1.18); color:var(--brand);} 100% { transform:scale(1);} }

.kasa-lines { list-style:none; margin:0; flex:1; overflow-y:auto; padding:14px 30px 8px; scrollbar-width:none; }
.kasa-lines::-webkit-scrollbar { width:0; height:0; }
.kasa-line { padding:18px 0 16px; border-bottom:1px solid var(--rule); animation:kasa-line-in 520ms var(--k-ease) both; }
.kasa-line:last-child { border-bottom:0; }
@keyframes kasa-line-in { 0% { opacity:0; transform:translateY(16px) scale(0.985);} 60% { opacity:1;} 100% { opacity:1; transform:none;} }
.kasa-line.fresh { position:relative; }
.kasa-line.fresh::after { content:""; position:absolute; inset:0 -30px; background:linear-gradient(90deg, transparent, color-mix(in srgb, var(--brand-bright) 16%, transparent), transparent); transform:translateX(-100%); animation:kasa-sweep 900ms var(--k-ease) 120ms; pointer-events:none; }
@keyframes kasa-sweep { to { transform:translateX(100%);} }
.kasa-line__head { display:grid; grid-template-columns:30px 1fr auto; align-items:baseline; gap:14px; }
.kasa-line__nr { font-family:var(--k-mono); font-size:14px; color:var(--ink-faint); font-variant-numeric:tabular-nums; }
.kasa-line__name { font-weight:600; font-size:20px; letter-spacing:-0.01em; color:var(--ink); display:flex; align-items:center; gap:10px; min-width:0; }
.kasa-line__name .txt { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.kasa-line__badge { flex-shrink:0; display:inline-flex; align-items:center; gap:5px; padding:3px 10px 3px 8px; border-radius:999px; background:linear-gradient(180deg, var(--accent-light), var(--accent)); color:var(--brand-deep); font-size:12px; font-weight:700; letter-spacing:0.03em; text-transform:uppercase; box-shadow:0 4px 10px -4px color-mix(in srgb, var(--accent) 70%, transparent); }
.kasa-line__badge::before { content:"★"; font-size:11px; }
.kasa-line__total { font-family:var(--k-mono); font-weight:600; font-size:20px; font-variant-numeric:tabular-nums; white-space:nowrap; color:var(--ink); }
.kasa-line__total.struck { text-decoration:line-through; text-decoration-color:var(--ink-faint); color:var(--ink-faint); font-weight:500; font-size:17px; }
.kasa-line__sub { margin:9px 0 0 44px; display:flex; flex-direction:column; gap:5px; }
.kasa-line__row { display:grid; grid-template-columns:1fr auto; align-items:baseline; font-size:15px; color:var(--ink-soft); }
.kasa-line__row .v { font-family:var(--k-mono); font-variant-numeric:tabular-nums; }
.kasa-line__row.discount, .kasa-line__row.discount .v { color:var(--brick); font-weight:600; }
.kasa-line__row.final { color:var(--ink); font-weight:700; font-size:17px; padding-top:4px; }
.kasa-line__row.final .v { font-size:18px; }

.kasa-foot { flex-shrink:0; border-top:1.5px dashed var(--rule-strong); background:linear-gradient(180deg, rgba(255,255,255,0.5), color-mix(in srgb, var(--paper-warm) 70%, transparent)); padding:18px 38px 26px; display:none; flex-direction:column; gap:14px; }
.kasa-foot[data-visible="true"] { display:flex; }
.kasa-foot__pre { display:grid; grid-template-columns:1fr auto; align-items:baseline; font-size:17px; color:var(--ink-soft); }
.kasa-foot__pre .v { font-family:var(--k-mono); font-variant-numeric:tabular-nums; font-size:19px; }

.kasa-savings { display:none; align-items:center; gap:18px; padding:16px 18px; border-radius:18px;
  background:radial-gradient(120% 160% at 12% 0%, color-mix(in srgb, var(--accent-light) 22%, transparent), transparent 60%), linear-gradient(180deg, color-mix(in srgb, var(--brand) 10%, transparent), color-mix(in srgb, var(--brand) 5%, transparent));
  border:1px solid color-mix(in srgb, var(--brand) 22%, transparent); position:relative; overflow:hidden; }
.kasa-savings[data-visible="true"] { display:flex; animation:kasa-pop-in 520ms var(--k-ease); }
@keyframes kasa-pop-in { from { opacity:0; transform:translateY(10px) scale(0.97);} to { opacity:1; transform:none;} }
.kasa-wallet { position:relative; width:76px; height:70px; flex-shrink:0; }
.kasa-wallet svg { position:absolute; inset:0; width:100%; height:100%; overflow:visible; }
/* Wallet-glyph fills shared by .kasa-wallet and .kasa-card__savings .big-wallet
   (both render the _kasa_wallet partial). Scoped at .kasa so one rule retints
   every wallet on screen. */
.kasa .w-back   { fill:var(--brand-deep); }
.kasa .w-flap   { fill:var(--brand); }
.kasa .w-pocket { fill:color-mix(in srgb, var(--brand-deep) 76%, #000); }
.kasa .w-coin   { fill:var(--accent); }
.kasa .w-coin-in{ fill:var(--accent-deep); }
.kasa-wallet.bump { animation:kasa-wallet-bump 360ms var(--k-ease); }
@keyframes kasa-wallet-bump { 0% { transform:translateY(0);} 30% { transform:translateY(4px) scale(0.97,1.03);} 100% { transform:translateY(0);} }
.kasa-coin { position:absolute; left:50%; top:-34px; width:26px; height:26px; margin-left:-13px; border-radius:50%; background:radial-gradient(circle at 35% 30%, var(--accent-light), var(--accent) 60%, var(--accent-deep)); box-shadow:inset 0 -2px 3px rgba(0,0,0,0.25), 0 3px 6px rgba(0,0,0,0.25); display:grid; place-items:center; font-family:var(--k-display); font-weight:700; font-size:12px; color:var(--coin-ink); z-index:3; animation:kasa-coin-drop 760ms cubic-bezier(0.5,0,0.7,1) forwards; }
.kasa-coin::after { content:"zł"; }
@keyframes kasa-coin-drop { 0% { opacity:0; transform:translateY(-12px) scale(0.6) rotate(-20deg);} 25% { opacity:1;} 70% { opacity:1; transform:translateY(26px) scale(1) rotate(8deg);} 100% { opacity:0; transform:translateY(34px) scale(0.7) rotate(14deg);} }
.kasa-savings__body { flex:1; min-width:0; }
.kasa-savings__label { font-family:var(--k-display); font-style:italic; font-weight:500; font-size:19px; color:var(--brand-deep); letter-spacing:-0.01em; }
.kasa-savings__amount { font-family:var(--k-mono); font-weight:700; font-variant-numeric:tabular-nums; font-size:34px; line-height:1.05; color:var(--brand); letter-spacing:-0.01em; }
.kasa-savings__amount .cur { font-size:0.55em; color:var(--brand-deep); margin-left:4px; }

.kasa-pay { display:grid; grid-template-columns:1fr auto auto; align-items:center; gap:16px; margin-top:2px; padding:20px 26px; border-radius:20px;
  background:linear-gradient(165deg, var(--brand-bright) 0%, var(--brand) 45%, var(--brand-deep) 100%); color:#fff; box-shadow:0 18px 38px -16px color-mix(in srgb, var(--brand) 75%, transparent), inset 0 1px 0 rgba(255,255,255,0.25); position:relative; overflow:hidden; }
.kasa-pay::before { content:""; position:absolute; inset:0; background:linear-gradient(105deg, transparent 35%, rgba(255,255,255,0.22) 50%, transparent 65%); transform:translateX(-120%); animation:kasa-shine 4.2s ease-in-out infinite; }
@keyframes kasa-shine { 0%,55% { transform:translateX(-120%);} 80%,100% { transform:translateX(120%);} }
.kasa-pay__label { font-size:17px; font-weight:600; opacity:0.92; }
.kasa-pay__amount { font-family:var(--k-mono); font-weight:700; font-variant-numeric:tabular-nums; font-size:40px; line-height:1; letter-spacing:-0.02em; }
.kasa-pay__amount .cur { font-size:0.5em; opacity:0.85; margin-left:4px; }
.kasa-pay__arrow { width:44px; height:44px; display:grid; place-items:center; border-radius:50%; background:rgba(255,255,255,0.18); }
.kasa-pay__arrow svg { width:22px; height:22px; }

/* ---- summary ---- */
.kasa-summary { position:absolute; inset:0; z-index:30; display:none; align-items:center; justify-content:center; padding:40px; background:radial-gradient(80% 70% at 50% 30%, var(--panel-glow), transparent 70%), linear-gradient(160deg, var(--panel-c) 0%, var(--panel-d) 100%); }
.kasa-summary[data-visible="true"] { display:flex; animation:kasa-fade 280ms ease-out; }
@keyframes kasa-fade { from { opacity:0;} to { opacity:1;} }
.kasa-confetti { position:absolute; inset:0; overflow:hidden; pointer-events:none; }
.kasa-confetti-piece { position:absolute; top:-20px; width:10px; height:14px; opacity:0; animation:kasa-confetti-fall linear forwards; }
@keyframes kasa-confetti-fall { 0% { opacity:0; transform:translateY(-20px) rotate(0);} 10% { opacity:1;} 100% { opacity:0.9; transform:translateY(105vh) rotate(540deg);} }
/* margin:auto centres the card when it fits but, on a short kiosk display where
   the card is taller than the receipt pane, the cross-axis auto margins collapse
   to 0 and pin it to the TOP (auto margins never overflow the start edge) — so
   the logo at the top is never clipped (only the trailing welcome line may clip,
   which the goodbye can afford). Compact padding/gap keep the whole card on
   shorter screens. */
.kasa-card { position:relative; margin:auto; width:min(560px,94%); background:radial-gradient(rgba(32,32,26,0.035) 1px, transparent 1.5px), linear-gradient(180deg, var(--card), var(--paper-warm)); background-size:8px 8px, 100% 100%; border-radius:22px; padding:32px 48px 28px; text-align:center; box-shadow:0 40px 90px -30px rgba(0,0,0,0.7), inset 0 1px 0 rgba(255,255,255,0.8); display:flex; flex-direction:column; gap:16px; animation:kasa-card-in 520ms var(--k-ease) both; }
@keyframes kasa-card-in { from { opacity:0; transform:translateY(26px) scale(0.96);} to { opacity:1; transform:none;} }
.kasa-card::before { content:""; position:absolute; top:-9px; left:22px; right:22px; height:18px; background:radial-gradient(circle at 9px 9px, transparent 8px, var(--card) 8.5px) 0 0 / 18px 18px repeat-x; filter:drop-shadow(0 -3px 4px rgba(0,0,0,0.12)); }
.kasa-card__thanks { font-family:var(--k-display); font-style:italic; font-weight:500; font-size:clamp(40px,6vw,58px); line-height:0.96; letter-spacing:-0.02em; color:var(--ink); animation:kasa-rise 460ms var(--k-ease) 120ms both; }
.kasa-card__sub { font-size:14px; text-transform:uppercase; letter-spacing:0.28em; color:var(--ink-faint); animation:kasa-rise 460ms var(--k-ease) 200ms both; }
.kasa-card__savings { display:none; flex-direction:column; align-items:center; gap:10px; margin:4px auto; padding:26px 28px 22px; border-radius:20px; background:radial-gradient(120% 150% at 50% 0%, color-mix(in srgb, var(--accent-light) 30%, transparent), transparent 65%), linear-gradient(180deg, color-mix(in srgb, var(--brand) 12%, transparent), color-mix(in srgb, var(--brand) 6%, transparent)); border:1px solid color-mix(in srgb, var(--brand) 28%, transparent); position:relative; overflow:hidden; animation:kasa-rise 500ms var(--k-ease) 320ms both; }
.kasa-card__savings[data-visible="true"] { display:flex; }
.kasa-card__savings .big-wallet { position:relative; width:96px; height:88px; margin-bottom:4px; }
.kasa-card__savings .big-wallet svg { width:100%; height:100%; overflow:visible; }
.kasa-card__savings-label { font-family:var(--k-display); font-style:italic; font-weight:500; font-size:22px; color:var(--brand-deep); }
.kasa-card__savings-amount { font-family:var(--k-mono); font-weight:700; font-variant-numeric:tabular-nums; font-size:clamp(46px,8vw,64px); line-height:1; letter-spacing:-0.02em; color:var(--brand); }
.kasa-card__savings-amount .cur { font-size:0.45em; color:var(--brand-deep); margin-left:6px; }
.kasa-card__total-label { font-family:var(--k-display); font-variant:small-caps; letter-spacing:0.16em; font-size:15px; color:var(--ink-soft); }
.kasa-card__total { font-family:var(--k-mono); font-weight:700; font-variant-numeric:tabular-nums; font-size:clamp(54px,10vw,80px); line-height:1; letter-spacing:-0.03em; color:var(--ink); animation:kasa-rise 500ms var(--k-ease) 420ms both; }
.kasa-card__total .cur { font-size:0.36em; color:var(--ink-soft); margin-left:6px; }
.kasa-card__rows { display:flex; flex-direction:column; gap:12px; padding-top:20px; border-top:1.5px dashed var(--rule-strong); margin:0; }
.kasa-card__row { display:grid; grid-template-columns:max-content 1fr max-content; align-items:baseline; animation:kasa-rise 420ms var(--k-ease) both; }
.kasa-card__row:nth-child(1) { animation-delay:520ms; } .kasa-card__row:nth-child(2) { animation-delay:580ms; } .kasa-card__row:nth-child(3) { animation-delay:640ms; }
.kasa-card__row dt { font-family:var(--k-display); font-variant:small-caps; letter-spacing:0.12em; font-size:16px; color:var(--ink-soft); white-space:nowrap; margin:0; }
.kasa-card__row::after { content:""; grid-column:2; align-self:center; height:2px; margin:0 14px; background-image:radial-gradient(var(--rule-strong) 1px, transparent 1.4px); background-size:8px 2px; background-repeat:repeat-x; transform:translateY(0.2em); }
.kasa-card__row dd { font-family:var(--k-mono); font-weight:600; font-variant-numeric:tabular-nums; font-size:19px; color:var(--ink); margin:0; }
.kasa-card__welcome { padding-top:18px; border-top:1.5px dashed var(--rule-strong); font-family:var(--k-display); font-style:italic; font-size:22px; color:var(--ink-soft); animation:kasa-rise 460ms var(--k-ease) 720ms both; }
@keyframes kasa-rise { from { opacity:0; transform:translateY(12px);} to { opacity:1; transform:none;} }

/* ---- lab chrome (operator-only) ---- */
.kasa-lab { position:relative; width:100vw; height:100vh; overflow:hidden; background:#0c0d0a; }
.kasa-lab__close { position:absolute; top:16px; right:18px; z-index:60; width:40px; height:40px; display:grid; place-items:center; border-radius:50%; background:rgba(0,0,0,0.55); color:#fff; text-decoration:none; }
.kasa-dock { position:fixed; left:50%; bottom:18px; transform:translateX(-50%); z-index:60; display:flex; gap:8px; padding:8px; border-radius:16px; background:rgba(12,13,10,0.82); backdrop-filter:blur(10px); box-shadow:0 12px 30px -10px rgba(0,0,0,0.6); }
.kasa-dock button { font-family:var(--k-ui); font-size:13px; font-weight:600; color:#f3f1e8; background:rgba(255,255,255,0.08); border:1px solid rgba(255,255,255,0.12); padding:9px 16px; border-radius:10px; cursor:pointer; }
.kasa-dock button:hover { background:rgba(255,255,255,0.16); }
.kasa-dock button.accent { background:var(--brand); border-color:var(--brand-bright); }
.kasa-dock__label { color:rgba(243,241,232,0.5); font-size:11px; align-self:center; padding:0 8px 0 4px; letter-spacing:0.04em; }
.kasa-dock__sep { width:1px; background:rgba(255,255,255,0.15); margin:4px 2px; }
