/*
 * OptiBooks Dash theme — application layer.
 *
 * Design TOKENS now live in optibooks_design/tokens.json and are generated into
 * assets/tokens.css by `python optibooks_design/build.py`. Dash auto-serves both;
 * tokens.css sorts AFTER theme.css alphabetically, so its :root wins for any token.
 * This file only MAPS those tokens onto Bootstrap/dbc and adds component polish.
 * Do not hard-code colors here — add/adjust them in tokens.json and rebuild.
 */

/* legacy alias kept for older references in callbacks */
:root { --ob-secondary: var(--ob-primary-hover); }

/* --------------------------------------------------------------------- */
/* Floating chat widget (optibooks_app/chat_widget.py) — fixed position,  */
/* stays put on scroll, mounted once in app.py's top-level layout so it  */
/* persists across client-side page navigation.                          */
/* --------------------------------------------------------------------- */
.ob-chat-fab {
  position: fixed;
  right: 24px;
  bottom: 24px;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  border: none;
  background-color: var(--ob-primary);
  color: var(--ob-text-on-accent);
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);
  cursor: pointer;
  z-index: 1050;
}
.ob-chat-fab:hover { background-color: var(--ob-primary-hover); }

.ob-chat-panel {
  position: fixed;
  right: 24px;
  bottom: 92px;
  width: 340px;
  max-height: 480px;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
  z-index: 1050;
  flex-direction: column;
  overflow: hidden;
}

.ob-chat-header {
  background-color: var(--ob-primary);
  color: var(--ob-text-on-accent);
  padding: 10px 14px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: 600;
}
.ob-chat-close {
  background: none;
  border: none;
  color: var(--ob-text-on-accent);
  font-size: 1.1rem;
  cursor: pointer;
  line-height: 1;
}

.ob-chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 160px;
}
.ob-chat-msg {
  padding: 8px 10px;
  border-radius: 10px;
  font-size: 0.9rem;
  max-width: 85%;
  word-wrap: break-word;
}
.ob-chat-msg-assistant {
  background-color: var(--ob-bg);
  color: var(--ob-text);
  align-self: flex-start;
}
.ob-chat-msg-user {
  background-color: var(--ob-primary);
  color: var(--ob-text-on-accent);
  align-self: flex-end;
}

.ob-chat-inputrow {
  display: flex;
  gap: 6px;
  padding: 10px;
  border-top: 1px solid var(--ob-bg);
}
.ob-chat-input { flex: 1; }

.ob-chat-quickreplies {
  padding: 0 12px;
  display: flex;
  flex-wrap: wrap;
}
.ob-chat-quickreplies:empty { padding: 0; }
.ob-chat-quickreply { font-size: 0.8rem; }

body {
  font-family: var(--ob-font-sans);
  background-color: var(--ob-bg);
  color: var(--ob-text);
  font-size: var(--ob-font-size-base, var(--ob-type-scale-base));
}

/* primary surfaces / navbar */
.bg-primary,
.navbar.bg-primary,
.btn-primary {
  background-color: var(--ob-primary) !important;
  border-color: var(--ob-primary) !important;
  /* Set the on-accent text colour explicitly so a primary button never depends
     on Bootstrap's implicit white (which, on a broken --ob-primary, rendered as
     invisible text on a blank button). */
  color: var(--ob-text-on-accent) !important;
}
.btn-primary:hover,
.btn-primary:focus {
  background-color: var(--ob-primary-hover) !important;
  border-color: var(--ob-primary-hover) !important;
}
.btn-outline-primary { color: var(--ob-primary) !important; border-color: var(--ob-primary) !important; }
.btn-outline-primary:hover { background-color: var(--ob-primary) !important; color: var(--ob-text-on-accent) !important; }
.text-primary { color: var(--ob-primary) !important; }
a { color: var(--ob-link); }
a:hover { color: var(--ob-primary-hover); }

/* status / severity accents aligned to brand tokens */
.badge.bg-danger, .bg-danger { background-color: var(--ob-error) !important; }
.badge.bg-success, .bg-success { background-color: var(--ob-success) !important; }
.badge.bg-warning, .bg-warning { background-color: var(--ob-warning) !important; }
.text-danger { color: var(--ob-error) !important; }
.text-success { color: var(--ob-success) !important; }

/* domain-semantic chips: provenance / verification / sandbox state.
   Usage: <span class="ob-state ob-state-unverified">…</span> — pair with an icon
   + text label in markup (never color alone, per WCAG 2.2 AA / principle 1). */
.ob-state { border-radius: var(--ob-radius-pill); padding: 1px 8px; font-size: var(--ob-type-scale-xs); font-weight: var(--ob-weight-semibold); }
.ob-state-engine       { color: var(--ob-state-engine); border: 1px solid var(--ob-state-engine); }
.ob-state-ai-suggested { color: var(--ob-state-ai-suggested); border: 1px solid var(--ob-state-ai-suggested); }
.ob-state-unverified   { color: var(--ob-warning); border: 1px solid var(--ob-warning); }
.ob-state-verified     { color: var(--ob-success); border: 1px solid var(--ob-success); }
.ob-state-rejected     { color: var(--ob-error); border: 1px solid var(--ob-error); }

/* card polish */
.card { border: none; box-shadow: var(--ob-shadow-1); border-radius: var(--ob-card-radius); }
.navbar-brand { font-weight: var(--ob-weight-bold); letter-spacing: 0.3px; }

/* accessible focus ring everywhere (compliance, not optional) */
:focus-visible { outline: none; box-shadow: var(--ob-focus-ring); }

/* numeric tables: monospace + right-align for scannable figures */
table td.num, table th.num, .ob-num { font-family: var(--ob-font-mono); text-align: right; font-variant-numeric: tabular-nums; }
