/* ─────────────────────────────────────────────────────────────────────────────
   #1817 — Bootstrap 5.3 tokens, backported onto the bundled Bootstrap 5.1.0.

   The portal ships wwwroot/lib/bootstrap/dist/css/bootstrap.min.css, which is
   v5.1.0. --bs-border-color, the --bs-*-bg family, --bs-secondary-color and the
   -emphasis family all arrived in 5.2/5.3. A declaration whose var() does not
   resolve is dropped WHOLE, so page CSS written against the current Bootstrap
   docs silently painted nothing: on Template Generator alone, 26 rules matching
   live elements lost their border, tint or muted color (#1806 found the same
   thing on Web Forms, where "border: 1px solid var(--bs-border-color)" left
   border-style: none and Jamie saw unstyled stacked divs).

   These five are the only ones the repo uses; the values are Bootstrap 5.3.3's
   own, copied verbatim so an upgrade is a no-op for anything that reads them.
   Website/tests/bootstrapTokens1817.test.js fails if any page or sheet reaches
   for a --bs- variable that is neither in the bundled Bootstrap nor in this
   block, which is how the next one gets caught before it ships.

   DELETE THIS BLOCK when Bootstrap is actually upgraded — the upgrade is its own
   piece of work, not this one. Measured 2026-09-02 against 5.3.3: it also makes
   admin.css's flat `.btn { padding: .5rem 1rem }` beat 5.3's variable-driven
   .btn-sm / .btn-group-sm, which grows 214 small buttons across 34 page files.
   ───────────────────────────────────────────────────────────────────────────── */
:root {
  --bs-border-color: #dee2e6;
  --bs-secondary-color: rgba(33, 37, 41, 0.75);
  --bs-secondary-bg: #e9ecef;
  --bs-tertiary-bg: #f8f9fa;
  --bs-danger-text-emphasis: #58151c;
}

/* Same bug, one level up: utility CLASSES from 5.2/5.3 used on the 5.1 bundle. The
   class simply is not there, so nothing applies — and .badge already carries
   `color: #fff`, which makes `badge text-bg-secondary` white text on a white page.
   That is the Template Generator's field-count and "Example" pills, the "N tokens"
   pill beside Generate, the environment pill on Connections and the child-row chip
   in the data browser: five labels nobody could read.

   No !important, unlike Bootstrap's own: the portal has rules that deliberately
   re-color a .badge (e.g. .dbf-tabs .badge in data-browser.css) and they win today.
   Fixing invisible text must not repaint something that already renders. site.css
   loads straight after bootstrap.min.css in every layout, so equal specificity is
   enough to beat .badge's white.
   DELETE THESE TOO when Bootstrap is upgraded — 5.3 ships them properly. */
.text-bg-secondary {
  color: #fff;
  background-color: rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity, 1));
}

.text-bg-light {
  color: #000;
  background-color: rgba(var(--bs-light-rgb), var(--bs-bg-opacity, 1));
}

.text-body-secondary {
  color: var(--bs-secondary-color);
}

.text-body-tertiary {
  color: rgba(33, 37, 41, 0.5);
}

/* The 5.3 -subtle / -emphasis pairs, same story. `badge bg-secondary-subtle
   text-secondary-emphasis` is the Vault status pill and its entity kinds; the
   Orchestrator builds `badge bg-primary-subtle text-primary-emphasis` chips in
   orchestrator.js; Admin > Users tints an "opted in" badge. None of the classes
   exist here, so all of them were white on white. text-warning-emphasis is the
   quieter half of the same failure: four hints on Template Generator and two in
   the Vault meant to read as a warning and rendered as ordinary gray.

   Values are 5.3.3's resolved light-mode ones, inlined rather than routed through
   a --bs-*-bg-subtle token: only this block would read those tokens, and a token
   nothing else uses is one more thing to keep in step. Only the pairs the repo
   actually wears are here — the guard test names the next one. */
.bg-primary-subtle { background-color: #cfe2ff; }
.bg-secondary-subtle { background-color: #e2e3e5; }
.bg-success-subtle { background-color: #d1e7dd; }
.border-success-subtle { border-color: #a3cfbb; }
.text-primary-emphasis { color: #052c65; }
.text-secondary-emphasis { color: #2b2f32; }
.text-warning-emphasis { color: #664d03; }
.text-success-emphasis { color: #0a3622; }
.text-info-emphasis { color: #055160; }
.bg-warning-subtle { background-color: #fff3cd; }
.bg-info-subtle { background-color: #cff4fc; }
.border-primary-subtle { border-color: #9ec5fe; }
/* #2001 — the danger trio, for the two-factor opt-out on /Portal/Settings: the "Two-factor
   off" badge and the panel the acknowledgment sits in. The guard test named these the
   moment the markup wore them, which is the whole point of it. Same 5.3.3 light-mode
   values as everything above. */
.bg-danger-subtle { background-color: #f8d7da; }
.border-danger-subtle { border-color: #f1aeb5; }
.text-danger-emphasis { color: #58151c; }
.text-bg-warning { color: #000; background-color: #ffc107; }

/* #1972 needed text-bg-success for the encryption badge and the guard test caught it
   before it shipped. Two of the other three are added with it because they were ALREADY
   broken and nothing could see it: /Portal/Transfer's status badge is built in script as
   `badge text-bg-` + kind, and it reaches 'primary' (sending), 'success' (connected,
   delivered) and 'danger' (hash mismatch, could not connect) at runtime. The markup guard
   only reads markup, so three states of the one badge that most needs reading — including
   HASH MISMATCH — have been white on white since #1843. Same 5.3.3 values, same rule as
   the block above, same instruction: DELETE WHEN BOOTSTRAP IS UPGRADED. */
.text-bg-success { color: #fff; background-color: rgba(var(--bs-success-rgb), var(--bs-bg-opacity, 1)); }
.text-bg-danger { color: #fff; background-color: rgba(var(--bs-danger-rgb), var(--bs-bg-opacity, 1)); }
.text-bg-primary { color: #fff; background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity, 1)); }
/* #1931's safety code. The guard caught it before it shipped, which is the third time this
   block has earned its keep. A code nobody can read is a check nobody makes, and this is
   the one element on the page that is not asking the reader to trust us. Same 5.3.3 value,
   same instruction: DELETE WHEN BOOTSTRAP IS UPGRADED. */
.text-bg-dark { color: #fff; background-color: rgba(var(--bs-dark-rgb), var(--bs-bg-opacity, 1)); }

html {
  font-size: 14px;
}

@media (min-width: 768px) {
  html {
    font-size: 16px;
  }
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

body {
  background-color: #f8f9fa;
}

/* DocButterfly Theme Styles */
.navbar-brand {
  font-weight: bold;
  color: #1a3a5c !important;
}

.navbar-brand img {
  transition: transform 0.3s ease;
}

.navbar-brand:hover img {
  transform: scale(1.1);
}

/* Hero Section */
.hero-section {
  padding: 60px 0;
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  margin: -30px -15px 40px -15px;
}

.hero-logo {
  max-width: 300px;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 4px 8px rgba(0,0,0,0.1));
}

.hero-tagline {
  color: #1a3a5c;
  font-weight: 600;
  font-size: 1.5rem;
  margin-bottom: 10px;
}

.hero-subtitle {
  color: #6c757d;
  font-size: 1.1rem;
}

.card {
  border-radius: 10px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
  margin-bottom: 20px;
}

.card-img-top {
  border-radius: 10px 10px 0 0;
}

.btn-primary {
  background-color: #1a3a5c;
  border-color: #1a3a5c;
}

.btn-primary:hover {
  background-color: #122a42;
  border-color: #122a42;
}

.family-tree-card {
  transition: transform 0.2s;
}

.family-tree-card:hover {
  transform: translateY(-5px);
}

.post-card {
  border-left: 4px solid #1a3a5c;
}

.timeline {
  position: relative;
  padding-left: 30px;
}

.timeline::before {
  content: '';
  position: absolute;
  left: 15px;
  top: 0;
  bottom: 0;
  width: 2px;
  background: #1a3a5c;
}

.timeline-item {
  position: relative;
  margin-bottom: 20px;
}

.timeline-item::before {
  content: '';
  position: absolute;
  left: -25px;
  top: 5px;
  width: 12px;
  height: 12px;
  background: #1a3a5c;
  border-radius: 50%;
}

.heritage-background {
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
  padding: 60px 0;
}

.person-card {
  border: none;
  background: white;
  border-radius: 15px;
  overflow: hidden;
  transition: all 0.3s ease;
}

.person-card:hover {
  transform: translateY(-10px);
  box-shadow: 0 20px 40px rgba(0,0,0,0.1);
}

/* Voting System Styles */
.vote-buttons {
  display: flex;
  align-items: center;
}

.btn-vote {
  border: 1px solid #dee2e6;
  background: white;
  color: #6c757d;
  transition: all 0.2s;
}

.btn-upvote:hover,
.btn-upvote.active {
  background-color: #28a745;
  border-color: #28a745;
  color: white;
}

.btn-downvote:hover,
.btn-downvote.active {
  background-color: #dc3545;
  border-color: #dc3545;
  color: white;
}

.vote-count {
  margin-left: 5px;
  font-weight: bold;
}

.vote-score .badge {
  font-size: 0.75rem;
}

.detail-section {
  border-bottom: 1px solid #f0f0f0;
  padding-bottom: 15px;
}

.detail-section:last-child {
  border-bottom: none;
}

.comment-item {
  border-left: 3px solid #ffc107;
}

.border-left-primary {
  border-left: 4px solid #1a3a5c;
}

.border-left-success {
  border-left: 4px solid #28a745;
}

.border-left-info {
  border-left: 4px solid #17a2b8;
}

/* GEDCOM Upload Styles */
.upload-area {
  border: 2px dashed #dee2e6;
  border-radius: 10px;
  padding: 40px;
  text-align: center;
  transition: all 0.3s;
}

.upload-area:hover {
  border-color: #1a3a5c;
  background-color: #f8f9fa;
}

.upload-area.dragover {
  border-color: #1a3a5c;
  background-color: #e8f5e8;
}
/* ═══════════════════════════════════════════ */
/* AI CHAT FAB + PANEL (site-wide)             */
/* ═══════════════════════════════════════════ */

.ai-chat-fab {
    position: fixed; bottom: 24px; right: 24px; width: 52px; height: 52px;
    border-radius: 50%; background: linear-gradient(135deg, #6366f1, #8b5cf6);
    color: #fff; border: none; font-size: 1.3rem; cursor: pointer; z-index: 1040;
    box-shadow: 0 4px 16px rgba(99,102,241,0.4); transition: transform 0.2s, box-shadow 0.2s;
    display: flex; align-items: center; justify-content: center;
}
.ai-chat-fab:hover { transform: scale(1.1); box-shadow: 0 6px 24px rgba(99,102,241,0.5); }
.ai-chat-fab.active { background: linear-gradient(135deg, #4f46e5, #7c3aed); }

.ai-chat-panel {
    position: fixed; bottom: 88px; right: 24px; width: 380px; height: 520px;
    z-index: 1039; background: #fff; border-radius: 14px;
    box-shadow: 0 8px 40px rgba(0,0,0,0.18); display: flex; flex-direction: column;
    overflow: hidden; border: 1px solid #e5e7eb;
}
.ai-chat-header {
    padding: 12px 16px; background: linear-gradient(135deg, #6366f1, #8b5cf6);
    color: #fff; font-weight: 600; font-size: 0.9rem;
    display: flex; align-items: center; justify-content: space-between; flex-shrink: 0;
}
.ai-chat-header i { margin-right: 6px; }
.ai-chat-close { background: none; border: none; color: #fff; font-size: 1.3rem; cursor: pointer; line-height: 1; opacity: 0.8; padding: 0 4px; }
.ai-chat-close:hover { opacity: 1; }
.ai-chat-messages { flex: 1; overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 8px; min-height: 0; }
.chat-msg { display: flex; max-width: 92%; }
.chat-msg.user { align-self: flex-end; }
.chat-msg.assistant { align-self: flex-start; }
.chat-bubble { padding: 8px 12px; border-radius: 12px; font-size: 0.84rem; line-height: 1.55; word-break: break-word; }
.chat-msg.user .chat-bubble { background: #6366f1; color: #fff; border-bottom-right-radius: 4px; }
.chat-msg.assistant .chat-bubble { background: #f3f4f6; color: #1f2937; border-bottom-left-radius: 4px; }
.chat-bubble code { background: rgba(0,0,0,0.08); padding: 1px 4px; border-radius: 3px; font-size: 0.78rem; }
.chat-msg.user .chat-bubble code { background: rgba(255,255,255,0.2); }
.chat-bubble a { color: #6366f1; text-decoration: underline; }
.chat-msg.user .chat-bubble a { color: #c7d2fe; }
.chat-code-block { margin: 6px 0; border-radius: 6px; overflow: hidden; }
.chat-code-block pre { background: #1e1e1e; color: #d4d4d4; padding: 10px; margin: 0; font-size: 0.75rem; line-height: 1.4; overflow-x: auto; white-space: pre-wrap; word-break: break-all; max-height: 180px; overflow-y: auto; }
.ai-chat-input { padding: 10px 12px; border-top: 1px solid #e5e7eb; display: flex; gap: 8px; flex-shrink: 0; background: #f9fafb; }
.ai-chat-input input, .ai-chat-input textarea { flex: 1; border: 1px solid #d1d5db; border-radius: 8px; padding: 8px 12px; font-size: 0.82rem; outline: none; transition: border-color 0.15s; }
.ai-chat-input input:focus, .ai-chat-input textarea:focus { border-color: #6366f1; box-shadow: 0 0 0 2px rgba(99,102,241,0.15); }
.ai-chat-input textarea { resize: none; font-family: inherit; line-height: 1.4; max-height: 120px; overflow-y: auto; } /* #735 */
.ai-chat-input button { background: #6366f1; color: #fff; border: none; border-radius: 8px; padding: 8px 14px; cursor: pointer; font-size: 0.85rem; transition: background 0.15s; }
.ai-chat-input button:hover { background: #4f46e5; }
.ai-chat-input button:disabled { background: #9ca3af; cursor: default; }
/* #1838 - the Advanced switch in the design assistant's composer. Quiet while off:
   it is a second register, not the main control, and a purple button beside Send
   would read as a second way to send. Lit while on, because a turn that can write
   the stylesheet and replace markup has to be visibly different from one that
   cannot. */
.ai-chat-input button.tdai-advanced {
    background: transparent; color: #6b7280; border: 1px solid #d1d5db;
    padding: 8px 10px; flex: 0 0 auto;
}
.ai-chat-input button.tdai-advanced:hover { background: #eef2ff; color: #4f46e5; border-color: #c7d2fe; }
.ai-chat-input button.tdai-advanced.is-on { background: #4f46e5; color: #fff; border-color: #4f46e5; }
.ai-chat-input button.tdai-advanced.is-on:hover { background: #4338ca; }
.ai-chat-callout {
    position: fixed; bottom: 84px; right: 24px; width: 300px;
    background: linear-gradient(135deg, #6366f1, #8b5cf6); color: #fff;
    border-radius: 12px; padding: 14px 16px; z-index: 1041;
    box-shadow: 0 8px 32px rgba(99,102,241,0.45); cursor: pointer;
    animation: sac-callout-appear 0.4s ease-out;
}
.ai-chat-callout::after { content: ''; position: absolute; bottom: -8px; right: 20px; width: 16px; height: 16px; background: #8b5cf6; transform: rotate(45deg); border-radius: 2px; }
.ai-chat-callout-close { position: absolute; top: 6px; right: 8px; background: none; border: none; color: rgba(255,255,255,0.7); font-size: 1.1rem; cursor: pointer; line-height: 1; padding: 2px 4px; }
.ai-chat-callout-close:hover { color: #fff; }
.ai-chat-callout-title { font-weight: 700; font-size: 0.88rem; margin-bottom: 6px; }
.ai-chat-callout-title i { margin-right: 4px; }
.ai-chat-callout-body { font-size: 0.8rem; line-height: 1.5; opacity: 0.92; }
.ai-chat-callout-hiding { opacity: 0; transform: translateY(8px) scale(0.95); transition: opacity 0.3s, transform 0.3s; }
@keyframes sac-callout-appear { from { opacity: 0; transform: translateY(12px) scale(0.9); } to { opacity: 1; transform: translateY(0) scale(1); } }
.chat-typing { display: inline-flex; gap: 4px; padding: 4px 0; }
.chat-typing span { width: 6px; height: 6px; background: #9ca3af; border-radius: 50%; animation: sac-bounce 1.4s infinite ease-in-out both; }
.chat-typing span:nth-child(1) { animation-delay: -0.32s; }
.chat-typing span:nth-child(2) { animation-delay: -0.16s; }
.chat-typing span:nth-child(3) { animation-delay: 0s; }
@keyframes sac-bounce { 0%, 80%, 100% { transform: scale(0); } 40% { transform: scale(1); } }
@media (max-width: 576px) {
    .ai-chat-panel { width: calc(100vw - 24px); right: 12px; bottom: 80px; }
    .ai-chat-callout { width: calc(100vw - 60px); right: 12px; }
}

/* #2412 - the environment note: one small line, never a banner. Dev/test say
   "This is test, not production."; prod says its configured beta disclaimer. */
.env-note {
    display: inline-block;
    font-size: .72rem;
    line-height: 1.25;
    padding: 2px 10px;
    margin: 0 0 4px;
    color: #7a5d00;
    background: #fff6d6;
    border: 1px solid #f3dd8a;
    border-radius: 0 0 8px 8px;
    letter-spacing: .01em;
}
