/* Portfolio Builder (see templates/portfolios/_portfolio_builder.html)

   Small consolidated token set instead of one-off margins/heights per
   element -- keeps the card's vertical rhythm and control sizing
   consistent without restyling anything. */
.portfolio-builder {
  margin-bottom: 1rem;
  --builder-section-gap: 0.4rem;
  --builder-control-height: 2.5rem;
  --builder-control-radius: 0.6rem;
}

@media (max-width: 767.98px) {
  .portfolio-builder {
    /* 44px -- comfortable touch target, matches iOS/Android guidance. */
    --builder-control-height: 2.75rem;
    /* Keep mobile a bit more generous than desktop's tightened rhythm --
       touch layouts need the extra breathing room more than desktop does. */
    --builder-section-gap: 0.55rem;
  }

  /* Bootstrap's .form-control/.form-select render at 14px here, and iOS
     Safari auto-zooms the whole page on focusing any input under 16px --
     quantityInput.focus() (see selectSearchResult() in portfolio-builder.js,
     called on every Quick Add tap) was triggering that zoom. 16px is the
     iOS zoom threshold, so bump just these three focusable controls back
     up on mobile rather than the site-wide .form-control default. */
  .builder-mode-select,
  .builder-search-input,
  .builder-quantity-input {
    font-size: 16px;
  }
}

.builder-head {
  margin-bottom: var(--builder-section-gap);
}

.builder-title {
  font-size: 1.2rem;
  font-weight: 800;
  color: var(--ss-text, #eef2f9);
  margin: 0;
}

.builder-form-row {
  display: grid;
  grid-template-columns: minmax(100px, 1fr) minmax(260px, 4fr) minmax(70px, 1fr) auto;
  grid-template-areas: "mode search qty add";
  gap: 0.55rem;
  align-items: end;
  margin-top: 0;
}

.builder-field--mode { grid-area: mode; }
.builder-field--search { grid-area: search; }
.builder-field--quantity { grid-area: qty; }
.builder-field--add { grid-area: add; }

.builder-quickstart {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: var(--builder-section-gap) 0 0 0;
  font-size: 0.82rem;
}

.builder-quickstart-label {
  color: var(--ss-text-secondary, rgba(230, 236, 245, 0.55));
}

.builder-quickstart-chips {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.builder-quickstart-chip {
  border: none;
  background: transparent;
  /* Padding (not a min-height/pill) widens the tap target on mobile
     without making this look like another button -- stays a text link. */
  padding: 0.4rem 0.3rem;
  margin: -0.4rem -0.3rem;
  color: var(--ss-accent, #34d399);
  font-weight: 600;
  font-size: 0.82rem;
  line-height: 1;
  text-decoration: underline;
  text-decoration-color: transparent;
  border-radius: 0.3rem;
}

.builder-quickstart-chip:hover,
.builder-quickstart-chip:focus-visible {
  text-decoration-color: currentColor;
}

.builder-quickstart-chip:focus-visible {
  outline: 2px solid rgba(99, 179, 237, 0.8);
  outline-offset: 2px;
}

.builder-quickstart-sep {
  color: var(--ss-text-secondary, rgba(230, 236, 245, 0.35));
}

.builder-field {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-width: 0;
}

.builder-field-label {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--ss-text-secondary, rgba(230, 236, 245, 0.6));
  margin: 0;
}

/* Bootstrap's default .form-control/.form-select are bright white, which
   reads as a jarring block on this dark theme -- tone them down to the
   same "raised element" surface token used elsewhere on dark cards while
   keeping enough contrast for readability. Shared height/radius tokens
   (see .portfolio-builder above) keep the mode select, ticker search,
   quantity input, and Add button visually aligned as one control row. */
.builder-mode-select,
.builder-search-input,
.builder-quantity-input,
.builder-add-btn {
  min-height: var(--builder-control-height);
  border-radius: var(--builder-control-radius);
}

.builder-add-btn {
  display: flex;
  align-items: center;
  justify-content: center;
}

@media (min-width: 768px) {
  /* Desktop-only: give Add more visual presence/weight in the form row --
     mobile keeps its own dedicated width rule further down (unaffected). */
  .builder-add-btn {
    min-width: 6.5rem;
  }
}

.builder-mode-select,
.builder-search-input,
.builder-quantity-input {
  background-color: var(--ss-surface-soft, #111f33);
  border: 1px solid rgba(255, 255, 255, 0.14);
  color: var(--ss-text, #eef2f9);
}

.builder-mode-select {
  width: 100%;
}

.builder-search-input:focus,
.builder-quantity-input:focus,
.builder-mode-select:focus {
  background-color: var(--ss-surface-soft, #111f33);
  color: var(--ss-text, #eef2f9);
  border-color: rgba(99, 179, 237, 0.6);
  box-shadow: 0 0 0 0.2rem rgba(99, 179, 237, 0.15);
}

.builder-search-input::placeholder {
  color: var(--ss-text-secondary, rgba(230, 236, 245, 0.45));
}

.builder-search-wrap {
  position: relative;
}

.builder-search-results {
  position: absolute;
  z-index: 40;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  margin: 0;
  padding: 0.3rem;
  list-style: none;
  max-height: 280px;
  overflow-y: auto;
  background: var(--ss-surface, #101a2e);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 0.6rem;
  box-shadow: 0 16px 32px rgba(3, 8, 20, 0.4);
}

.builder-search-result {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  width: 100%;
  padding: 0.45rem 0.55rem;
  border: none;
  border-radius: 0.45rem;
  cursor: pointer;
  color: var(--ss-text, #eef2f9);
  background: transparent;
  text-align: left;
  font: inherit;
}

.builder-search-result:hover,
.builder-search-result.is-active {
  background: rgba(99, 179, 237, 0.16);
}

.builder-search-result img,
.builder-search-result .builder-search-result-fallback {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  flex: 0 0 auto;
  object-fit: cover;
}

.builder-search-result-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.62rem;
  font-weight: 700;
  background: rgba(255, 255, 255, 0.08);
  color: var(--ss-text-secondary, rgba(230, 236, 245, 0.72));
}

.builder-search-result-text {
  min-width: 0;
  display: flex;
  flex-direction: column;
  line-height: 1.25;
}

.builder-search-result-symbol {
  font-weight: 700;
  font-size: 0.9rem;
}

.builder-search-result-name {
  font-size: 0.78rem;
  color: var(--ss-text-secondary, rgba(230, 236, 245, 0.62));
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.builder-search-empty {
  padding: 0.5rem 0.6rem;
  font-size: 0.85rem;
  color: var(--ss-text-secondary, rgba(230, 236, 245, 0.6));
}

.builder-form-error {
  margin: var(--builder-section-gap) 0 0 0;
  font-size: 0.86rem;
  color: #ff8080;
}

.builder-holdings-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: var(--builder-section-gap) 0 0 0;
  padding: 0;
  list-style: none;
}

.builder-holdings-list:empty {
  margin-top: 0;
}

.builder-chip {
  display: flex;
  align-items: stretch;
  gap: 0.15rem;
  border-radius: 0.85rem;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.05);
  max-width: 100%;
  animation: builder-chip-in 220ms ease both;
}

/* Every render recreates all chips (see renderHoldingsList()), so this
   plays each time the list updates -- kept very short/subtle (per "not
   flashy") rather than a one-off single-node insert animation. */
@keyframes builder-chip-in {
  from {
    opacity: 0;
    transform: translateY(3px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .builder-chip {
    animation: none;
  }
}

.builder-chip-main {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.3rem 0.5rem 0.3rem 0.5rem;
  border: none;
  background: transparent;
  border-radius: 0.85rem 0 0 0.85rem;
  cursor: pointer;
  min-width: 0;
  text-align: left;
  font: inherit;
  color: inherit;
}

.builder-chip:hover,
.builder-chip:focus-within {
  border-color: rgba(99, 179, 237, 0.5);
}

.builder-chip-main:focus-visible {
  outline: 2px solid rgba(99, 179, 237, 0.8);
  outline-offset: -2px;
}

.builder-chip-logo {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.08);
}

.builder-chip-logo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.builder-chip-logo-fallback {
  font-size: 0.6rem;
  font-weight: 700;
  color: var(--ss-text-secondary, rgba(230, 236, 245, 0.72));
}

.builder-chip-text {
  display: flex;
  flex-direction: column;
  line-height: 1.2;
  min-width: 0;
}

.builder-chip-ticker-row {
  display: flex;
  align-items: baseline;
  gap: 0.35rem;
  min-width: 0;
}

.builder-chip-ticker {
  font-weight: 800;
  font-size: 0.92rem;
  color: var(--ss-text, #eef2f9);
  white-space: nowrap;
}

.builder-chip-company {
  font-size: 0.72rem;
  color: var(--ss-text-secondary, rgba(230, 236, 245, 0.55));
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.builder-chip-meta {
  font-size: 0.74rem;
  color: var(--ss-text-secondary, rgba(230, 236, 245, 0.62));
}

.builder-chip-remove {
  flex: 0 0 auto;
  align-self: center;
  border: none;
  background: transparent;
  color: var(--ss-text-secondary, rgba(230, 236, 245, 0.6));
  font-size: 1.05rem;
  line-height: 1;
  min-width: 2.25rem;
  min-height: 2.25rem;
  margin-right: 0.15rem;
  border-radius: 50%;
}

.builder-chip-remove:hover {
  color: #ff8080;
  background: rgba(255, 128, 128, 0.12);
}

.builder-chip-remove:focus-visible,
.builder-search-result:focus-visible,
.builder-mode-select:focus-visible,
.builder-search-input:focus-visible,
.builder-quantity-input:focus-visible,
.builder-add-btn:focus-visible {
  outline: 2px solid rgba(99, 179, 237, 0.8);
  outline-offset: 2px;
}

.builder-summary {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 0.9rem;
  margin-top: 0.6rem;
  padding-top: 0.5rem;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  font-size: 0.85rem;
  color: var(--ss-text-secondary, rgba(230, 236, 245, 0.72));
}

.builder-summary-item.is-over-allocated {
  color: #ffb366;
  font-weight: 700;
}

.builder-clear-all {
  margin-left: auto;
  padding: 0;
  font-size: 0.85rem;
  color: #ff8080;
  text-decoration: none;
}

.builder-broker-cta {
  margin-top: var(--builder-section-gap);
  padding-top: 0.6rem;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  opacity: 1;
  transition: opacity 0.4s ease;
}

.builder-broker-cta.is-entering {
  opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
  .builder-broker-cta {
    transition: none;
  }
}

.builder-broker-cta-title {
  font-weight: 600;
  font-size: 0.8rem;
  color: var(--ss-text-secondary, rgba(230, 236, 245, 0.75));
  margin: 0 0 0.15rem 0;
}

.builder-broker-cta-body {
  font-size: 0.78rem;
  line-height: 1.4;
  color: var(--ss-text-secondary, rgba(230, 236, 245, 0.55));
  margin: 0 0 0.55rem 0;
  max-width: 40rem;
}

.builder-broker-cta-btn {
  white-space: nowrap;
  font-size: 0.82rem;
  padding: 0.35rem 0.85rem;
  opacity: 0.9;
}

.builder-broker-cta-btn:hover {
  opacity: 1;
}

.builder-empty-state {
  padding: 1.4rem;
  text-align: center;
  margin-bottom: 1rem;
}

.builder-empty-state__title {
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--ss-text, #eef2f9);
  margin: 0 0 0.35rem 0;
}

.builder-empty-state__body {
  font-size: 0.9rem;
  color: var(--ss-text-secondary, rgba(230, 236, 245, 0.72));
  margin: 0;
}

/* Zero-holdings Allocation/Risk preview: a dimmed, non-interactive example
   visualization (built from the SharpeShare showcase portfolio data) with
   a centered call-to-action overlay -- see snapshot_tab.html/deepview_tab.html
   and _build_example_snapshot_view_model() in public/views.py. */
.ss-preview-host {
  position: relative;
}

.ss-preview-host.is-preview .ss-preview-host__content {
  filter: grayscale(65%) opacity(0.5);
  pointer-events: none;
  user-select: none;
}

.ss-preview-overlay {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 16px;
  pointer-events: none;
}

.ss-preview-overlay__message {
  /* The dimmed content behind this can be much taller than one viewport
     (e.g. the whole Risk tab, chart + diversification/attribution cards)
     -- stick the message near the vertical center of the viewport as the
     user scrolls, instead of centering it once in the middle of the full
     (possibly very tall) dimmed region where it could land off-screen. */
  position: sticky;
  top: 40vh;
  margin: 0;
  padding: 0.55rem 1.1rem;
  max-width: 22rem;
  text-align: center;
  font-weight: 700;
  font-size: 0.92rem;
  color: var(--ss-text, #eef2f9);
  background: var(--ss-surface, #101a2e);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: var(--ss-radius-pill, 999px);
  box-shadow: 0 12px 30px rgba(3, 8, 20, 0.45);
}

/* Preview insight placeholder (Diversification Benefit / Risk Attribution
   replacement, see _risk_attribution.html) -- deliberately low-emphasis:
   a single centered, muted line rather than a bordered card, so the chart
   above stays the focal point of the preview state. */
.ss-preview-insight-placeholder {
  margin: 0.75rem 0 0 0;
  padding: 0;
  text-align: center;
  color: var(--ss-text-secondary, rgba(230, 236, 245, 0.5));
  font-size: 0.85rem;
  font-weight: 500;
}

@media (max-width: 767.98px) {
  /* Compact 3-row layout: mode selector on its own row, ticker search gets
     a full-width row (most of the horizontal space, for logos/company
     names), then shares + Add share one compact row instead of every
     control stacking full-width. Control heights already scale up via
     --builder-control-height above -- only the Add button's width and the
     remove icon's tap target need a mobile-only bump here. */
  .builder-form-row {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "mode mode"
      "search search"
      "qty add";
    row-gap: 0.5rem;
  }
  .builder-add-btn {
    min-width: 4.75rem;
  }
  .builder-chip-remove {
    min-width: 2.5rem;
    min-height: 2.5rem;
  }
}

/* Subtle cross-fade around swapResultsRegion()'s innerHTML swap (preview
   -> real analysis, and any later holding change) -- see
   portfolio-builder.js. Scoped to this stylesheet since it's only loaded
   for the free/manual builder. */
#portfolio-results-region {
  transition: opacity 160ms ease;
  opacity: 1;
}

#portfolio-results-region.is-updating {
  opacity: 0.4;
}

@media (prefers-reduced-motion: reduce) {
  #portfolio-results-region {
    transition: none;
  }
}
