/* ==========================================================================
   Demo UI Stylesheet
   --------------------------------------------------------------------------
   Purpose:
     Lightweight, component-oriented styles for the FastAPI demo (auth, prompts,
     generate). Focused on clarity and minimalism.

   How to customize quickly:
     - Change theme colors in :root (e.g., --accent, --accent2).
     - Use the utility classes (.row, .muted, .hidden) for layout tweaks.
     - Reuse components: .card for panels, .output for response boxes, .vars-* for
       prompt variable inputs.

   Accessibility & busy state:
     - JS toggles `body.busy` and sets `aria-busy="true"` during long tasks.
       This file sets a progress cursor for that state.
     - Disabled buttons are dimmed and non-interactive.

   CORS/mixed-content reminders (frontend-only note):
     - If requests fail in browser but work in Python, check CORS and HTTPS.

   Optional spinner overlay (not enabled by default):
     - If you want a visual spinner, add markup and rules in a separate section.
       The progress cursor here is intentionally minimal.
   ========================================================================== */

/* === Theme tokens ========================================================= */
:root{
  --bg:#f7fafc; --panel:#ffffff; --border:#e5e7eb; --text:#111827;
  --muted:#6b7280; --accent:#2563eb; --accent2:#7c3aed; --danger:#dc2626; --ok:#16a34a;
}

/* === Base/reset =========================================================== */
*{box-sizing:border-box}
html,body{margin:0;padding:0;background:var(--bg);color:var(--text);font:14px/1.5 Inter, system-ui, -apple-system, Segoe UI, Roboto, sans-serif}
a{color:var(--accent);text-decoration:none}

/* === Top bar / navigation =================================================
   Structure:
     <div class="topbar">
       <div class="brand"><span class="logo">…</span><span class="title">…</span></div>
       <nav class="nav"><a href="#/auth">Auth</a>…</nav>
     </div>
   Sticky header with subtle border.
   ========================================================================== */
.topbar{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--border);background:#fff;position:sticky;top:0;z-index:10}
.brand{display:flex;gap:10px;align-items:center}
.logo{font-size:22px}
.title{font-weight:700}
.nav a{margin:0 6px;padding:6px 10px;border-radius:8px}
.nav a:hover{background:#eef2ff}

/* === Layout containers ====================================================
   .screen constrains width and centers content.
   .card is a generic panel container.
   ========================================================================== */
.screen{max-width:1100px;margin:20px auto;padding:0 16px}
.card{background:var(--panel);border:1px solid var(--border);border-radius:12px;padding:16px;box-shadow:0 1px 2px rgba(0,0,0,.03)}

/* === Forms & inputs =======================================================
   .form vertical stack, .grid2 for 2-column sections, .full spans full width.
   ========================================================================== */
.form{display:flex;flex-direction:column;gap:12px}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.grid2 .full{grid-column:1 / -1}
label{display:flex;flex-direction:column;gap:6px}
input,textarea,select{background:#fff;border:1px solid var(--border);color:var(--text);padding:10px 12px;border-radius:10px;outline:none}
input:focus,textarea:focus,select:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(37,99,235,.15)}

/* === Buttons ==============================================================
   Variants:
     - default (neutral)
     - .primary (accent gradient, e.g., main actions like GENERATE)
     - .ghost (subtle)
     - .danger (destructive)
   Disabled buttons are also styled (see bottom of file).
   ========================================================================== */
button{border:1px solid var(--border);background:#fff;color:var(--text);padding:10px 14px;border-radius:10px;cursor:pointer}
button.primary{background:linear-gradient(135deg,var(--accent),var(--accent2));color:#fff;border:0}
button.ghost{background:#f9fafb}
button.danger{border-color:var(--danger);color:var(--danger);background:#fff}

/* === Small utilities ======================================================
   .row       → horizontal flex group with wrapping
   .status    → fixed min width for inline status messages
   .muted     → subdued text color, e.g., hints
   .hidden    → toggle visibility in JS router/mode switches
   ========================================================================== */
.row{display:flex;gap:10px;flex-wrap:wrap;align-items:center}
.status{min-width:160px}
.muted{color:var(--muted)}
.hidden{display:none}

/* === Tables (Prompts list) =============================================== */
table{width:100%;border-collapse:collapse;margin-top:10px}
th,td{border-bottom:1px solid var(--border);padding:10px;text-align:left}
td .row{gap:6px}

/* === Output panes (responses/raw JSON) ===================================
   .output      → pre-like block with wrapping for model text
   .output.raw  → scrollable region for raw JSON / SSE debug text
   ========================================================================== */
.output{background:#f9fafb;border:1px solid var(--border);border-radius:10px;padding:12px;white-space:pre-wrap;min-height:120px}
.output.raw{max-height:300px;overflow:auto}

/* === Footer =============================================================== */
.footer{padding:16px;text-align:center;color:var(--muted)}

/* === Prompt variables UI ==================================================
   Used by placeholder detection for {var} inputs in the Generate screen.
   - .vars-grid renders two columns of label+textarea fields.
   - .placeholder-pill shows detected placeholders as chips.
   ========================================================================== */
.vars{margin-top:8px}
.vars-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
.vars-field{display:flex;flex-direction:column;gap:8px;padding:12px;border:1px solid var(--border);border-radius:10px;background:#fff;min-height:120px}
.vars-field textarea{min-height:90px;resize:vertical}
.vars-field__name{font-weight:600;color:#1f2937;font-size:13px;letter-spacing:.01em}
.placeholder-upload{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:4px}
.placeholder-upload__label{font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--muted)}
.placeholder-upload input[type="file"]{font-size:13px}
.placeholder-upload__status{font-size:12px;color:var(--muted);flex:1;min-width:160px}
.placeholder-upload__status.error{color:var(--danger)}
.placeholder-files{display:flex;flex-direction:column;gap:6px;margin-top:6px}
.placeholder-files__empty{color:var(--muted);font-size:12px;padding:2px 0}
.placeholder-file-item{display:flex;align-items:center;gap:10px;padding:6px 8px;border:1px dashed var(--border);border-radius:8px;background:#fff;flex-wrap:wrap}
.placeholder-file-item__name{font-weight:500;color:#111827;flex:1;min-width:150px}
.placeholder-file-item__meta{font-size:12px;color:var(--muted)}
.placeholder-file-item__remove{margin-left:auto}
.placeholder-pills{margin-top:8px}
.placeholder-pill{display:inline-block;padding:4px 8px;border-radius:999px;border:1px solid var(--border);background:#f3f4f6;margin:4px 8px 0 0;color:var(--muted);font-size:12px}

.placeholder-editor{margin-top:12px;padding:12px;border:1px solid var(--border);border-radius:10px;background:#f9fafb}
.placeholder-editor__toolbar{align-items:center;gap:.75rem;margin-bottom:8px}
.placeholder-editor__list{display:flex;flex-direction:column;gap:10px}
.placeholder-editor__head{display:grid;grid-template-columns:minmax(0,140px) minmax(0,220px) minmax(0,1fr);gap:12px;padding:0 4px;font-size:12px;font-weight:600;color:#4b5563;letter-spacing:.02em;text-transform:uppercase}
.placeholder-editor__row{display:grid;grid-template-columns:minmax(0,140px) minmax(0,220px) minmax(0,1fr);gap:12px;align-items:start}
.placeholder-editor__row code{display:inline-block;background:#fff;border:1px solid var(--border);border-radius:6px;padding:4px 10px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:13px;color:#374151}
.placeholder-editor__row input{width:100%;padding:6px 8px;border:1px solid var(--border);border-radius:6px;font-size:13px;line-height:1.3;color:#111}
.placeholder-editor__row textarea{width:100%;min-height:38px;resize:vertical;padding:6px 8px;border:1px solid var(--border);border-radius:6px;font-size:13px;line-height:1.4}
.placeholder-editor__empty{color:var(--muted);font-size:13px}

/* === Mode toggle spacing ================================================== */
.mode{margin-top:8px}

/* === Busy/processing state ===============================================
   What it does:
     - Shows a progress cursor anywhere on the page while work is ongoing.
   How to use:
     - JS should toggle `document.body.classList.toggle('busy', true/false)`.
     - (Optional) Also set `document.body.setAttribute('aria-busy','true')` in JS.
   Notes:
     - Buttons are disabled during work by JS (see :disabled rule below).
   ========================================================================== */
body.busy, body.busy * { cursor: progress !important; }

/* Disabled buttons:
   - Visual feedback and prevent clicks while a request is in-flight.
   - Example (JS): `btn.disabled = true;` during async operations.
*/
button:disabled{opacity:.6;cursor:not-allowed;pointer-events:none}

/* === Nav: active link highlight ========================================= */
.nav a.active{ background:#e0e7ff; color:#111827; }

/* split view for the LLM output */
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  align-items: start;
}

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

.output.html-output {
  /* unlike <pre>, this should wrap like normal HTML */
  white-space: normal;
  overflow-wrap: anywhere;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: 12px;
  min-height: 120px;
}

/* Formatter base */
.llm-clean {
  font-family: system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, Arial, sans-serif;
  max-width: 65ch;
  line-height: 1.55;
  font-size: 13px;   /* consistent size */
  color: #111;
}
.llm-clean h1, .llm-clean h2, .llm-clean h3, .llm-clean h4 { margin: .75em 0 .35em; line-height: 1.25; }
.llm-clean p { margin: .5em 0; }
.llm-clean ul, .llm-clean ol { margin: .5em 0 .5em 1.25em; padding: 0; }
.llm-clean li { margin: .25em 0; }
.llm-clean pre { background: #f6f8fa; padding: .6em .75em; border-radius: .5rem; overflow: auto; font-size: .95em; }
.llm-clean code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .95em; }
.llm-clean blockquote { margin: .6em 0; padding-left: .8em; border-left: 3px solid #ddd; color: #555; }
.llm-clean a { text-decoration: none; border-bottom: 1px solid rgba(0,0,0,.25); }

/* Ensure the HTML pane doesn’t inherit <pre> sizing */
.output.html-output { white-space: normal; overflow-wrap: anywhere; font-size: 1rem; }


/* === Chat UI ============================================================= */
.chatlog{
  background:#fff;
  border:1px solid var(--border);
  border-radius:12px;
  padding:12px;
  height:420px;               /* tweak if you want a taller chat view */
  overflow:auto;
  display:flex;
  flex-direction:column;
  gap:8px;
}

.bubble{
  max-width:80%;
  border:1px solid var(--border);
  border-radius:14px;
  padding:10px 12px;
  line-height:1.45;
  box-shadow:0 1px 1px rgba(0,0,0,.02);
  background:#fff;
  word-wrap:break-word;
  overflow-wrap:anywhere;
}
.bubble .who{
  font-size:12px;
  color:var(--muted);
  margin-bottom:4px;
}
.bubble .text{
  white-space:pre-wrap;
}

/* Roles */
.bubble.user{
  margin-left:auto;
  background:#eef2ff;
  border-color:#dbeafe;
}
.bubble.assistant{
  margin-right:auto;
  background:#f3f4f6;
}
.bubble.system{
  margin:0 auto;
  background:#fff7ed;
  border-color:#fed7aa;
}

/* Optional: visual hint while streaming */
.bubble.streaming{
  box-shadow:0 0 0 3px rgba(37,99,235,.12) inset;
}

/* Chat input row */
.chatinput{
  display:grid;
  grid-template-columns:1fr auto;
  gap:10px;
  margin-top:12px;
  align-items:end;
}
.chatinput textarea{
  min-height:60px;
  resize:vertical;
}
.chatinput .row{
  justify-content:flex-end;
}

/* === Tuning page: monospace for JSON-ish fields ========================= */
#t_response_format,
#t_logit_bias,
#t_extra{
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  font-variant-ligatures: none;
}

/* === Vars grid: better wrapping on mobile ================================ */
@media (max-width: 900px){
  .grid2{ grid-template-columns:1fr; }
  .vars-grid{ grid-template-columns:1fr; }
  .chatlog{ height:55vh; }
}

/* === Fine-tuning: focus ring for accessibility ========================== */
.bubble:focus-within{
  outline: 2px solid rgba(37,99,235,.35);
  outline-offset: 2px;
}

/* Hints & quick guide */
.hint{ color:var(--muted); font-size:12px; line-height:1.35; }
.hint code{ background:#f3f4f6; border:1px solid var(--border); border-radius:6px; padding:0 4px; }

details.help{
  margin:8px 0 12px 0;
  background:#f9fafb;
  border:1px solid var(--border);
  border-radius:10px;
  padding:8px 10px;
}
details.help summary{ cursor:pointer; font-weight:600; }
details.help ul{ margin:8px 0 0 18px; padding:0; }
details.help li{ margin:4px 0; }

/* Public/Private, Visible/Hidden badges */
.badge { display:inline-flex; align-items:center; gap:6px; padding:2px 6px; border-radius:12px; font-size:.9rem; }
.badge-public  { background:rgba(16,185,129,.12); color:#065f46; }   /* green-ish */
.badge-private { background:rgba(239,68,68,.12);  color:#7f1d1d; }   /* red-ish  */

/* If you prefer image icons instead of emoji:
.badge-public::before  { content:""; width:1em; height:1em; background:url(/icons/unlock.svg) no-repeat center/contain; }
.badge-private::before { content:""; width:1em; height:1em; background:url(/icons/lock.svg)   no-repeat center/contain; }
*/

/* === Admin: shares manager =============================================== */
.form.grid2 { align-items: start; }  /* keep both columns top-aligned */

.listbox {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px;
  min-height: 360px;
  max-height: 360px;
  overflow: auto;
  background: #fff;
}
.listbox .rowitem {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 2px;
  border-bottom: 1px dashed rgba(0,0,0,0.06);
}
.listbox .rowitem:last-child { border-bottom: none; }

.pill { font-size: .85em; padding: 2px 6px; border-radius: 999px; background: rgba(0,0,0,.06); }
.pill.ok    { background: rgba(16,185,129,.12); color: #065f46; }
.pill.warn  { background: rgba(239,68,68,.12);  color: #7f1d1d; }
.pill.muted { background: rgba(0,0,0,.05);      color: var(--muted); }

/* === Badges: Visible/Hidden (to match your Public/Private) ================ */
.badge-visible { background: rgba(59,130,246,.12); color: #1e3a8a; }   /* blue-ish */
.badge-hidden  { background: rgba(107,114,128,.15); color: #374151; }  /* gray-ish */
