/* ==========================================================================
   SaksiBot admin — design system
   ========================================================================== */
:root {
  --green-900: #143d18;
  --green-800: #1b5e20;
  --green-700: #2e7d32;
  --green-600: #388e3c;
  --green-100: #e8f5e9;
  --green-50:  #f2f8f2;
  --ink:       #17281a;
  --ink-2:     #44544a;
  --muted:     #5c6b5c;   /* WCAG AA (~4.9:1 on white); was #71806f (~4.0:1, failed) */
  --line:      #e0e8e0;
  --bg:        #f4f7f4;
  --card:      #ffffff;
  --danger:    #b3261e;
  --danger-bg: #fdecea;
  --amber-bg:  #fff7e6;
  --amber:     #8a5a00;
  --radius:    12px;
  --shadow:    0 1px 2px rgba(20, 40, 22, 0.06), 0 4px 14px rgba(20, 40, 22, 0.05);
  --shadow-lg: 0 8px 30px rgba(20, 40, 22, 0.14);
  --sidebar-w: 232px;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; font-family: var(--font); background: var(--bg);
  color: var(--ink); line-height: 1.5; font-size: 15px;
}
a { color: var(--green-800); text-decoration: none; }
a:hover { text-decoration: underline; }
h1 { font-size: 1.45rem; margin: 0; letter-spacing: -0.01em; }
h2 { font-size: 1.02rem; margin: 1.6rem 0 0.6rem; color: var(--ink-2);
     text-transform: uppercase; letter-spacing: 0.05em; font-size: 0.82rem; }

/* ---- layout ---- */
.shell { display: flex; min-height: 100vh; }
.sidebar {
  width: var(--sidebar-w); flex: 0 0 var(--sidebar-w);
  background: linear-gradient(180deg, var(--green-900), var(--green-800));
  color: #eaf3ea; display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh;
}
.sidebar .brand {
  display: flex; align-items: center; gap: 0.6rem;
  font-weight: 800; font-size: 1.12rem; letter-spacing: 0.01em;
  padding: 1.1rem 1.2rem 0.9rem; color: #fff;
}
.sidebar .brand .leaf { font-size: 1.3rem; }
.sidebar nav { display: flex; flex-direction: column; gap: 2px; padding: 0.4rem 0.7rem; }
.sidebar nav a {
  display: flex; align-items: center; gap: 0.65rem;
  color: #cfe0cf; padding: 0.55rem 0.75rem; border-radius: 9px;
  font-size: 0.93rem; font-weight: 500;
}
.sidebar nav a svg { width: 17px; height: 17px; flex: 0 0 17px; opacity: 0.85; }
.sidebar nav a:hover { background: rgba(255,255,255,0.08); color: #fff; text-decoration: none; }
.sidebar nav a.active { background: rgba(255,255,255,0.16); color: #fff; font-weight: 600; }
/* Red count on the Razgovori link — how many customers are waiting, from any page. */
.sidebar nav a .navcount {
  margin-left: auto; background: #ff7a70; color: #3a0d09; font-weight: 800;
  font-size: 0.72rem; min-width: 1.35rem; text-align: center; border-radius: 999px;
  padding: 0.05rem 0.4rem;
}
.sidebar .foot { margin-top: auto; padding: 1rem 1.2rem; display: flex; flex-direction: column; gap: 0.7rem; }
.statuspill {
  display: inline-flex; align-items: center; gap: 0.45rem;
  font-size: 0.8rem; font-weight: 600; border-radius: 999px;
  padding: 0.3rem 0.75rem; background: rgba(255,255,255,0.12); color: #fff;
}
.statuspill .dot { width: 8px; height: 8px; border-radius: 50%; background: #7ce07f; box-shadow: 0 0 6px #7ce07f; }
.statuspill.off .dot { background: #ff7a70; box-shadow: 0 0 6px #ff7a70; }

/* Each lamp is also its own switch — a whole button, so it is hard to miss and
   hard to hit by accident. Amber means running but unwell: recent failures, or
   the day's allowance nearly spent. */
.sidebar .foot .pillform { margin-bottom: 0.35rem; }
button.statuspill {
  width: 100%; justify-content: flex-start; cursor: pointer;
  border: 1px solid rgba(255,255,255,0.18); font-family: inherit; text-align: left;
}
button.statuspill:hover { background: rgba(255,255,255,0.2); }
button.statuspill.warn .dot { background: #ffc861; box-shadow: 0 0 6px #ffc861; }
button.statuspill.off  .dot { background: #ff7a70; box-shadow: 0 0 6px #ff7a70; }
button.statuspill.off  { opacity: 0.75; }
button.statuspill .pilllabel { flex: 1; }

/* A switch that also reads as one. Colour alone is a poor signal — it is the first
   thing lost to a dim screen or to colour blindness — so the knob's position carries
   the same information in shape. */
.statuspill .knob {
  flex: none; width: 26px; height: 15px; border-radius: 999px; position: relative;
  background: rgba(255,255,255,0.22); transition: background 0.15s ease;
}
.statuspill .knob i {
  position: absolute; top: 2px; left: 2px; width: 11px; height: 11px; border-radius: 50%;
  background: #fff; transition: left 0.15s ease;
}
.statuspill.on   .knob { background: rgba(124,224,127,0.75); }
.statuspill.warn .knob { background: rgba(255,200,97,0.8); }
.statuspill.on   .knob i, .statuspill.warn .knob i { left: 13px; }
.statuspill.off  .knob { background: rgba(255,122,112,0.45); }
.statuspill.off  .knob i { left: 2px; }
.sidebar .foot .stopall, .sidebar .foot .startall {
  width: 100%; border-radius: 8px; padding: 0.4rem 0.7rem; cursor: pointer;
  font-size: 0.82rem; font-family: inherit; margin-bottom: 0.5rem;
}
.sidebar .foot .stopall {
  background: rgba(255,122,112,0.16); border: 1px solid rgba(255,122,112,0.5); color: #ffd9d5;
}
.sidebar .foot .stopall:hover { background: rgba(255,122,112,0.28); }
/* Once everything is off, the same button in the same place is the way back on. */
.sidebar .foot .startall {
  background: rgba(124,224,127,0.18); border: 1px solid rgba(124,224,127,0.55); color: #dcf5dd;
}
.sidebar .foot .startall:hover { background: rgba(124,224,127,0.3); }
.sidebar .foot form button {
  width: 100%; background: transparent; border: 1px solid rgba(255,255,255,0.35);
  color: #eaf3ea; border-radius: 8px; padding: 0.4rem 0.7rem; cursor: pointer; font-size: 0.85rem;
}
.sidebar .foot form button:hover { background: rgba(255,255,255,0.1); }

.content { flex: 1; min-width: 0; padding: 1.6rem 2rem 3rem; }
.pagehead { display: flex; align-items: center; gap: 1rem; margin-bottom: 1.2rem; flex-wrap: wrap; }
.pagehead .sub { color: var(--muted); font-size: 0.9rem; flex-basis: 100%; margin-top: 0.15rem; }

/* ---- cards & stats ---- */
.card {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.1rem 1.3rem; margin-bottom: 1rem; box-shadow: var(--shadow);
}
.statgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 0.9rem; margin-bottom: 0.5rem; }
.stat {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1rem 1.1rem; box-shadow: var(--shadow);
}
.stat .num { font-size: 1.75rem; font-weight: 800; color: var(--green-700); letter-spacing: -0.02em; }
.stat .lbl { font-size: 0.78rem; color: var(--muted); margin-top: 0.1rem; }
a.stat { text-decoration: none; color: inherit; display: block; }
a.stat:hover { text-decoration: none; }

/* ---- tables ---- */
.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: 0.88rem; }
th, td { text-align: left; padding: 0.55rem 0.65rem; border-bottom: 1px solid var(--line); vertical-align: middle; }
th { color: var(--muted); font-weight: 600; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em; }
tbody tr:hover, tr.hoverable:hover { background: var(--green-50); }
tr:last-child td { border-bottom: none; }

/* ---- badges & chips ---- */
.badge {
  display: inline-block; padding: 0.13rem 0.55rem; border-radius: 999px;
  font-size: 0.72rem; font-weight: 600; background: var(--green-100); color: var(--green-800);
  white-space: nowrap;
}
.badge.off { background: var(--danger-bg); color: var(--danger); }
.badge.gray { background: #edf1ed; color: #5c6b5c; }
.badge.amber { background: var(--amber-bg); color: var(--amber); }
.kw {
  display: inline-flex; align-items: center; background: var(--green-100); color: var(--green-800);
  border-radius: 7px; padding: 0.16rem 0.3rem 0.16rem 0.55rem; margin: 0.12rem; font-size: 0.85rem; font-weight: 500;
}
.kw.exclude { background: var(--danger-bg); color: var(--danger); text-decoration: line-through; }
.kw form { display: inline; margin: 0; }
.kw button { background: none; border: none; color: inherit; cursor: pointer; padding: 0 0.25rem; font-size: 0.8rem; opacity: 0.6; }
.kw button:hover { opacity: 1; }

/* ---- buttons & forms ---- */
button, input, select, textarea { font-family: var(--font); }
.btn, button.primary, button.subtle, button.danger {
  border-radius: 9px; cursor: pointer; font-size: 0.88rem; font-weight: 600;
  padding: 0.5rem 1rem; border: 1px solid transparent; transition: all 0.12s ease;
}
button.primary { background: var(--green-700); color: #fff; }
button.primary:hover { background: var(--green-800); box-shadow: var(--shadow); }
button.subtle { background: #fff; color: var(--ink-2); border-color: var(--line); padding: 0.38rem 0.8rem; font-size: 0.82rem; }
button.subtle:hover { border-color: var(--green-600); color: var(--green-800); }
button.danger { background: #fff; color: var(--danger); border-color: #f0c9c5; padding: 0.38rem 0.8rem; font-size: 0.82rem; }
button.danger:hover { background: var(--danger-bg); }
input[type="text"], input[type="number"], input[type="password"], select, textarea {
  border: 1.5px solid var(--line); border-radius: 9px; padding: 0.5rem 0.7rem;
  font-size: 0.9rem; background: #fff; max-width: 100%; color: var(--ink);
  transition: border-color 0.12s ease;
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--green-600); }
/* One visible focus ring for keyboard and switch users, across buttons, links, tabs,
   toggles and inputs. Only on keyboard focus (:focus-visible), so mouse clicks stay clean.
   A light variant for the dark green sidebar, where a dark ring would vanish. */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--green-600); outline-offset: 2px; border-radius: 6px;
}
.sidebar a:focus-visible, .sidebar button:focus-visible {
  outline: 2px solid #cfe0cf; outline-offset: 2px;
}
textarea { width: 100%; min-height: 96px; resize: vertical; line-height: 1.45; }
select { cursor: pointer; }
label { font-size: 0.88rem; color: var(--ink-2); }
form.inline { display: inline-flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; margin: 0; }
form.stack { display: flex; flex-direction: column; gap: 0.8rem; max-width: 520px; }
/* 520px is a good measure for one column of prose-width fields, and a terrible one
   for a row of three cards — it left each credential column about 170px wide, one
   word per line. Pages that lay their fields out side by side opt out of the cap. */
form.stack.wide { max-width: none; }
form.stack label { display: flex; flex-direction: column; gap: 0.3rem; font-weight: 500; }
.switch { display: inline-flex; align-items: center; gap: 0.55rem; cursor: pointer; }
.switch input { width: 42px; height: 24px; appearance: none; background: #ccd6cc; border-radius: 999px; position: relative; cursor: pointer; transition: background 0.15s; }
.switch input:checked { background: var(--green-600); }
.switch input::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px;
  border-radius: 50%; background: #fff; transition: left 0.15s; box-shadow: 0 1px 3px rgba(0,0,0,0.25);
}
.switch input:checked::after { left: 21px; }

.muted { color: var(--muted); font-size: 0.85rem; }
.pill-row { display: flex; gap: 0.55rem; flex-wrap: wrap; align-items: center; }
.spacer { flex: 1; }
.empty {
  text-align: center; color: var(--muted); padding: 2.2rem 1rem; font-size: 0.92rem;
}
.empty .big { font-size: 1.8rem; display: block; margin-bottom: 0.4rem; }

/* ---- IG posts grid ---- */
.postgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1rem; }
.postcard {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; box-shadow: var(--shadow); display: flex; flex-direction: column;
}
.postcard .thumbwrap { position: relative; aspect-ratio: 1 / 1; background: var(--green-50); overflow: hidden; }
.postcard img { width: 100%; height: 100%; object-fit: cover; display: block; }
.postcard .typechip { position: absolute; top: 8px; right: 8px; }
.postcard .body { padding: 0.8rem 0.95rem 1rem; display: flex; flex-direction: column; gap: 0.55rem; flex: 1; }
.postcard .cap { font-size: 0.86rem; color: var(--ink-2); min-height: 2.4em; }
.postcard .maprow { display: flex; gap: 0.45rem; align-items: center; flex-wrap: wrap; margin-top: auto; }
.postcard select { flex: 1; min-width: 0; font-size: 0.84rem; padding: 0.4rem 0.5rem; }

/* ---- toast ---- */
.toast {
  position: fixed; bottom: 1.6rem; left: 50%; transform: translateX(-50%);
  background: var(--green-900); color: #fff; font-weight: 600; font-size: 0.92rem;
  padding: 0.75rem 1.4rem; border-radius: 999px; box-shadow: var(--shadow-lg);
  z-index: 1000; animation: toast-in 0.25s ease, toast-out 0.4s ease 3.2s forwards;
}
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, 12px); } to { opacity: 1; transform: translate(-50%, 0); } }
@keyframes toast-out { to { opacity: 0; transform: translate(-50%, 10px); visibility: hidden; } }

/* ---- login ---- */
.login-wrap {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  background: linear-gradient(160deg, var(--green-900) 0%, var(--green-700) 100%);
}
.login-box {
  width: min(370px, 92vw); background: #fff; border-radius: 18px;
  padding: 2.2rem 2rem; box-shadow: var(--shadow-lg);
}
.login-box h1 { text-align: center; margin-bottom: 0.4rem; }
.login-box .tag { text-align: center; color: var(--muted); font-size: 0.85rem; margin: 0 0 1.4rem; }
.login-box input { width: 100%; padding: 0.65rem 0.8rem; }
.login-box button { width: 100%; padding: 0.65rem; font-size: 0.95rem; }
.alert {
  background: var(--amber-bg); border: 1px solid #ffe0b2; color: var(--amber);
  border-radius: 10px; padding: 0.65rem 0.95rem; margin-bottom: 1rem; font-size: 0.88rem;
}
.alert.error { background: var(--danger-bg); border-color: #f0c9c5; color: var(--danger); }

/* ---- responsive ---- */
@media (max-width: 860px) {
  .shell { flex-direction: column; }
  .sidebar { width: 100%; flex-basis: auto; height: auto; position: static; }
  .sidebar nav { flex-direction: row; flex-wrap: wrap; }
  .content { padding: 1.1rem 1rem 2.5rem; }
  /* The three status pills share a row, but "Zaustavi sve" — which cuts off every
     automatic reply — stays a single full-width bar so it is never lost in a wrap. */
  .sidebar .foot { flex-direction: row; flex-wrap: wrap; gap: 0.5rem; align-items: center; padding-top: 0; }
  .sidebar .foot .pillform { flex: 1 1 46%; margin-bottom: 0; }
  .sidebar .foot > form:not(.pillform) { flex: 1 1 100%; }
  .sidebar .foot .stopall, .sidebar .foot .startall { margin-bottom: 0; }
}

/* ---- connections page (Povezivanje) ---- */
.cardtitle {
  margin: 0 0 0.9rem; font-size: 0.82rem; text-transform: uppercase;
  letter-spacing: 0.05em; color: var(--ink-2);
}
.connfield { padding: 0.75rem 0; border-top: 1px solid var(--line); }
.connfield:first-of-type { border-top: 0; padding-top: 0; }
.connhead { display: flex; align-items: center; gap: 0.55rem; margin-bottom: 0.35rem; }
.connhead label { font-weight: 600; font-size: 0.92rem; }
.connval {
  margin-left: auto; font-size: 0.8rem; color: var(--ink-2);
  background: var(--green-50); border: 1px solid var(--line);
  border-radius: 6px; padding: 0.1rem 0.45rem; max-width: 46%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.badge-ui   { background: var(--green-100); color: var(--green-800); }
.badge-env  { background: #edf1ed; color: #5c6b5c; }
.badge-none { background: var(--amber-bg); color: var(--amber); }
.connfield input[type="text"], .connfield input[type="password"] {
  width: 100%; padding: 0.5rem 0.65rem; border: 1px solid var(--line);
  border-radius: 8px; font-size: 0.9rem; font-family: var(--font);
  background: #fff;
}
.connfield input:focus { outline: 2px solid var(--green-600); outline-offset: -1px; border-color: var(--green-600); }
.connfoot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.8rem; margin-top: 0.3rem; font-size: 0.82rem;
  /* Hint and "vrati na .env" used to collide and spill outside the card once these
     sat in columns; let them stack instead of overlapping. */
  flex-wrap: wrap;
}
.connfoot .muted { flex: 1 1 12rem; min-width: 0; }
.clearbox { display: flex; align-items: center; gap: 0.3rem; color: var(--danger); white-space: nowrap; font-size: 0.82rem; }
.row-actions { display: flex; gap: 0.6rem; margin-top: 0.9rem; }

/* ---- conversations per post (Razgovori o objavi) ---- */
.talkslink {
  display: inline-block; margin-top: 0.45rem; font-size: 0.85rem;
  font-weight: 600; color: var(--green-800);
}
.talkslink.muted { font-weight: 400; color: var(--muted); }
.talkshead { display: flex; gap: 1rem; align-items: flex-start; }
.talksthumb {
  width: 96px; height: 96px; object-fit: cover; border-radius: 10px;
  flex: 0 0 96px; border: 1px solid var(--line);
}
.talksmeta { display: flex; flex-direction: column; gap: 0.35rem; min-width: 0; }
.thread .threadhead { margin-bottom: 0.7rem; }
.avatar {
  width: 30px; height: 30px; border-radius: 50%; flex: 0 0 30px;
  background: linear-gradient(135deg, var(--green-700), var(--green-900));
  color: #fff; font-weight: 700; text-transform: uppercase;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 0.9rem;
}
.chat { display: flex; flex-direction: column; gap: 0.5rem; }
.chat .msg { display: flex; }
.chat .msg.in  { justify-content: flex-start; }
.chat .msg.out { justify-content: flex-end; }
.chat .bubble {
  max-width: 78%; padding: 0.55rem 0.8rem; border-radius: 14px;
  box-shadow: var(--shadow); font-size: 0.92rem; line-height: 1.45;
}
.chat .msg.in .bubble {
  background: #fff; border: 1px solid var(--line);
  border-bottom-left-radius: 4px;
}
.chat .msg.out .bubble {
  background: var(--green-100); border: 1px solid #d3e9d4;
  border-bottom-right-radius: 4px;
}
.chat .chn {
  display: block; font-size: 0.7rem; font-weight: 700; letter-spacing: 0.03em;
  color: var(--ink-2); text-transform: uppercase; margin-bottom: 0.15rem;
}
.chat .txt { white-space: pre-wrap; word-break: break-word; }
.chat .ts { display: block; font-size: 0.72rem; color: var(--muted); margin-top: 0.25rem; text-align: right; }

/* A message the customer unsent, and one that never reached them: both are still
   shown (the thread must not quietly change shape) but plainly not current. */
.chat .bubble.withdrawn .txt { text-decoration: line-through; opacity: 0.6; }
.chat .bubble.withdrawn { background: #f6f8f6; }
.chat .bubble.undelivered { background: var(--danger-bg); border-color: #f0c9c5; }

/* Tap-to-react heart, shown on each customer message. Discreet until you look for it,
   then a real 44px tap target for a thumb. */
.chat .msg.in .bubble { position: relative; }
.reactbtn {
  position: absolute; top: -10px; right: -8px;
  min-width: 30px; min-height: 30px; padding: 0 0.35rem;
  border: 1px solid var(--line); border-radius: 999px; background: #fff;
  font-size: 0.95rem; line-height: 1; cursor: pointer; box-shadow: var(--shadow);
  opacity: 0.55; transition: opacity 0.12s ease, transform 0.06s ease;
}
.reactbtn:hover { opacity: 1; transform: scale(1.08); }
.reactbtn:disabled { cursor: default; opacity: 1; }
@media (max-width: 860px) { .reactbtn { opacity: 0.85; min-width: 34px; min-height: 34px; } }

/* A long thread scrolls inside its own box and opens at the newest message,
   so the reply field is always where you left it rather than a page-scroll away. */
.chat { max-height: 58vh; overflow-y: auto; padding-right: 0.3rem; }
.chatmedia { max-width: 240px; max-height: 260px; border-radius: 10px; display: block; margin: 0.2rem 0; }
.replybox { display: flex; gap: 0.6rem; align-items: flex-end; margin-top: 0.9rem; }
.replybox textarea {
  flex: 1; resize: vertical; min-height: 2.6rem; font: inherit; font-size: 0.92rem;
  padding: 0.55rem 0.7rem; border: 1px solid var(--line); border-radius: 10px;
}
.replybox textarea:focus { outline: 2px solid var(--green-100); border-color: #b9d9bb; }
.replybox button { white-space: nowrap; }
.statusbar { display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; }

/* The three outside services the bot depends on, side by side — they are read as a
   set ("is everything connected?"), so they belong on one line. Email is not one of
   them: it is how the bot reaches us, so it keeps its own full-width row below.
   Collapses to two columns, then one, rather than squeezing the key fields. */
/* A dashboard section heading is where you look when the five rows under it are not
   enough — so that is where the way to the rest of them belongs. */
h2.seeall { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
h2.seeall a { font-size: 0.85rem; font-weight: 600; }

.conngrid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem; }
.conngrid > .card { margin: 0; }
@media (max-width: 1180px) { .conngrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 780px)  { .conngrid { grid-template-columns: 1fr; } }

/* Red where a person is needed, green where the bot finished by itself — the two
   things worth spotting from across the room. */
.badge.red   { background: var(--danger-bg); color: var(--danger); }
.badge.green { background: var(--green-100); color: var(--green-800); }
tr.row-wait > td { background: rgba(214, 69, 59, 0.06); }
tr.row-wait > td:first-child { box-shadow: inset 3px 0 0 var(--danger); }
tr.row-done > td { background: rgba(76, 145, 80, 0.06); }
tr.row-done > td:first-child { box-shadow: inset 3px 0 0 var(--green-800); }
/* Ticked off by hand: faded, because it is done with — but still legible, because
   it un-ticks itself the moment the customer writes again. */
tr.row-resolved > td { background: #f6f8f6; opacity: 0.62; }
tr.row-resolved > td:first-child { box-shadow: inset 3px 0 0 #9bb69d; }
.legend .sw.resolved { background: #9bb69d; }

/* ---- legend ----
   Every page says what its own words mean, in the same shape everywhere: the mark
   itself on the left, exactly as it appears in the table above, and the plain-language
   meaning on the right. Showing the real badge rather than describing it is the point —
   the eye matches shapes far faster than it matches names to definitions. */
.legend {
  margin-top: 1.2rem; border: 1px solid var(--line); border-radius: var(--radius);
  background: linear-gradient(180deg, #fbfdfb, #f6faf6);
  overflow: hidden; box-shadow: var(--shadow);
}
.legend-title {
  display: flex; align-items: center; gap: 0.45rem;
  padding: 0.65rem 1.1rem; border-bottom: 1px solid var(--line);
  background: #fff; font-weight: 700; font-size: 0.88rem; color: var(--ink);
  letter-spacing: 0.01em;
}
.legend dl { margin: 0; padding: 0.35rem 0; }
.legend-item {
  display: grid; grid-template-columns: minmax(9rem, 15rem) 1fr; gap: 0.2rem 1rem;
  padding: 0.55rem 1.1rem; align-items: start;
}
.legend-item + .legend-item { border-top: 1px dashed var(--line); }
.legend-item dt { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
.legend-item dd {
  margin: 0; font-size: 0.85rem; color: var(--ink-2); line-height: 1.5;
}
.legend-item dd b, .legend-item dd strong { color: var(--ink); }
@media (max-width: 720px) {
  .legend-item { grid-template-columns: 1fr; }
}
/* small colour chip, for rows whose mark is a row tint rather than a badge */
.legend .sw {
  display: inline-block; width: 12px; height: 12px; border-radius: 3px;
  border: 1px solid rgba(0,0,0,0.08);
}
.legend .sw.wait { background: var(--danger); }
.legend .sw.done { background: var(--green-800); }
.legend .sw.run  { background: #9bb69d; }
.legend .sw.resolved { background: #9bb69d; }

/* ---- brand logo, login, tabs, customer list ---- */
.brandlogo { width: 26px; height: 26px; border-radius: 7px; }
/* The brand is a link home now, so it must not look like body text. */
a.brand { text-decoration: none; }
a.brand:hover { text-decoration: none; opacity: 0.85; }

/* The assistant's face, wherever a row or a legend refers to it. */
.boticon { width: 22px; height: 22px; border-radius: 6px; vertical-align: middle; }
.statecell { text-align: center; font-size: 1.05rem; width: 44px; }
.statecell .okmark { color: var(--green-700); }

/* Whole-row highlight on hover — the eye follows the line it is reading, and the row
   tints (waiting / done / resolved) must not swallow it. */
tbody tr.hoverable:hover > td,
tbody tr.hoverable:hover > td:first-child { background: #eaf4ea; transition: background 0.08s ease; }
tbody tr.hoverable { cursor: default; }

/* The customer's own words in the log — one line, full text on hover. */
.logmsg {
  max-width: 34rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-size: 0.85rem; color: var(--ink-2);
}
@media (max-width: 1100px) { .logmsg { max-width: 16rem; } }

/* ---- lift-on-hover, one rule per family ----
   The same gesture everywhere: a card you can read lifts a little when the pointer
   finds it. Respect users who asked their OS for less motion. */
.stat, .postcard, .healthtile {
  transition: transform 0.14s ease, box-shadow 0.14s ease,
              border-color 0.14s ease, background 0.14s ease;
}
/* A clear COLOUR cue, not just a lift: the card tints the store's green and grows a
   green top edge, so the hover is unmistakable even at a glance. */
.stat:hover, .healthtile:hover {
  transform: translateY(-2px); box-shadow: var(--shadow-lg);
  border-color: var(--green-600); background: var(--green-50);
  border-top: 2px solid var(--green-600);
}
.postcard:hover {
  transform: translateY(-3px); box-shadow: var(--shadow-lg);
  border-color: var(--green-600);
}
@media (prefers-reduced-motion: reduce) {
  .stat, .postcard, .healthtile, .tabbar a { transition: none; }
  .stat:hover, .healthtile:hover, .postcard:hover { transform: none; }
}

/* Every data table row answers the pointer — dashboard, orders, stats, rules alike. */
.card table tbody tr:hover > td,
.card table tr:hover > td { background: var(--green-100); }

/* The AI settings page uses the full width, with a small breathing gap. */
form.aiwide { max-width: 93%; }

/* ---- live toasts (SSE) ----
   They stack in a column now. The old rule nudged a second toast up to bottom:90px,
   which meant a third landed straight on top of the first.

   Each names its kind by icon and left edge, so a glance is enough: a customer
   wrote, we answered, a sale landed, something broke. They slide in from the right,
   pause while the pointer rests on them, and can be dismissed. Nothing flashes, and
   nothing is red unless it is genuinely wrong. */
.toaststack {
  position: fixed; bottom: 18px; right: 18px; z-index: 950;
  display: flex; flex-direction: column; gap: 10px;
  max-width: min(360px, calc(100vw - 36px));
  pointer-events: none;                 /* the gaps stay click-through */
}
.livetoast {
  pointer-events: auto;
  display: grid; grid-template-columns: auto 1fr auto; gap: 0.6rem;
  align-items: start;
  padding: 0.7rem 0.8rem 0.7rem 0.85rem;
  background: var(--card); color: var(--ink);
  border: 1px solid var(--line); border-left: 4px solid var(--green-600);
  border-radius: var(--radius); box-shadow: var(--shadow-lg);
  font-size: 0.88rem; line-height: 1.35;
  opacity: 0; transform: translateX(14px) scale(0.98);
  transition: opacity 0.28s ease, transform 0.28s cubic-bezier(0.2, 0.8, 0.3, 1);
}
.livetoast.show { opacity: 1; transform: translateX(0) scale(1); }
.livetoast .ticon { font-size: 1.05rem; line-height: 1.2; }
.livetoast .tbody { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.livetoast .tbody b { font-weight: 600; }
/* Long messages get two lines and an ellipsis rather than a growing wall of text. */
.livetoast .tbody span {
  color: var(--muted); overflow: hidden; display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.livetoast .tclose {
  background: none; border: 0; cursor: pointer; padding: 0 2px;
  font-size: 1.1rem; line-height: 1; color: var(--muted);
  opacity: 0.5; transition: opacity 0.15s ease, color 0.15s ease;
}
.livetoast .tclose:hover { opacity: 1; color: var(--ink); }
.livetoast.in    { border-left-color: #3f9d44; }   /* a customer wrote */
.livetoast.out   { border-left-color: #7aa7d9; }   /* we answered      */
.livetoast.order { border-left-color: #c98a2e; }   /* a sale landed    */
.livetoast.warn  { border-left-color: var(--danger); }

/* Reduced motion still gets the toast — it just appears instead of sliding. */
@media (prefers-reduced-motion: reduce) {
  .livetoast { transition: opacity 0.2s ease; transform: none; }
  .livetoast.show { transform: none; }
}

/* ---- the per-thread AI lamp ----
   A ring around the robot icon: green = the assistant may answer this customer,
   red = muted (human takeover, needs-human, or "stop"). The ring IS the signal,
   so it stays visible on row tints and in the legend alike. */
.botwrap {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 2px; border-radius: 50%; border: 2px solid transparent;
  vertical-align: middle;
}
.botwrap.livering  { border-color: #3f9d44; box-shadow: 0 0 5px rgba(63, 157, 68, 0.55); }
.botwrap.mutedring { border-color: var(--danger); box-shadow: 0 0 5px rgba(179, 38, 30, 0.45); }
.botwrap .boticon  { display: block; }

/* ---- language switch ----
   Fixed top-right on every page. Two little flags; the chosen one wears a green ring
   and full opacity, the other dims and lifts on hover so it invites the click. */
.langswitch {
  position: fixed; top: 12px; right: 16px; z-index: 60;
  display: flex; gap: 6px; padding: 4px;
  background: rgba(255,255,255,0.92); backdrop-filter: blur(6px);
  border: 1px solid var(--line); border-radius: 999px; box-shadow: var(--shadow);
}
.langswitch a {
  display: flex; align-items: center; gap: 5px;
  padding: 4px 9px 4px 5px; border-radius: 999px;
  font-size: 0.72rem; font-weight: 800; letter-spacing: 0.04em;
  color: var(--muted); text-decoration: none; opacity: 0.6;
  border: 1.5px solid transparent; transition: all 0.14s ease;
}
.langswitch a:hover { opacity: 1; transform: translateY(-1px); background: var(--green-50);
  color: var(--green-800); text-decoration: none; }
.langswitch a.on {
  opacity: 1; color: var(--green-900); background: var(--green-100);
  border-color: var(--green-600);
}
.langswitch .flag {
  width: 22px; height: 15px; border-radius: 3px; overflow: hidden;
  box-shadow: 0 0 0 1px rgba(0,0,0,0.08); flex: 0 0 auto; display: block;
}
/* On narrow screens the flags sit above the content; drop the text to save room. */
@media (max-width: 720px) {
  .langswitch { top: 8px; right: 8px; }
  .langswitch a span { display: none; }
  .langswitch a { padding: 5px; }
}
form.aiwide input[type="text"], form.aiwide input[type="number"] { width: 100%; max-width: 640px; }

.waitbanner.healthalert {
  background: var(--amber-bg); border-color: #ffe0b2; border-left-color: var(--amber);
}
.waitbanner.healthalert .waitnum { color: var(--amber); font-size: 1.3rem; }
.loginlogo { width: 42px; height: 42px; border-radius: 10px; vertical-align: middle; margin-right: 0.3rem; }
.rememberme {
  display: flex; align-items: center; gap: 0.45rem;
  font-size: 0.88rem; color: var(--ink-2);
}
.tabbar {
  display: flex; gap: 0.35rem; margin: 0.9rem 0 1.1rem;
  border-bottom: 2px solid var(--line); padding-bottom: 0;
}
.tabbar a {
  padding: 0.45rem 0.9rem; font-size: 0.9rem; font-weight: 600;
  color: var(--ink-2); border: 1px solid transparent; border-bottom: 0;
  border-radius: 9px 9px 0 0; margin-bottom: -2px;
}
.tabbar a {
  transition: background 0.15s ease, color 0.15s ease, transform 0.12s ease;
}
.tabbar a:hover { background: var(--green-100); color: var(--green-900);
  text-decoration: none; transform: translateY(-1px); }
/* The chosen tab wears the store's colour, exactly like the active item in the left
   menu — one visual language for "you are here" everywhere. */
.tabbar a.active, .tabbar a.active:hover {
  background: linear-gradient(180deg, var(--green-800), var(--green-900));
  color: #fff; border-color: var(--green-900);
  border-bottom: 2px solid var(--green-900); transform: none;
}
.customerlist { display: flex; flex-direction: column; gap: 0.55rem; }
.customerrow {
  display: flex; align-items: center; gap: 0.7rem;
  padding: 0.75rem 1rem; text-decoration: none; color: var(--ink);
  transition: transform 0.06s ease, box-shadow 0.06s ease;
}
.customerrow:hover { text-decoration: none; box-shadow: var(--shadow-lg); transform: translateY(-1px); }
.customerrow .custname { font-weight: 700; }
.customerrow .chev { color: var(--green-700); font-weight: 700; }

/* checkbox sits inline-left of its label (the .stack form widens inputs) */
.rememberme input[type="checkbox"] {
  width: auto; margin: 0; flex: 0 0 auto;
}

/* The "someone is waiting" banner — the first thing the operator should see. Red
   enough to notice, calm enough to live at the top of a dashboard every day. */
.waitbanner {
  display: flex; align-items: center; gap: 0.9rem;
  background: var(--danger-bg); border: 1px solid #f0c9c5; border-left: 4px solid var(--danger);
  color: var(--ink); border-radius: var(--radius); padding: 0.8rem 1.1rem; margin-bottom: 1rem;
  box-shadow: var(--shadow); text-decoration: none;
}
.waitbanner:hover { box-shadow: var(--shadow-lg); text-decoration: none; }
.waitbanner .waitnum {
  font-size: 1.6rem; font-weight: 800; color: var(--danger);
  min-width: 1.6em; text-align: center; line-height: 1;
}

/* ---- statistics (Statistika) ---- */
td.numcol, th.numcol { text-align: right; font-variant-numeric: tabular-nums; }
.metrichint { font-size: 0.76rem; margin-top: 0.15rem; max-width: 42ch; }
@media (max-width: 720px) { .metrichint { display: none; } }

/* A dependency-free bar chart: one flex column per day, height set inline.
   It scrolls sideways on a phone rather than crushing 30 bars into 320px. */
.chart {
  display: flex; align-items: flex-end; gap: 4px; height: 180px;
  overflow-x: auto; padding-bottom: 0.2rem;
}
.chart .bar {
  flex: 1 0 16px; min-width: 14px; height: 100%;
  display: flex; flex-direction: column; justify-content: flex-end; align-items: center;
}
.chart .barfill {
  width: 100%; min-height: 2px; border-radius: 4px 4px 0 0;
  background: linear-gradient(180deg, var(--green-600), var(--green-800));
  transition: height 0.2s ease;
}
.chart .barfill.hasorder { position: relative; }
.chart .barfill.hasorder::after {
  content: ""; position: absolute; top: -9px; left: 50%; transform: translateX(-50%);
  width: 7px; height: 7px; border-radius: 50%; background: var(--green-600);
  box-shadow: 0 0 0 2px #fff;
}
.chart .barday {
  font-size: 0.6rem; color: var(--muted); margin-top: 4px;
  transform: rotate(-45deg); transform-origin: center; white-space: nowrap;
}
.chartkey { display: flex; gap: 1.2rem; flex-wrap: wrap; margin-top: 1.1rem; font-size: 0.8rem; color: var(--ink-2); }
.chartkey .sw { display: inline-block; width: 12px; height: 12px; border-radius: 3px; vertical-align: middle; margin-right: 0.3rem; }
.chartkey .sw.msg { background: var(--green-700); }
.chartkey .sw.ord { background: var(--green-600); border-radius: 50%; }

/* ---- health tiles (Zdravlje sistema) ----
   One tile per external service. The left border and the dot carry the state in
   colour AND position, same philosophy as the sidebar lamps. */
.healthgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); gap: 0.9rem; margin-bottom: 1.2rem; }
.healthtile {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 0.85rem 1rem; box-shadow: var(--shadow); border-left-width: 4px;
}
.healthtile.on   { border-left-color: var(--green-600); }
.healthtile.warn { border-left-color: #e8a13c; background: #fffdf7; }
.healthtile.off  { border-left-color: var(--danger); background: #fffafa; }
.healthname { display: flex; align-items: center; gap: 0.4rem; font-size: 0.95rem; }
.healthname .healthdot { margin-left: auto; width: 9px; height: 9px; border-radius: 50%; }
.healthtile.on   .healthdot { background: #3f9d44; box-shadow: 0 0 5px #7ce07f; }
.healthtile.warn .healthdot { background: #e8a13c; box-shadow: 0 0 5px #ffc861; }
.healthtile.off  .healthdot { background: var(--danger); box-shadow: 0 0 5px #ff7a70; }
.healthstatus { font-weight: 700; margin-top: 0.25rem; }
.healthtile.off .healthstatus { color: var(--danger); }
.healthtile.warn .healthstatus { color: var(--amber); }
.healthnote { font-size: 0.78rem; margin-top: 0.2rem; line-height: 1.4; }
.healthhead { display: inline-flex; align-items: center; gap: 0.7rem; font-weight: 400; text-transform: none; letter-spacing: 0; }

/* stored daily report, isolated from the admin styles */
.reportframe-wrap { padding: 0; overflow: hidden; }
.reportframe { width: 100%; height: 78vh; border: 0; display: block; background: #fff; }
/* On a phone a nested viewport-height scroll is miserable — give the email more room. */
@media (max-width: 860px) { .reportframe { height: 120vh; } }
