/* --- Brand tokens ---------------------------------------------------------
   The first group is copied verbatim from the :root block of
   businessplancompany.com/styles.css (fetched 2026-08-25) so this app and the
   public site cannot drift apart. Do not hand-tune these values -- if the site
   is restyled, re-copy the block rather than nudging hexes here.

   Cross-checked against app/static/brand/logo_color_medium.png, which samples
   to the same two families (navy ~#1B334B, gold ~#EBAB15/#BF8410) and nothing
   else. That is the evidence these are the live brand colours rather than a
   palette left over from an old redesign.

   The second group is this app's semantic layer, defined in terms of the
   first. Rules below refer only to the semantic names, so a brand change is a
   one-line edit here rather than a sweep through the stylesheet.
   ------------------------------------------------------------------------ */
:root {
  --navy: #1B3A5C;
  --navy-deep: #0F2742;
  --navy-soft: #2D4F73;
  --gold: #E8B830;
  --gold-deep: #C99A1F;
  --gold-light: #F4D373;
  --cream: #FDF8ED;
  --cream-warm: #F5EDD9;
  --ink: #1A1F2E;
  --muted: #6B7380;
  --line: rgba(27, 58, 92, 0.12);

  --serif: 'Fraunces', Georgia, 'Times New Roman', serif;
  --display: 'Barlow Condensed', 'Helvetica Neue', Impact, sans-serif;
  --sans: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --accent: var(--navy);
  --accent-tint: #EAF0F6;
  --surface: #ffffff;
  --border: var(--line);
  /* The site has no "warning" colour -- gold is its attention colour, so
     warnings borrow it. The background is gold at ~12% over cream, mixed
     down here rather than layered with opacity so it stays a flat value
     that nested elements can sit on. */
  --warn-bg: #FBF1D6;
  --warn-border: var(--gold);
  /* No brand red exists either. Errors must not read as gold, so this keeps
     the previous red -- it is the one colour on the page that is deliberately
     off-brand, because "wrong" has to be unmistakable. */
  --error: #B3261E;
}

* { box-sizing: border-box; }

body {
  font-family: var(--sans);
  color: var(--ink);
  background: var(--cream);
  line-height: 1.5;
  margin: 0;
  -webkit-font-smoothing: antialiased;
}

/* The site sets headings in Fraunces and body copy in Inter. Sizes here are
   deliberately NOT the site's -- it uses clamp(2.5rem, 6vw, 5rem) for h1,
   which is right for a landing page and unusable above a dense work queue.
   The typeface is the brand; the scale belongs to the tool. */
h1, h2, h3 {
  font-family: var(--serif);
  color: var(--navy-deep);
  font-weight: 500;
  letter-spacing: -0.01em;
}
h1 { font-size: 1.85rem; }
h2 { font-size: 1.35rem; }
h3 { font-size: 1.1rem; }

/* Plain links inside the page body -- the "Back" links, mostly. Without
   this they render as browser-default blue, which against navy and gold
   reads as a broken style rather than a link. */
a { color: var(--accent); }
a:hover { color: var(--gold-deep); }

.topbar {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.6rem 1.5rem;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
/* Logo lockup + tool name. The logo reads "Business Plan Company"; the
   wordmark beside it says which of the company's tools this is. */
.topbar .brand { display: flex; align-items: center; gap: 0.55rem; text-decoration: none; }
.topbar .brand img { height: 30px; width: auto; display: block; }
.topbar .brand span {
  font-family: var(--display);
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--navy-deep);
}
.topbar .user { color: var(--muted); flex: 1; font-size: 0.9rem; }
.topbar a { color: var(--accent); text-decoration: none; font-weight: 500; }
.topbar a:hover { color: var(--gold-deep); }

main { max-width: 960px; margin: 0 auto; padding: 1.5rem; }

h1 { margin-top: 0; }
.hint { color: var(--muted); font-size: 0.9rem; }

table { width: 100%; border-collapse: collapse; margin-bottom: 2rem; background: white; }
th, td { text-align: left; padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--border); vertical-align: top; }
.fields th { width: 220px; color: var(--muted); font-weight: 500; }

.inline-form { display: inline-block; margin-right: 0.4rem; }

/* 2026-09-12, Jim, live, on the editor files page: "add separation between
   download and reload" -- those two are plain <a> tags side by side with no
   wrapping form, so they had none of the 0.4rem gap .inline-form gives
   every button/form on this same row. Same spacing value, applied directly
   to the link instead. */
.action-link { margin-right: 0.4rem; }

button { cursor: pointer; padding: 0.4rem 0.8rem; border-radius: 6px; border: 1px solid var(--border); background: white; }
button.soon { color: var(--muted); cursor: not-allowed; }
button.live-button { background: var(--accent); color: white; border-color: var(--accent); font-weight: 600; }
button.danger-button { background: var(--error); color: white; border-color: var(--error); font-weight: 600; }

/* 2026-09-12, Jim, live, on the editor files page: "reload next to open in
   browser and then download as a blue button right after it with space."
   Download is a real <a> file-download link, not a form <button>, so it
   can't pick up button.live-button above (that selector only matches
   actual <button> elements) -- this gives an <a> the same blue/white/bold
   look as every other primary action in this app (Upload edited file(s),
   Done editing -- sync back) without changing what element it actually is. */
a.button-link {
  display: inline-block;
  padding: 0.4rem 0.8rem;
  border-radius: 6px;
  background: var(--accent);
  color: white;
  font-weight: 600;
  text-decoration: none;
}
a.button-link:hover { background: var(--navy-deep); }

/* 2026-09-12, Jim, live, on the editor files page: "can you have the text
   box line up with the buttons and drop down" -- the Regenerate
   pitch-deck-image form's <select>, <textarea> and <button> are plain
   inline elements, which vertical-align on their shared text BASELINE by
   default; a two-row <textarea> is much taller than a one-line
   select/button, so its baseline sits near its bottom and drags the
   select/button down with it, leaving all three visibly misaligned. A
   flex row with align-items: center fixes this by centering every child
   on the row's cross-axis instead of aligning text baselines -- applied
   here rather than to `.inline-form` generally, since that class is also
   used for single-control forms (e.g. "Open in browser") where this
   would be a no-op anyway, and scoping it narrowly avoids any risk of
   affecting an unrelated form later. Used in both app/templates/editor_files.html
   and app/templates/pipeline.html -- same form, same fix, in both places. */
.regenerate-form {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.error { color: var(--error); font-weight: 500; }

.warning {
  background: var(--warn-bg);
  border: 1px solid var(--warn-border);
  padding: 0.75rem 1rem;
  border-radius: 6px;
  margin-bottom: 1rem;
  font-weight: 600;
}

.preview {
  background: white;
  border: 1px solid var(--border);
  padding: 1rem;
  white-space: pre-wrap;
  max-height: 300px;
  overflow-y: auto;
  border-radius: 6px;
}

.notes { background: white; border: 1px solid var(--border); border-radius: 6px; padding: 1rem 1rem 1rem 2rem; }
.notes li { margin-bottom: 0.5rem; }

.outcome-done { color: var(--accent); font-weight: 600; }
.outcome-error { color: var(--error); font-weight: 600; }
.soon-label { color: var(--muted); }
.jobtypes td { font-size: 0.9rem; }
.admin-note { color: var(--muted); font-style: italic; }

/* 2026-09-12, Jim, live, screenshot of the dashboard's "Running now" badge
   rendering as jumbled, overlapping text: root cause is that these two
   classes were designed as standalone banners (app/templates/client_detail.html's
   big "plan ready"/"needs review" callouts, both real <p> tags, already
   block-level by default) but got reused as inline <span>s inside table
   cells (dashboard.html's per-client "Running now" badge, pipeline.html's
   matching one on the pipeline board). An inline element's vertical padding
   doesn't push surrounding line boxes apart the way a block element's does
   -- so the box's own padding/border/background painted directly on top of
   the <br>-separated "Started Xm Ys ago" text sitting right above/below it,
   producing exactly the overlapping look in the screenshot. display: block
   here is a no-op for every existing <p> usage (already block by default)
   and fixes both <span> usages by giving the badge its own line, matching
   what both templates' surrounding <br> tags already assumed was happening. */
.status-complete {
  display: block;
  background: var(--accent-tint);
  border: 1px solid var(--accent);
  color: var(--accent);
  padding: 0.9rem 1.2rem;
  border-radius: 6px;
  font-weight: 600;
  font-size: 1.05rem;
}
.status-review {
  display: block;
  background: var(--warn-bg);
  border: 1px solid var(--warn-border);
  padding: 0.9rem 1.2rem;
  border-radius: 6px;
  font-weight: 600;
  font-size: 1.05rem;
}

.login-box {
  max-width: 320px;
  margin: 4rem auto;
  background: white;
  padding: 2rem;
  border-radius: 8px;
  border: 1px solid var(--border);
}
.login-box label { display: block; margin-bottom: 1rem; font-size: 0.9rem; color: var(--muted); }
.login-box input { width: 100%; padding: 0.5rem; margin-top: 0.25rem; border: 1px solid var(--border); border-radius: 4px; }
.login-box button { width: 100%; background: var(--accent); color: white; border-color: var(--accent); padding: 0.6rem; }

.mode-cards { display: flex; gap: 1.5rem; margin-top: 2rem; }
.mode-card {
  flex: 1;
  display: block;
  background: white;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 2rem;
  text-decoration: none;
  color: var(--ink);
  transition: border-color 0.15s;
}
.mode-card:hover { border-color: var(--accent); }
.mode-card h2 { margin: 0 0 0.5rem 0; color: var(--accent); }
.mode-card p { margin: 0; color: var(--muted); }

.notice {
  background: var(--accent-tint);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.6rem 0.9rem;
  margin-bottom: 1.5rem;
}

/* Admin user management (admin_users.html) */
.users .row-inactive td { color: var(--muted); }
.user-form { background: white; border: 1px solid var(--border); border-radius: 8px; padding: 1.25rem; max-width: 420px; }
.user-form label { display: block; margin-bottom: 1rem; font-size: 0.9rem; color: var(--muted); }
.user-form input, .user-form select { width: 100%; padding: 0.5rem; margin-top: 0.25rem; border: 1px solid var(--border); border-radius: 4px; }
.user-form button { background: var(--accent); color: white; border-color: var(--accent); font-weight: 600; }

/* The copyable invite link (Brief 12). Shown after every invite, because
   with SMTP unconfigured it is the only way the link reaches the person --
   see app/jobs/mailer.py. Full width and monospace so a long signed token
   is readable and selectable in one click rather than truncated. */
.invite-box {
  background: white;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 1rem;
  margin-bottom: 1.5rem;
}
.invite-box p { margin: 0 0 0.5rem 0; }
.invite-link {
  width: 100%;
  padding: 0.5rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.8rem;
  background: var(--cream);
}

/* --- Pipeline view (see app/templates/pipeline.html) --- */

.pipeline-link {
  display: inline-block;
  padding: 0.4rem 0.8rem;
  border: 1px solid var(--accent);
  border-radius: 6px;
  background: white;
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
}
.pipeline-link:hover { background: var(--accent-tint); }

.stage-heading { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.25rem; }
.stage-count {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.05rem 0.55rem;
  background: white;
}

/* Small left-to-right progress indicator: one chip per stage in the
   mode's flow, with the client's current stage highlighted. Nothing
   equivalent existed in this stylesheet before. */
.stage-chips { display: inline-flex; flex-wrap: wrap; gap: 0.25rem; }
.stage-chip {
  font-size: 0.72rem;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.05rem 0.5rem;
  background: white;
  white-space: nowrap;
}
.stage-chip-current {
  color: white;
  background: var(--accent);
  border-color: var(--accent);
  font-weight: 600;
}
/* Added 2026-09-01 for the top-of-page progress bar (client_detail.html /
   pipeline.html's aggregate bar) -- a step that has already happened, as
   distinct from `.stage-chip-current` (the step happening right now).
   Both can apply to the same chip (the "just generated" step is both done
   and current -- see client_detail.html), so this stays a separate
   additive class rather than a replacement for `.stage-chip-current`. */
.stage-chip-done {
  color: var(--accent);
  border-color: var(--accent);
  font-weight: 600;
}
.progress-bar-label {
  margin: 0 0 0.4rem 0;
  font-size: 0.85rem;
  color: var(--muted);
}
.progress-bar {
  margin-bottom: 1.25rem;
}
.progress-bar .stage-chip {
  font-size: 0.85rem;
  padding: 0.25rem 0.85rem;
}

/* The aggregate version of the same idea, at the top of pipeline.html --
   how many active clients sit at each post-Intake step, not any one
   client's own position. A filled horizontal bar (not chips) so it reads
   as a single summary at a glance rather than a list to scan. */
.progress-summary {
  display: flex;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  margin-bottom: 1.5rem;
  background: white;
}
.progress-summary-step {
  flex: 1;
  padding: 0.6rem 0.9rem;
  border-right: 1px solid var(--border);
  text-align: center;
}
.progress-summary-step:last-child { border-right: none; }
.progress-summary-step .count {
  display: block;
  font-family: var(--serif);
  font-size: 1.4rem;
  color: var(--navy-deep);
  line-height: 1.1;
}
.progress-summary-step .label {
  font-size: 0.78rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.progress-summary-step.has-clients { background: var(--accent-tint); }
.progress-summary-step.has-clients .count { color: var(--accent); }

/* 2026-09-13, Jim, live, from the "Web Factory updates and fixes" doc:
   "When we do a batch build we need a loading progress bar under BP
   Creation Pipeline Title that shows where we are in the project
   overall." A BatchRun (app/models.py) has a real, known total and a
   real completed count the moment it starts, so this is an honest
   percentage-fill bar -- unlike .client-progress-fill just below, which
   deliberately never claims to know a percentage. */
.batch-progress { margin: 0.75rem 0 1.25rem 0; }
.batch-progress-track {
  background: var(--border);
  border-radius: 999px;
  height: 10px;
  overflow: hidden;
}
.batch-progress-fill {
  background: var(--accent);
  height: 100%;
  transition: width 0.6s ease;
}

/* 2026-09-13, Jim, live, same doc: "we need a better progress bar under
   the [client's] name in the main list. It should be a bar that loads
   until complete to make it easier to read." Deliberately an
   INDETERMINATE sliding-stripe animation, not a percentage fill --
   app/jobs/job_progress.py's own docstring explains why a fabricated
   percentage would be more misleading than no bar at all (nothing in
   this app knows how many turns a given client's build will take). The
   moving stripe communicates "actively working" honestly, without
   claiming to know how close to done it is. */
.client-progress-track {
  background: var(--border);
  border-radius: 999px;
  height: 8px;
  overflow: hidden;
  margin: 0.35rem 0;
}
.client-progress-fill {
  height: 100%;
  width: 40%;
  background: var(--accent);
  border-radius: 999px;
  animation: client-progress-slide 1.4s ease-in-out infinite;
}
@keyframes client-progress-slide {
  0% { margin-left: -40%; }
  100% { margin-left: 100%; }
}

.rework-flag {
  display: inline-block;
  margin-left: 0.4rem;
  font-size: 0.75rem;
  font-weight: 600;
  background: var(--warn-bg);
  border: 1px solid var(--warn-border);
  border-radius: 999px;
  padding: 0.05rem 0.55rem;
}

/* 2026-09-09, Jim, live: "the only thing that I think we need to see
   [in Intake] would be the client's name and status" -- three-state pill,
   same shape as .rework-flag above, for the simplified Intake roster
   (app/templates/pipeline.html). */
.status-pill {
  display: inline-block;
  font-size: 0.75rem;
  font-weight: 600;
  border-radius: 999px;
  padding: 0.05rem 0.55rem;
}
.status-pill-not-started { background: var(--cream-warm); border: 1px solid var(--border); color: var(--muted); }
.status-pill-in-progress { background: var(--warn-bg); border: 1px solid var(--warn-border); }
.status-pill-completed { background: var(--accent-tint); border: 1px solid var(--accent); color: var(--accent); }
/* 2026-09-15, task #515: a client whose Intake finished cleanly but whose
   Generate Plan/Apply Revisions never started and never will on its own
   (see app/main.py's _stalled_after_intake_run()) -- visually distinct
   from the neutral "not started, just waiting its turn" pill above, same
   red as .outcome-error elsewhere on this page, since both mean "this one
   actually needs you to do something." */
.status-pill-stalled { background: var(--cream-warm); border: 1px solid var(--error); color: var(--error); }

.pipeline td { vertical-align: middle; }
.history-row td { background: var(--cream-warm); }
.stage-history { margin: 0.5rem 0 0 0; font-size: 0.8rem; }
.stage-history .preview { max-height: 140px; font-size: 0.75rem; padding: 0.5rem; }

/* --- Editor review workspace (see app/templates/editor_queue.html) --- */

/* One upload form per client, with one file field per replaceable
   deliverable. Stacked rather than inline: the labels are full sentences
   ("Business plan (Word)"), and a row of file inputs wraps badly. */
.upload-form { display: flex; flex-direction: column; gap: 0.35rem; align-items: flex-start; }
.upload-field { font-size: 0.8rem; color: var(--muted); }
.upload-field input[type="file"] { display: block; margin-top: 0.15rem; font-size: 0.8rem; }

/* Settings page: one radio per line, and the radio itself must not stretch
   to the full width .user-form input gives text fields. */
.setting-choice { display: block; margin-bottom: 0.75rem; color: var(--ink); }
.setting-choice input[type="radio"] { width: auto; margin-right: 0.5rem; }

/* --- Brand lockup on the signed-out pages (login, invite) ---------------
   Full logo, wordmark and all, because these are the two pages someone may
   land on having never seen the app: the logo is what tells them whose tool
   this is. The topbar uses the cropped mark instead -- the lockup's
   "BUSINESS PLAN COMPANY" line is set small enough that at topbar height it
   degrades into an unreadable smudge. */
.brand-lockup { display: block; margin: 0 auto 1.5rem auto; height: 96px; width: auto; }
.login-box h1 { font-size: 1.4rem; text-align: center; margin-bottom: 1.5rem; }
