/* Settings view (#/settings) — a left section tab list and the four section
 * panels. The tab list is a real WAI-ARIA tablist (role=tablist, role=tab,
 * role=tabpanel, aria-selected, aria-controls, aria-labelledby, roving
 * tabindex, Arrow/Home/End). Only the selected section's panel is in the DOM;
 * the panel tree is a single tabpanel each, with the visible one carrying
 * hidden=false and the others hidden=true, so the page never scrolls and
 * every keyboard and screen-reader behaviour is the standard pattern.
 *
 * This file layers ON TOP of the shared shells in styles.css (.view-head,
 * .panel, .field, .field-hint, .btn, .form-error, .form-ok, .empty-note,
 * .banner, .dot, .conn-ok/-warn/-bad, .badge, .card) and the components the
 * view composes (SegmentedControl .tabs/.tab, StatCard .card/.stat-card,
 * States .state-*); it only adds or restyles what the approved design asks
 * for.
 *
 * Colour, type, spacing, radius and motion come from tokens.css custom
 * properties only: no colour literal of any kind lives here (transparent /
 * currentColor / inherit excepted), nothing is fetched, and no raw length
 * that a token already carries is written out. The 168 px nav column, the
 * 180 px label column (matching Settings.dc), the 220 px field floor, the
 * 360 px control ceiling and the 180 px card floor are design-locked values
 * (min()-clamped below 768); the phone rules live in the tail media block.
 *
 * Loading: views/settings.js appends <link rel="stylesheet" href="…settings.css">
 * to the document head at mount (idempotent), because index.html links only
 * styles.css and the component sheets until the Phase 4 shell task.
 */

/* ---- page frame --------------------------------------------------------- */

.settings {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.settings-state {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* ---- layout: section tab list + single tabpanel ------------------------ */

.settings-layout {
  display: grid;
  grid-template-columns: 168px minmax(0, 1fr);
  gap: var(--space-5);
  align-items: start;
}

/* ---- section tab list -------------------------------------------------- */

.settings-nav {
  position: sticky;
  top: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.settings-nav-link {
  appearance: none;
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  text-align: left;
  font: inherit;
  font-size: var(--fs-small);
  color: var(--text-muted);
  cursor: pointer;
  transition: color var(--dur-fast) ease, background var(--dur-fast) ease;
}

.settings-nav-link:hover {
  color: var(--text);
  background: var(--surface-2);
}

.settings-nav-link[aria-selected="true"] {
  color: var(--text);
  background: var(--surface-2);
  box-shadow: inset 2px 0 0 var(--accent);
}

.settings-nav-link:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* ---- panel stack (only one is visible at a time) ----------------------- */

.settings-sections,
.settings-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-width: 0;
}

/* A non-selected tabpanel is taken out of the layout but kept in the
   accessibility tree, so the tablist's aria-controls target stays live. */
.settings-section[hidden] {
  display: none;
}

/* ---- one section -------------------------------------------------------- */

.settings-section {
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-md);
  padding: var(--space-5);
}

.settings-section-title {
  margin: 0;
  font-size: var(--fs-section);
  font-weight: var(--fw-semibold);
  color: var(--text);
}

.settings-section-sub {
  margin: var(--space-1) 0 0;
  font-size: var(--fs-label);
  line-height: 1.55;
  color: var(--text-muted);
}

.settings-section-body {
  margin-top: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* ---- account ----------------------------------------------------------- */

.account-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.settings-avatar {
  width: var(--space-7);
  height: var(--space-7);
  border-radius: 50%;
  background: var(--accent-tint);
  color: var(--text);
  display: grid;
  place-items: center;
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-label);
  flex: none;
}

.account-name {
  font-size: var(--fs-body);
  font-weight: var(--fw-semibold);
  color: var(--text);
  overflow-wrap: anywhere;
}

.account-sub {
  font-size: var(--fs-label);
  color: var(--text-muted);
}

.account-actions {
  margin-left: auto;
  display: flex;
  gap: var(--space-2);
}

.account-note {
  margin: 0;
  font-size: var(--fs-small);
  line-height: 1.55;
  color: var(--text-muted);
}

/* ---- Alpaca connection ------------------------------------------------- */

.conn-line {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.conn-text {
  font-size: var(--fs-small);
  font-weight: var(--fw-medium);
}

.conn-message {
  font-size: var(--fs-label);
  color: var(--text-muted);
}

.settings-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  gap: var(--space-3) var(--space-4);
}

.settings-secret-note {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  font-size: var(--fs-label);
  color: var(--text-muted);
}

.settings-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.settings-test {
  min-height: calc(var(--fs-label) * 1.5);
}

/* ---- display (the label/hint | control grid from Settings.dc) ---------- */

.display-rows {
  display: grid;
  grid-template-columns: 180px minmax(0, 1fr);
  column-gap: var(--space-5);
  row-gap: var(--space-4);
  align-items: center;
}

.display-row {
  display: contents;
}

.display-row-head {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.display-label {
  font-size: var(--fs-body);
  font-weight: var(--fw-regular);
  color: var(--text-muted);
}

.display-hint {
  font-size: var(--fs-label);
  color: var(--text-muted);
  line-height: 1.4;
}

.display-control {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.display-status {
  font-size: var(--fs-label);
  color: var(--pos);
  min-height: 1em;
}

.display-status:empty {
  /* No box while idle: the flex item still takes its own line under a
     nowrap Time zone control at 390px, so reserve no space until the
     "Saving…" / "Saved" / error text actually appears. */
  display: none;
}

.display-status-err {
  color: var(--neg);
}

/* §10.1 viewer rows: the server-wide display choices shown read-only with
   "Set by the owner" as the row hint. */
.display-readonly {
  font-size: var(--fs-small);
  color: var(--ink-2);
  padding: var(--space-1) 0;
}

.settings-control {
  /* The compact segmented control sizes itself to its content. */
  display: flex;
}

/* The public symbol limit's number field (owner decision 1 Nov 2026): a
   narrow field for two or three digits, next to its own Save button. */
.settings-control input[type="number"] {
  width: var(--space-9);
}

/* ---- data and refresh -------------------------------------------------- */

.data-copy {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.data-copy p {
  margin: 0;
  font-size: var(--fs-small);
  line-height: 1.55;
  color: var(--text-muted);
}

.data-copy strong {
  color: var(--text);
  font-weight: var(--fw-medium);
}

.settings-live {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr));
  gap: var(--space-3);
}

/* ---- ETF holdings (HOLDINGS_SPEC §22) ----------------------------------- */

.hldset-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.hldset-actions[hidden] {
  display: none;
}

.hldset-progress {
  min-height: 1em;
}

.hldset-subtitle {
  margin: 0;
  font-size: var(--fs-label);
  font-weight: var(--fw-semibold);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
}

.hldset-providers {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 230px), 1fr));
  gap: var(--space-2) var(--space-4);
}

.hldset-provider {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-size: var(--fs-small);
  min-width: 0;
}

.hldset-provider .dot {
  align-self: center;
  flex: none;
}

.hldset-provider-name {
  font-weight: var(--fw-semibold);
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hldset-provider-state {
  font-size: var(--fs-label);
  white-space: nowrap;
}

.hldset-provider-counts {
  margin-left: auto;
  white-space: nowrap;
}

.hldset-list {
  display: flex;
  flex-direction: column;
}

.hldset-etf {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  padding: var(--space-1) 0;
  border-bottom: 1px solid var(--panel-border);
  font-size: var(--fs-small);
  flex-wrap: wrap;
}

.hldset-etf:last-child {
  border-bottom: 0;
}

.hldset-etf-symbol {
  font-weight: var(--fw-semibold);
  color: var(--ink);
  min-width: 3.5em;
}

.hldset-etf-provider {
  min-width: 9em;
}

.hldset-etf-asof {
  color: var(--ink-2);
  white-space: nowrap;
}

.hldset-etf-fetched,
.hldset-etf-message {
  overflow-wrap: anywhere;
}

.hldset-etf-message {
  margin-left: auto;
  min-width: 0;
  flex-basis: 100%;
}

@media (min-width: 900px) {
  .hldset-etf-message {
    flex-basis: auto;
  }
}

/* ---- phones (below 768): the §3.6 mobile layout ---------------------------
   The section tablist is a horizontal scroll-x strip under the header
   (views/settings.js re-parents the same navEl into the region), the forms
   are one column with fill-mode controls, the Alpaca secret field carries
   its Show/Hide row, and Save / Test connection ride a sticky action bar
   that clears the keyboard and the bottom nav. At 768 and wider none of
   this applies and the layout is exactly today's. */

@media (max-width: 767.98px) {
  .settings-layout {
    grid-template-columns: minmax(0, 1fr);
  }

  /* One 44 px-tall row of single-line links that scrolls sideways inside
     the scroll-x region — the page itself never scrolls horizontally. */
  .settings-nav {
    position: static;
    flex-direction: row;
    flex-wrap: nowrap;
    width: max-content;
    min-width: 100%;
  }

  .settings-nav-link {
    white-space: nowrap;
  }

  /* The active tab reads as a strip tab: the accent moves to its baseline. */
  .settings-nav-link[aria-selected="true"] {
    box-shadow: inset 0 -2px 0 var(--accent);
  }

  .settings-section {
    padding: var(--space-4);
  }

  /* The label/control grid stacks: label + hint above, control below. */
  .display-rows {
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--space-3);
  }

  /* Fill mode: the control row is the full width, so the SegmentedControl
     fills it and its labels wrap inside their cells — "New York (exchange) |
     UTC | My local time" fits at 320 and the +33 px overflow is gone. */
  .settings-control {
    width: 100%;
  }

  /* The secret field's Show/Hide row: input grows, the toggle keeps its
     own width (a 44 px .btn). */
  .settings-secret-row {
    display: flex;
    gap: var(--space-2);
  }

  .settings-secret-row input {
    flex: 1 1 auto;
    min-width: 0;
  }

  .settings-secret-toggle {
    flex: none;
  }

  /* Save / Test connection: a sticky bar that rides above the keyboard
     (--keyboard-inset) and the bottom nav (--bottom-nav-space), buttons
     stacked full width. `order` paints it last on phones only, so nothing
     renders beneath the stuck bar; the DOM order (and the desktop) is
     untouched. */
  .settings-actions {
    order: 10;
    position: sticky;
    bottom: calc(var(--keyboard-inset) + var(--bottom-nav-space) + var(--space-2));
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-2) 0;
    background: var(--panel);
    border-top: 1px solid var(--panel-border);
  }

  .settings-actions .btn {
    width: 100%;
  }

  /* ETF Holdings: the refresh action is a full-width button with its live
     progress line beneath it. */
  .hldset-actions {
    flex-direction: column;
    align-items: stretch;
  }

  .hldset-actions .btn {
    width: 100%;
  }

  .hldset-etf {
    gap: var(--space-2);
  }

  .hldset-etf-fetched {
    display: none; /* the as-of date carries the essential timing on phones */
  }
}

@media (max-width: 1023.98px) {
  /* Preference controls include six default-page choices. Wrap them on
     phones and tablets while preserving the full desktop layout. */
  .settings-control .tabs {
    max-width: 100%;
    flex-wrap: wrap;
  }

  .settings-control .tab {
    flex: 1 1 5rem;
    white-space: normal;
  }
}

@media (max-width: 767.98px) {
  /* Keep the horizontal scrollbar below the section tabs' 44px targets. */
  .settings-layout > .scroll-x {
    padding-bottom: var(--space-2);
  }
}
