/* ============================================================
   Souppe Chip Entry - styles for the one-field portfolio entry.
   ------------------------------------------------------------
   Paired with public/js/portfolio_chips.js and shared by every
   surface that mounts SouppeChipEntry: the staged landing hero,
   the retail analyzer and the accredited workspace.

   The .demo-* prefix is historical - the entry was born in the
   homepage demo. It is kept because the class names are load-
   bearing in deployed markup and JS, and renaming them would
   buy nothing.

   The box sits on whatever background the page gives it. Its
   own surfaces restore the light-theme text tokens, so it reads
   correctly inside the dark hero band as well as on the white
   analyzer panels. Uses the brand tokens from styles.css :root.
   ============================================================ */
/* ── The box ─────────────────────────────────────────────── */

.demo-shell {
  position: relative;
  max-width: 720px;
  margin: 0 auto;
  text-align: left;
}

/* On the analyzer pages the entry owns the whole panel. The 720px cap above
   is a hero measure - it keeps the box in proportion under a headline, and
   applying it here would waste the width the stacked layout exists to give. */
.pf-chip-shell {
  max-width: none;
}

/* The instruction. Brighter than the pain line above it and tight against
   the box, because it is the ask, not the argument: it has to read as the
   thing to do next rather than as one more sentence about the product. */
.demo-instruction {
  margin: 0 auto 12px;
  text-align: center;
  font-size: 16px;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.88);
  text-wrap: balance;
}

/* The hero band redefines --color-text/--color-text-secondary to white
   for its dark background. These components are white cards sitting
   INSIDE the hero, so they restore the light-theme text tokens. The
   hint chips are NOT in this list - they are ghost pills on the dark. */
.demo-box,
.demo-ac,
.demo-result {
  --color-text: #0F172A;
  --color-text-secondary: #475569;
  --color-text-muted: #94A3B8;
}

/* Two regions, stacked: the holdings collect at the top, the entry line sits
   under them. Before this they shared one wrapping row, so the field drifted
   to wherever the last chip left off and shrank as the portfolio grew - by
   ten positions you were typing into whatever gap remained. */
.demo-box {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px;
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--card-shadow);
  cursor: text;
  transition: box-shadow var(--transition-base), border-color var(--transition-base);
}

/* The holdings bar. Scrolls once it is deep enough that the entry line would
   otherwise be pushed off screen - the field and the button stay put. */
.demo-box__holdings,
.demo-box__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  max-height: min(34vh, 260px);
  overflow-y: auto;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--card-border);
}

/* Nothing held yet: no empty bar, no rule, just the one line. */
.demo-box__chips:empty {
  display: none;
}

.demo-box__entry {
  display: flex;
  align-items: center;
  gap: 8px;
}

.demo-box:focus-within {
  border-color: var(--color-blue);
  box-shadow: 0 0 0 3px rgba(6, 68, 238, 0.12), var(--card-shadow-hover);
}

.demo-box--busy { opacity: 0.85; pointer-events: none; }

.demo-box__input {
  /* Wrapping is decided on the basis, not on the width the input ends up
     with. 180 keeps a two-chip portfolio on one row beside the action
     column; the input still grows to fill whatever is left. */
  flex: 1 1 180px;
  min-width: 160px;
  border: none;
  outline: none;
  font-family: var(--font-body);
  font-size: 16px;
  color: var(--color-text);
  background: transparent;
  padding: 8px 4px;
}

.demo-box__input::placeholder { color: var(--color-text-muted); }

/* Total above the button it belongs to, and the two as one flex item: the
   input grows, and without the grouping the button wraps to its own line
   and leaves the total stranded. */
.demo-box__actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  margin-left: auto;
}

.demo-box__analyze {
  flex: 0 0 auto;
}

/* Running weight total, beside Analyze. Amber while the portfolio is still
   being allocated, green once it is - a progress read, never an error,
   because whatever is entered becomes the whole portfolio either way. The
   three colours are the tier colours the results already use. */
.demo-box__total {
  flex: 0 0 auto;
  margin-left: auto;
  padding: 4px 10px;
  border-radius: 999px;
  font-family: var(--font-heading);
  font-size: 13px;
  font-weight: 700;
  cursor: default;
  transition: color var(--transition-base), background var(--transition-base);
}

.demo-box__total[hidden] { display: none; }

.demo-box__total--low   { color: #EA580C; background: rgba(234, 88, 12, 0.10); }
.demo-box__total--part  { color: #D97706; background: rgba(217, 119, 6, 0.10); }
.demo-box__total--full  { color: #047857; background: rgba(4, 120, 87, 0.10); }

/* Amount mode has no 100% to reach, so the total reports and does not
   judge: same pill, no verdict colour. */
.demo-box__total--plain {
  color: var(--color-text-secondary);
  background: var(--color-bg-tinted);
}

/* ── Tooltip ─────────────────────────────────────────────
   The site's own bubble, not the browser's: dark card, brand radius, a
   small tail, and it fades rather than appearing after a delay. Rendered
   inside .demo-shell so it is positioned against the box, and pointer
   events stay off so it can never sit between the cursor and a chip. */

.demo-tip {
  position: absolute;
  z-index: 40;
  max-width: 260px;
  padding: 7px 11px;
  border-radius: var(--radius-sm);
  background: #0B1B3A;
  border: 1px solid rgba(255, 255, 255, 0.10);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
  color: #FFFFFF;
  font-family: var(--font-body);
  font-size: 13px;
  line-height: 1.45;
  text-align: center;
  pointer-events: none;
  opacity: 0;
  transform: translateY(3px);
  transition: opacity 0.14s ease, transform 0.14s ease;
}

.demo-tip--on {
  opacity: 1;
  transform: translateY(0);
}

/* The tail, centred under the bubble. */
.demo-tip::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  margin-left: -5px;
  border: 5px solid transparent;
  border-top-color: #0B1B3A;
}

/* ── Position chips inside the box ───────────────────────── */

.demo-pos {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 6px 4px 10px;
  background: var(--color-bg-tinted);
  border: 1px solid var(--card-border);
  border-radius: 999px;
  font-size: 14px;
  line-height: 1.4;
}

.demo-pos__ticker {
  font-weight: 700;
  font-family: var(--font-heading);
  color: var(--color-text);
}

/* Both of these are controls, so both have to look like one. The market
   button carries a chevron, the weight field a caret and an underline that
   darkens under the pointer - without them the chip reads as a label and
   nobody discovers that either can be changed. */
.demo-pos__country {
  border: none;
  border-radius: 4px;
  background: transparent;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--color-blue);
  cursor: pointer;
  padding: 2px 3px;
}

.demo-pos__country::after {
  content: '';
  display: inline-block;
  width: 0;
  height: 0;
  margin-left: 3px;
  vertical-align: 1px;
  border-left: 3px solid transparent;
  border-right: 3px solid transparent;
  border-top: 3px solid currentColor;
  opacity: 0.7;
}

.demo-pos__country:hover { background: rgba(6, 68, 238, 0.09); }
.demo-pos__country--quiet { color: var(--color-text-muted); }
.demo-pos__country--quiet:hover { color: var(--color-blue); }

.demo-pos__weight {
  width: 52px;
  border: none;
  border-bottom: 1px dashed var(--card-border-hover);
  background: transparent;
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--color-text-secondary);
  text-align: right;
  outline: none;
  cursor: text;
}

.demo-pos__weight:hover { border-bottom-color: var(--color-blue); }
.demo-pos__weight:focus { border-bottom-color: var(--color-blue); color: var(--color-text); }

.demo-pos__country:focus-visible,
.demo-pos__weight:focus-visible {
  outline: 2px solid var(--color-blue);
  outline-offset: 1px;
}

/* A weight nobody set: the share this position WOULD get, shown as a
   placeholder so the split is visible while the portfolio is being built
   rather than announced once the analysis has already run. */
.demo-pos__weight--ghost::placeholder {
  color: var(--color-text-muted);
  font-style: italic;
  opacity: 1;
}

.demo-pos--typing { border-color: var(--color-blue); }

/* A ticker the validator did not recognise. Marked, never removed - the
   visitor decides whether it was a typo. */
.demo-pos--unknown {
  border-color: #FCA5A5;
  background: rgba(220, 38, 38, 0.05);
}

/* Marks the page owns, not the entry: a ticker the pre-flight could not
   price, and the tracker's diff against the committed paper portfolio.
   These mirror .pf-row--missing / --sync-new / --sync-changed on the row
   table so both entries speak the same visual language. */
.demo-pos--missing {
  border-color: #FCA5A5;
  background: rgba(220, 38, 38, 0.08);
}

.demo-pos--sync-new {
  border-color: rgba(4, 120, 87, 0.45);
  background: rgba(4, 120, 87, 0.07);
}

.demo-pos--sync-changed {
  border-color: rgba(217, 119, 6, 0.45);
  background: rgba(217, 119, 6, 0.07);
}

.demo-pos__remove {
  border: none;
  background: transparent;
  color: var(--color-text-muted);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 4px;
  border-radius: 50%;
}

.demo-pos__remove:hover { color: #DC2626; background: rgba(220, 38, 38, 0.08); }

/* ── Autocomplete ────────────────────────────────────────── */

.demo-ac {
  position: absolute;
  z-index: 30;
  margin-top: 6px;
  width: min(420px, 90vw);
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: var(--radius-md);
  box-shadow: var(--card-shadow-hover);
  overflow: hidden;
}

.demo-ac__item {
  display: flex;
  align-items: baseline;
  gap: 10px;
  width: 100%;
  padding: 9px 14px;
  border: none;
  background: transparent;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-body);
}

.demo-ac__item:hover,
.demo-ac__item--active { background: var(--color-bg-tinted); }

.demo-ac__ticker { font-weight: 700; font-size: 14px; color: var(--color-text); }
.demo-ac__name {
  font-size: 13px;
  color: var(--color-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── Names, count, caption, note ─────────────────────────── */

/* The names Souppe resolved, and how many positions it holds. This is the
   line that tells the visitor they were understood. */
.demo-names {
  display: flex;
  align-items: baseline;
  gap: 16px;
  margin: 10px 4px 0;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.62);
}

.demo-names[hidden] { display: none; }

.demo-names__list {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.demo-names__count {
  flex: 0 0 auto;
  color: rgba(255, 255, 255, 0.45);
}

.demo-names__miss { color: #FCA5A5; }

/* Centred under the box, on the same axis as the headline above it -
   the hero reads down one line, never left-then-centre-then-left. */
.demo-caption {
  margin: 12px auto 0;
  text-align: center;
  font-size: 14px;
  color: var(--color-text-secondary);
}

/* The second door, quieter than the price it follows, and on its own line:
   left inline it wraps in the middle of "Excel, CSV, JSON or TSV". */
.demo-caption__quiet {
  display: block;
  color: rgba(255, 255, 255, 0.45);
}

.demo-caption span[hidden] { display: none; }

.demo-note {
  margin: 10px auto 0;
  text-align: center;
  font-size: 14px;
  color: var(--color-text-secondary);
}

/* The caption and note sit on the dark hero background. */
.demo-note--warn { color: #FBBF24; }
.demo-note--loading { color: var(--color-cyan); }
.demo-note a { color: var(--color-cyan); text-decoration: underline; }

/* ── Mobile ──────────────────────────────────────────────── */

@media (max-width: 640px) {
  .demo-box { padding: 10px 12px; }
  .demo-box__input { font-size: 15px; }
  /* Full-width action block under the field: the button spans the box with
     the total centred above it. `stretch` is what widens the button in a
     column - flex-grow would only give it height. */
  .demo-box__entry { flex-wrap: wrap; }
  .demo-box__actions {
    flex: 1 1 100%;
    margin-left: 0;
    align-items: stretch;
  }
  .demo-box__total { align-self: center; }
}
