/* ============================================================
   utilities.css — color/text helpers, scrollbar, responsive overrides (loaded last)
   ============================================================ */

/* ─── Color Utilities ─────────────────────────────────── */
.text-green { color: var(--accent-green) !important; }
.text-red { color: var(--accent-red) !important; }
.text-blue { color: var(--accent-blue) !important; }
.text-orange { color: var(--accent-orange) !important; }
.text-purple { color: var(--accent-purple) !important; }
.text-muted { color: var(--text-muted) !important; }
.text-secondary { color: var(--text-secondary) !important; }
/* DM Sans/DM Mono ship 300–500 only — 600/700 would be synthesized
   (faux-bold smears). 500 is the real top weight, and reads sharper. */
.fw-600 { font-weight: 500; }
.fw-700 { font-weight: 500; }
.text-right { text-align: right; }
.text-sm { font-size: 0.8125rem; }
.text-xs { font-size: 0.8125rem; }
.mono { font-family: 'SF Mono', 'Fira Code', ui-monospace, monospace; }


/* ─── Divider ─────────────────────────────────────────── */
.divider { border: none; border-top: 1px solid var(--border); margin: 20px 0; }
.section { margin-bottom: 22px; }


/* ─── Scrollbar ───────────────────────────────────────── */
::-webkit-scrollbar { width: 5px; height: 5px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(243,240,233,0.14); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: rgba(243,240,233,0.26); }


/* ═══════════════════════════════════════════════════════════════
   NUMBERS → clean sans (DM Sans) instead of the serif display font.
   Cormorant's old-style figures read poorly for money; DM Sans gives
   uniform, tabular, legible figures. Titles (.page-title) + logo stay serif.
   ═══════════════════════════════════════════════════════════════ */
.metric-value, .stat-value, .hs-score-num, .hs-score-val,
.val-sum-price, .val-sum-upside, .val-meth-val, .val-cmp-num,
.val-fin-val, .val-fin-val--total, .val-final-upside, .val-rev-val {
  font-family: var(--font-ui) !important;
  font-variant-numeric: lining-nums tabular-nums;
  letter-spacing: 0 !important;
}

/* ─── Helpers extracted from inline styles ────────────── */
/* utilities.css loads last, so these reproduce the former inline
   declarations exactly (same value, winning by source order). */
.uppercase       { text-transform: uppercase; }
.overflow-hidden { overflow: hidden; }
.resize-v        { resize: vertical; }
.cal-event-sm    { font-size: 0.8125rem; padding: 1px 5px; } /* small calendar-legend chip */


/* ═══════════════════════════════════════════════════════════════
   RESPONSIVE — the app must feel designed at every width,
   not merely scaled down.
   ═══════════════════════════════════════════════════════════════ */

@media (max-width: 1280px) {
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 1024px) {
  .grid-3 { grid-template-columns: repeat(2, 1fr); }
  .grid-3-2 { grid-template-columns: 1fr; }
  .grid-2-1 { grid-template-columns: 1fr; }
}

/* ─── Mobile: the sidebar becomes a sticky glass top bar ───
   Logo left, nav scrolls horizontally, currency pinned right.
   Everything stays one thumb-reach away. */
@media (max-width: 768px) {
  html, body { overflow-x: clip; }   /* phones: vertical scrolling only */
  body { flex-direction: column; }

  /* iOS Safari auto-zooms into any field whose font-size is < 16px on focus —
     and never zooms back out, so searching for a stock left the page stuck
     zoomed in. 16px is the exact threshold that suppresses it, WITHOUT
     disabling pinch-zoom (accessibility). Applies to every text control. */
  input, select, textarea,
  .form-input, .form-select, .form-textarea, .search-input, .val-search-input {
    font-size: 16px;
  }

  .sidebar {
    width: 100%;
    height: auto;
    flex-direction: row;
    align-items: center;
    gap: 2px;
    padding: 10px 14px;
    overflow-x: auto;
    overflow-y: hidden;
    border-right: none;
    border-bottom: 1px solid var(--border-subtle);
    background: rgba(7,7,7,0.88);
    -webkit-backdrop-filter: blur(16px);
    backdrop-filter: blur(16px);
    scrollbar-width: none;
  }
  .sidebar::-webkit-scrollbar { display: none; }

  .logo { margin: 0 12px 0 0; flex-shrink: 0; }
  .logo-text { font-size: 18px; }
  .logo-sub { display: none; }
  .logo::after { display: none; }

  /* flatten the three nav sections into one row of items */
  .nav-section { display: contents; }
  .nav-section-label { display: none; }
  .nav-item {
    padding: 9px 11px;
    margin-bottom: 0;
    white-space: nowrap;
    flex-shrink: 0;
    font-size: 0.8125rem;
    border-left: none;
    border-bottom: 1px solid transparent;
  }
  .nav-item.active {
    border-left: none;
    border-bottom: 1px solid var(--accent);
    background: none;
  }

  .sidebar-footer {
    margin: 0 0 0 auto;
    padding: 0 0 0 12px;
    border-top: none;
    display: flex;
    align-items: center;
    flex-shrink: 0;
    animation: none;
  }
  .currency-switcher { display: flex; gap: 4px; margin-bottom: 0; }
  .curr-btn { flex-direction: row; gap: 4px; padding: 5px 8px; }
  .curr-code { display: none; }
  .live-status { display: none; }

  .main-content { min-height: 0; }

  .page-header { padding: 16px 16px 14px; }
  .page-title { font-size: 24px; }
  .page-content { padding: 16px 14px 28px; }

  .grid-2 { grid-template-columns: 1fr; }

  tbody td, thead th { padding: 10px 10px; }

  /* Scroll affordance for sideways-scrolling surfaces (tables + the nav bar):
     a faint warm glow marks each edge that still has content beyond it, and a
     background-attachment:local "cover" slides over the glow when that edge is
     reached — pure CSS scroll shadows, no JS. */
  .table-container {
    background:
      linear-gradient(90deg,  var(--bg-surface) 45%, rgba(18,18,17,0)) left  / 36px 100% no-repeat local,
      linear-gradient(270deg, var(--bg-surface) 45%, rgba(18,18,17,0)) right / 36px 100% no-repeat local,
      linear-gradient(90deg,  rgba(200,169,126,0.16), rgba(200,169,126,0)) left  / 16px 100% no-repeat scroll,
      linear-gradient(270deg, rgba(200,169,126,0.16), rgba(200,169,126,0)) right / 16px 100% no-repeat scroll,
      var(--bg-surface);
  }
  .sidebar {
    background:
      linear-gradient(90deg,  rgba(7,7,7,0.92) 45%, rgba(7,7,7,0)) left  / 32px 100% no-repeat local,
      linear-gradient(270deg, rgba(7,7,7,0.92) 45%, rgba(7,7,7,0)) right / 32px 100% no-repeat local,
      linear-gradient(90deg,  rgba(200,169,126,0.20), rgba(200,169,126,0)) left  / 14px 100% no-repeat scroll,
      linear-gradient(270deg, rgba(200,169,126,0.20), rgba(200,169,126,0)) right / 14px 100% no-repeat scroll,
      rgba(7,7,7,0.88);
  }

  .modal { padding: 24px 18px 20px; width: 100%; margin: 0 10px; }
  .modal-title { font-size: 22px; }

  #toast { left: 16px; right: 16px; bottom: 16px; max-width: none; }
}

/* ─── Valuation: the weighted-fair-value equation becomes a ledger ───
   On desktop it reads as one inline sum (DCF + Relative + Historical = total);
   below ~640px that row wraps mid-equation with stranded +/= glyphs. Stack it
   as ledger rows instead: method · value · weight · contribution, with the
   total ruled off underneath like a column sum. */
@media (max-width: 640px) {
  .val-final-body { flex-direction: column; align-items: stretch; gap: 16px; }
  .val-final-sum  { display: block; }
  .val-fin-op     { display: none; }     /* the inline equation's + / = glyphs */
  .val-fin-item {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    align-items: baseline;
    column-gap: 12px;
    padding: 12px 0;
    background: transparent;
    border: none;
    border-radius: 0;
    border-bottom: 1px solid var(--border-subtle);
  }
  .val-fin-val     { font-size: 20px; margin: 0; }
  .val-fin-sub     { justify-content: flex-end; }
  .val-fin-contrib { min-width: 66px; text-align: right; font-size: 15px; }
  .val-fin-item--total {
    grid-template-columns: minmax(0, 1fr) auto;
    border-bottom: none;
    border-top: 1px solid var(--border);
    padding-top: 14px;
    min-width: 0;
  }
  .val-fin-val--total { font-size: 32px; }
  .val-final-signal-box { width: 100%; }
}

@media (max-width: 560px) {
  .grid-3, .grid-4 { grid-template-columns: 1fr; }
  /* Vertical-only scrolling: the recurring killer is min-content — a grid or
     flex row whose children refuse to shrink props its card past the viewport
     and the page would pan. Let every such container shrink, and stack the
     ones whose content genuinely cannot fit three-across on a phone. */
  .card-title { flex-wrap: wrap; row-gap: 10px; }
  .tabs { flex-wrap: wrap; gap: 12px; }
  .header-actions { flex-wrap: wrap; }
  .set-grid > *, .an-conc-stats > *, .curr-picker > * { min-width: 0; }
  .curr-picker { grid-template-columns: 1fr; min-width: 0; }
  .an-conc-stats { grid-template-columns: 1fr; }
  .pf-new-row { flex-wrap: wrap; }
  /* Valuation hero: stack price → fair value vertically; a 50px figure with a
     long native-currency string (₩1,390,000) cannot fit a 380px viewport. */
  .val-hero-flow { flex-direction: column; align-items: stretch; gap: 14px; }
  .val-flow-op { display: none; }
  .val-flow-v .stat-value { font-size: 30px; }
  .val-flow-stat--fv .val-flow-v .stat-value { font-size: 36px; }
  .val-hero-upside { font-size: 32px; }
  .val-meth-val { font-size: 22px; }
  .form-row, .form-row-3 { grid-template-columns: 1fr; }
  /* A date needs far less than a phone's full width; a full-bleed field for
     "21.07.2026" reads as oversized and empty beside the numeric inputs. Cap
     every date control (buy, sell, calendar event) so each sits as a compact,
     deliberate control, left-aligned in its group. */
  #txn-date, #sell-date, #ev-date { max-width: 200px; }
  .header-actions { width: 100%; }
  .header-actions .btn { flex: 1; }
  .filter-row .search-input { width: 100%; flex: 1 1 100%; }
  .dist-label { width: 180px; }   /* fit "Communication Services" (~177px) without clipping */
  .dist-val { display: none; }
}

/* ═══════════════════════════════════════════════════════════════
   LAPTOP READABILITY — every "smallest text" size above is declared
   in rem against this root. Phones keep the tuned 13px floor
   (root 16px); laptops and desktops raise the floor to ~14.2px so
   labels, table detail and captions read comfortably on a 13-inch
   screen. One knob, no per-selector overrides.
   ═══════════════════════════════════════════════════════════════ */
html { font-size: 16px; }
@media (min-width: 769px) { html { font-size: 17.5px; } }
