/*
 * This is a manifest file that'll be compiled into application.css.
 *
 * With Propshaft, assets are served efficiently without preprocessing steps. You can still include
 * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
 * cascading order, meaning styles declared later in the document or manifest will override earlier ones,
 * depending on specificity.
 *
 * Consider organizing styles into separate files for maintainability.
 */

/* ── Chat messages: fade content under navbar (top) and textarea (bottom) ── */
/* Mimics the Claude app soft-mask so messages dissolve gracefully at edges   */
#chat-messages {
  -webkit-mask-image: linear-gradient(
    to bottom,
    transparent 0,
    black 2.5rem,
    black calc(100% - 4.5rem),
    transparent 100%
  );
  mask-image: linear-gradient(
    to bottom,
    transparent 0,
    black 2.5rem,
    black calc(100% - 4.5rem),
    transparent 100%
  );
}

/* ── Background gradient orbs — global positioning ──────────────────────── */
@media (max-width: 639px) {
  #bg-gradient-orbs { display: none; }
}
@media (min-width: 640px) {
  #bg-gradient-orbs > .orb-1 {
    left: -320px; top: auto; bottom: -100px;
    width: 600px; height: 500px;
  }
  #bg-gradient-orbs > .orb-2 {
    right: -260px; left: auto; bottom: 20%;
    width: 520px; height: 420px;
  }
  #bg-gradient-orbs > .orb-3 {
    left: -200px; bottom: 30%;
    width: 480px; height: 400px;
  }
}
@media (min-width: 1024px) {
  #bg-gradient-orbs > .orb-1 {
    left: -420px; bottom: -140px;
    width: 820px; height: 680px;
  }
  #bg-gradient-orbs > .orb-2 {
    right: -340px; bottom: 18%;
    width: 720px; height: 580px;
  }
  #bg-gradient-orbs > .orb-3 {
    left: -280px; bottom: 28%;
    width: 660px; height: 540px;
  }
}
@media (min-width: 1440px) {
  #bg-gradient-orbs > .orb-1 {
    left: -520px; bottom: -180px;
    width: 1000px; height: 840px;
  }
  #bg-gradient-orbs > .orb-2 {
    right: -420px; bottom: 15%;
    width: 880px; height: 720px;
  }
  #bg-gradient-orbs > .orb-3 {
    left: -360px; bottom: 25%;
    width: 820px; height: 680px;
  }
}

/* ── Base typography ─────────────────────────────────────────────────────── */
body {
  font-size: 16px;
  line-height: 1.6;
}

/* Navbar left title — smaller on mobile so long titles fit. One line always;
   on phones the pill has a max-width, so a title longer than it ellipsises
   rather than running under the menu button. */
.left-title p {
  font-size: 0.75rem;
  line-height: 1.3;
  white-space: nowrap;
}
@media (max-width: 639.98px) {
  .left-title p {
    overflow: hidden;
    text-overflow: ellipsis;
  }
}
@media (min-width: 640px) {
  .left-title p {
    font-size: 1.125rem; /* text-lg */
  }
}

/* Thinking indicator dot pulse (smooth, slower than bounce) */
@keyframes thinking-dot {
  0%, 100% { opacity: 0.3; transform: translateY(0); }
  50%       { opacity: 1;   transform: translateY(-3px); }
}

/* Serif font for LLM response content */
.font-serif-response {
  font-family: 'Source Serif 4', Georgia, serif;
}

/* Force all text inside response boxes to match the summary font size (1rem/16px).
   Tailwind Typography resets p/li/ul internally — this wins regardless of prose modifiers. */
.font-serif-response p,
.font-serif-response li,
.font-serif-response ul,
.font-serif-response ol,
.font-serif-response td,
.font-serif-response th {
  font-size: 1rem;
  line-height: 1.6;
}

/* ── Global form input focus ring ───────────────────────────────────────── */
/* Applies the brand focus ring to all text-like inputs app-wide — the same
   recipe as the marketing site, so a sign-in field and a subscribe field
   focus identically. var(--color-brand) resolves because @theme static emits
   it into :root and tailwind.css loads before this file. */
input:not([type=submit]):not([type=button]):not([type=checkbox]):not([type=radio]):not([type=file]):not([type=range]):focus,
textarea:focus,
select:focus {
  outline: none;
  border-color: var(--color-brand);
  box-shadow: 0 0 0 3px oklch(54.6% 0.245 262.881 / 0.15);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

/* Query textarea: parent wrapper shows focus ring; the textarea itself stays borderless */
textarea#question:focus {
  border-color: transparent;
  box-shadow: none;
}

/* The soft shadow scale now lives in @theme (app/assets/tailwind/application.css)
   as --shadow-*. It used to be five .shadow-* rules here — but this file is
   UNLAYERED, so those always beat anything the theme generates, and
   `shadow-xl shadow-blue-100` could never tint. The values are identical, so
   deleting them changes nothing except that shadow-<colour> now works. */

/* ── Toast notification animations ──────────────────────────────────────── */
@keyframes toast-in {
  from { transform: translateX(calc(-100% - 1.5rem)); opacity: 0; }
  to   { transform: translateX(0); opacity: 1; }
}
@keyframes toast-out {
  from { opacity: 1; transform: translateX(0); }
  to   { opacity: 0; transform: translateX(-1rem); }
}
.toast-enter { animation: toast-in  0.35s cubic-bezier(0.16, 1, 0.3, 1) forwards; }
.toast-exit  { animation: toast-out 0.25s ease-in forwards; }

/* ── Insights feed: a row leaving one section and landing in the other ───── */
/* `from` is deliberately absent on insight-leave: the controller pins the row's
   height inline before adding the class, and a keyframe with no `from` starts
   at the computed value. */
@keyframes insight-leave {
  to { height: 0; opacity: 0; transform: translateX(-8px); border-bottom-width: 0; }
}
.insight-leave {
  overflow: hidden;
  pointer-events: none;
  animation: insight-leave 0.32s cubic-bezier(0.4, 0, 1, 1) forwards;
}
@keyframes insight-arrive {
  from { opacity: 0; transform: translateY(-10px); background-color: #eff6ff; }
  55%  { opacity: 1; transform: translateY(0);     background-color: #eff6ff; }
  to   { background-color: transparent; }
}
[data-insight-animate-in="1"] {
  animation: insight-arrive 0.9s cubic-bezier(0.16, 1, 0.3, 1) both;
}
@media (prefers-reduced-motion: reduce) {
  .insight-leave, [data-insight-animate-in="1"] { animation: none; }
}

/* ── Flyout menu: animated Siri-style gradient border + bounce entry ─────── */
@property --flyout-angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

@keyframes spin-flyout-border {
  to { --flyout-angle: 360deg; }
}

@keyframes flyout-enter {
  0%   { opacity: 0; transform: translateY(-8px) scale(0.95); }
  55%  { opacity: 1; transform: translateY(3px) scale(1.018); }
  75%  { transform: translateY(-1.5px) scale(0.997); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

.flyout-border-wrap {
  padding: 2px;
  border-radius: 18px;
  background: conic-gradient(
    from var(--flyout-angle) at 50% 50%,
    #60a5fa 0%,     /* blue-400 */
    #2563eb 30%,    /* blue-600 */
    #0ea5e9 55%,    /* sky-500  */
    #38bdf8 75%,    /* sky-400  */
    #60a5fa 100%
  );
  animation:
    flyout-enter 0.45s cubic-bezier(0.34, 1.56, 0.64, 1) both,
    spin-flyout-border 5s linear infinite;
  box-shadow:
    0 0 28px rgba(37, 99, 235, 0.35),
    0 0 56px rgba(14, 165, 233, 0.18),
    0 12px 40px rgba(0, 0, 0, 0.1);
}

/* ── KPI generation shimmer skeleton ────────────────────────────────────── */
@keyframes shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position:  200% 0; }
}
.kpi-skeleton {
  background: linear-gradient(90deg,
    #f3f4f6 25%, #e9eaf0 50%, #f3f4f6 75%);
  background-size: 200% 100%;
  animation: shimmer 1.6s ease-in-out infinite;
}

/* ── Standardised button base ────────────────────────────────────────────── */
/* Usage: class="btn btn-primary | btn-secondary | btn-danger | btn-ghost"   */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center; /* centers text horizontally — critical for input[type=submit] */
  text-align: center;
  gap: 0.5rem;             /* gap-2 */
  padding: 0.625rem 1.25rem; /* py-2.5 px-5 */
  font-size: 0.875rem;     /* text-sm */
  font-weight: 500;        /* font-medium */
  border-radius: 0.5rem;   /* rounded-lg */
  border: 1px solid transparent;
  line-height: 1.25rem;
  transition: opacity 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease;
  cursor: pointer;
  white-space: nowrap;
}
/* Compact size for a toolbar or a list header. A class, not px-/py- utilities:
   this file is unlayered, so utilities cannot out-rank .btn's padding. */
.btn-sm { padding: 0.375rem 0.75rem; font-size: 0.75rem; line-height: 1rem; gap: 0.375rem; }
.btn:active { transform: scale(0.97); }
.btn:disabled, .btn[disabled] { opacity: 0.45; cursor: not-allowed; transform: none; }

.btn-primary {
  background: linear-gradient(to right, var(--color-brand), var(--color-brand-action));
  color: #fff;
  box-shadow: 0 1px 2px rgba(0,0,0,0.04), 0 2px 8px rgba(0,0,0,0.04);
}
/* color on hover too: without it a visited <a class="btn btn-primary"> leaks. */
.btn-primary:hover { opacity: 0.9; color: #fff; }

.btn-secondary {
  background: #fff;
  color: #374151;         /* text-gray-700 */
  border-color: #e5e7eb;  /* border-gray-100 */
}
.btn-secondary:hover { background: #f9fafb; border-color: #d1d5db; }

.btn-danger {
  background: #dc2626;
  color: #fff;
}
.btn-danger:hover { opacity: 0.9; }

.btn-danger-outline {
  background: #fff;
  color: #dc2626;
  border-color: #fecaca;
}
.btn-danger-outline:hover { background: #fef2f2; }

.btn-ghost {
  background: transparent;
  color: #6b7280;
  border-color: transparent;
}
.btn-ghost:hover { background: #f3f4f6; color: #111827; }

/* ── Standardised form controls ─────────────────────────────────────────── */
/* Ensures select height / appearance matches text inputs everywhere.        */
select {
  appearance: none;
  -webkit-appearance: none;
  /* Height is driven by padding + line-height to match text inputs.
     Tailwind py-* classes on individual selects will override padding
     but appearance:none + the arrow image are the critical fixes.   */
  padding: 0.5rem 2.25rem 0.5rem 0.75rem; /* py-2 equivalent + right room for arrow */
  font-size: 0.875rem;
  line-height: 1.25rem;
  color: #111827;
  background-color: #fff;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='%236b7280'%3E%3Cpath fill-rule='evenodd' d='M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z' clip-rule='evenodd'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.5rem center;
  background-size: 1.25rem;
  border: 1px solid #e5e7eb;
  border-radius: 0.5rem;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
  cursor: pointer;
}
select:disabled { opacity: 0.5; background-color: #f9fafb; cursor: not-allowed; }
/* A select sitting beside .field-input text fields (settings) matches their
   height and border. It has to be said HERE: the rule above is unlayered, so
   the layered .field-input cannot out-rank it. */
select.field-input { padding-top: 0.625rem; padding-bottom: 0.625rem; border-color: #d1d5db; }
