/* ============================================================================
   SB-391 — Sistema de diseño data-forward (capa reutilizable, canónica).

   Por qué este archivo existe como stylesheet separado y no al final de
   styles.css: el builder scripts/build_cycle_compass.py trunca styles.css en
   el marcador "Cycle Compass (SB-150" y reescribe todo lo que venga después.
   Cualquier CSS apendizado al final de styles.css (SB-384..SB-389) se perdía
   en cada rebuild del compass. Esta capa vive aparte y se carga con su propio
   <link> después de styles.css, así sobrevive a los rebuilds y centraliza el
   lenguaje visual compartido entre la home y las páginas metrics/*.

   Contiene los componentes del sistema SB-384 (kpi-grid, metric-card,
   sparkline, df-pill, category-nav, metric-strip) más las secciones de la home
   cuyo CSS había sido borrado por la regresión (Los 21M market-square,
   newsletter/premium, mapa editorial, estado producto, bitácora).

   Regla dura heredada de la visión: ningún sparkline/curva sin datos reales.
   El componente sparkline (assets/sparkline.js) no dibuja nada si la serie es
   insuficiente; aquí sólo se define su caja y color.
   ========================================================================== */

/* ---------- Sparkline (caja + trazo base) ---------- */
.sparkline { display:block; width:100%; height:34px; min-height:34px; }
.sparkline[data-spark-state="empty"] { height:0; min-height:0; }
.sparkline-svg { display:block; width:100%; height:100%; }
.sparkline-line { stroke: var(--accent); stroke-width:1.5; fill:none; }
.sparkline-dot { fill: var(--accent); }

/* ---------- df-pill (estado genérico reutilizable) ---------- */
.df-pill {
  display:inline-flex; align-items:center; gap:.3rem;
  font:600 .66rem/1 var(--font-mono); letter-spacing:.04em; text-transform:uppercase;
  padding:.2rem .42rem; border-radius:999px; border:1px solid var(--border);
  color: var(--muted); white-space:nowrap;
}
.df-pill[data-status="ok"]          { color: var(--accent-green); border-color: rgba(34,197,94,.45); background: rgba(34,197,94,.10); }
.df-pill[data-status="stale"]       { color: var(--yellow); border-color: rgba(234,179,8,.45); background: rgba(234,179,8,.10); }
.df-pill[data-status="unavailable"] { color: var(--dim); border-color: rgba(148,163,184,.30); background: rgba(148,163,184,.08); }
.df-pill[data-status="placeholder"] { color: var(--accent); border-color: rgba(247,147,26,.40); background: rgba(247,147,26,.08); }

/* ---------- KPI grid / KPI tile (estilo strategy.com/btc) ---------- */
.kpi-grid {
  display:grid; gap: var(--gap-tile);
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}
.kpi-tile {
  display:flex; flex-direction:column; gap:.45rem;
  padding:.85rem .9rem; border:1px solid var(--border);
  border-radius: var(--radius-tile); background: var(--card-bg);
  min-height: 132px;
}
.kpi-tile-head { display:flex; align-items:flex-start; justify-content:space-between; gap:.5rem; }
.kpi-label { margin:0; color: var(--muted); font-size:.72rem; font-weight:600; letter-spacing:.08em; text-transform:uppercase; }
.kpi-value { margin:0; font-size:1.55rem; font-weight:700; letter-spacing:-.03em; color: var(--text); line-height:1.1; word-break:break-word; }
.kpi-value small { font-size:.62em; color: var(--muted); font-weight:500; }
.kpi-foot { display:flex; flex-wrap:wrap; align-items:baseline; gap:.4rem .55rem; }
.kpi-sub { color: var(--muted); font-size:.72rem; }
.kpi-tile .tile-note { margin:.1rem 0 0; color: var(--dim); font-size:.66rem; line-height:1.3; }
.kpi-tile .sparkline { margin-top:auto; }
/* Convención BTC-first del trazo en el Hero (no aplica al resto): sube→naranja, baja→verde. */
.kpi-tile .sparkline[data-trend="up"]   .sparkline-line { stroke: var(--accent-orange); }
.kpi-tile .sparkline[data-trend="up"]   .sparkline-dot  { fill: var(--accent-orange); }
.kpi-tile .sparkline[data-trend="down"] .sparkline-line { stroke: var(--accent-green); }
.kpi-tile .sparkline[data-trend="down"] .sparkline-dot  { fill: var(--accent-green); }
.kpi-tile .sparkline[data-trend="flat"] .sparkline-line { stroke: var(--muted); }
.kpi-tile .sparkline[data-trend="flat"] .sparkline-dot  { fill: var(--muted); }

/* ---------- metric-card (estilo charts.bitcoin.com / bitcoinmagazinepro) ---------- */
.metric-card-grid {
  display:grid; gap:1rem;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.metric-card {
  display:flex; flex-direction:column; gap:.5rem;
  padding:.95rem 1rem; border:1px solid var(--border);
  border-radius: var(--radius-tile); background: var(--card-bg);
  color: var(--text); text-decoration:none;
  transition: border-color .15s ease, transform .15s ease, box-shadow .15s ease;
}
a.metric-card:hover { border-color: rgba(247,147,26,.45); transform: translateY(-2px); box-shadow: var(--shadow); color: var(--text); }
.metric-card[hidden] { display:none; }
.metric-card-head { display:flex; align-items:flex-start; justify-content:space-between; gap:.6rem; }
.metric-card-heading { display:flex; flex-direction:column; gap:.1rem; min-width:0; }
.metric-card-kicker { color: var(--accent); font-size:.64rem; font-weight:600; letter-spacing:.1em; text-transform:uppercase; }
.metric-card-title { margin:0; font-size:.96rem; font-weight:700; letter-spacing:-.01em; line-height:1.2; }
.metric-card-value { margin:.1rem 0 0; font-size:1.5rem; font-weight:700; letter-spacing:-.03em; color: var(--text); line-height:1.1; word-break:break-word; }
.metric-card-value small { font-size:.55em; color: var(--muted); font-weight:500; }
.metric-card .sparkline { height:38px; min-height:38px; }
.metric-card-caption { margin:0; color: var(--muted); font-size:.8rem; line-height:1.35; }
.metric-card-meta { color: var(--dim); font-size:.66rem; line-height:1.3; }
.metric-card-link { margin-top:auto; color: var(--accent); font-size:.76rem; font-weight:600; }
a.metric-card:hover .metric-card-link { text-decoration:underline; }
/* Trazo neutro para métricas que no son BTC/USD: no se afirma signo. */
.metric-card .sparkline .sparkline-line { stroke: var(--accent); }
.metric-card .sparkline .sparkline-dot  { fill: var(--accent); }

/* ---------- category-nav (barra de categorías de cards) ---------- */
.category-nav { display:flex; flex-wrap:wrap; gap:.45rem; margin:0 0 1rem; }
.category-nav-item {
  display:inline-flex; align-items:center; gap:.35rem;
  padding:.35rem .7rem; border:1px solid var(--border); border-radius:999px;
  background: var(--panel); color: var(--muted);
  font:600 .76rem var(--font-body); cursor:pointer; transition: all .15s ease;
}
.category-nav-item:hover { color: var(--text); border-color: var(--accent); }
.category-nav-item.is-active { color: var(--bg); background: var(--accent); border-color: var(--accent); }

/* ---------- metric-strip (grilla compacta label/valor, estilo S&P index) ---------- */
.metric-strip {
  display:grid; gap:.55rem;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
.metric-strip-item { display:flex; flex-direction:column; gap:.15rem; padding:.55rem .65rem; border:1px solid var(--border-soft); border-radius:10px; background: rgba(255,255,255,.02); }
.metric-strip-label { color: var(--muted); font-size:.66rem; font-weight:600; letter-spacing:.06em; text-transform:uppercase; }
.metric-strip-value { font:700 1.05rem/1.1 var(--font-mono); color: var(--text); }

/* ---------- Los 21M · cuadrado de mercado (treemap por stake) ---------- */
.supply-market-square { display:flex; flex-wrap:wrap; gap:4px; border-radius:12px; overflow:hidden; }
.supply-market-cell {
  flex: var(--share, 1) 1 0; min-width: 96px; min-height: 64px;
  display:flex; flex-direction:column; justify-content:flex-end; gap:.15rem;
  padding:.5rem .55rem; border-radius:8px;
  border:1px solid rgba(247,147,26,.30); background: var(--accent-soft);
  color: var(--text); overflow:hidden;
}
.supply-market-cell strong { font-size:.74rem; font-weight:700; line-height:1.15; }
.supply-market-cell span { font-size:.72rem; color: var(--muted); }
.supply-market-cell[data-status="immobile"] { border-color: var(--border); background: rgba(148,163,184,.08); }
.supply-market-cell[data-status="immobile"] strong { color: var(--muted); }
.supply-market-caption { display:flex; flex-wrap:wrap; gap:.4rem .7rem; align-items:baseline; margin-top:.6rem; color: var(--muted); font-size:.78rem; }
.supply-market-caption strong { color: var(--text); }

/* ---------- Newsletter / acceso premium ---------- */
.premium-access { display:grid; grid-template-columns: 1.1fr 1fr; gap:1.4rem; align-items:start; }
.premium-copy h2 { margin:.2rem 0 .5rem; font-size:1.45rem; letter-spacing:-.02em; }
.premium-copy p { margin:0; color: var(--muted); }
.premium-timeline { display:grid; gap:.6rem; margin-top:1rem; }
.access-step { display:grid; grid-template-columns: auto 1fr; gap:.1rem .8rem; align-items:baseline; padding:.55rem .75rem; border:1px solid var(--border-soft); border-radius:10px; background: rgba(255,255,255,.02); }
.access-step span { grid-row: span 2; color: var(--accent); font-size:.72rem; align-self:center; }
.access-step strong { font-size:.9rem; }
.access-step small { color: var(--muted); font-size:.76rem; grid-column:2; }
.access-step.is-full { border-color: rgba(34,197,94,.35); }
.access-step.is-advanced { border-color: rgba(56,189,248,.30); }
.premium-graphics { display:grid; gap:.8rem; }
.premium-pack { border:1px solid var(--border); border-radius:12px; padding:.8rem .9rem; background: var(--card-bg); }
.premium-pack header { display:flex; align-items:center; justify-content:space-between; gap:.5rem; margin-bottom:.5rem; }
.pack-cat { font-weight:700; font-size:.86rem; }
.pack-count { color: var(--accent); font:600 .68rem var(--font-mono); text-transform:uppercase; letter-spacing:.05em; }
.pack-signals { list-style:none; display:flex; flex-wrap:wrap; gap:.35rem; margin:0 0 .55rem; padding:0; }
.pack-signals li { font:500 .7rem var(--font-mono); padding:.2rem .45rem; border:1px solid var(--border-soft); border-radius:999px; color: var(--muted); }
.premium-pack p { margin:0; color: var(--muted); font-size:.78rem; line-height:1.35; }

/* ---------- Mapa editorial público ---------- */
.editorial-map-panel { padding:1.2rem; }
.editorial-map-grid { display:grid; gap:.8rem; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); margin-top:1rem; }
.editorial-map-card { display:flex; flex-direction:column; gap:.25rem; padding:.85rem .9rem; border:1px solid var(--border); border-radius:12px; background: var(--card-bg); color: var(--text); text-decoration:none; transition: border-color .15s ease, transform .15s ease; }
a.editorial-map-card:hover { border-color: var(--accent); transform: translateY(-2px); color: var(--text); }
.editorial-map-card span { color: var(--accent); font:600 .72rem var(--font-mono); }
.editorial-map-card strong { font-size:.95rem; }
.editorial-map-card small { color: var(--muted); font-size:.76rem; line-height:1.35; }
.editorial-map-card.is-sandbox { border-style:dashed; opacity:.85; }

/* ---------- Estado del producto ---------- */
.product-status-panel { padding:1.2rem; }
.product-status-grid { display:grid; gap:.8rem; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); margin:1rem 0; }
.product-status-grid > div { display:flex; flex-direction:column; gap:.25rem; padding:.75rem .85rem; border:1px solid var(--border-soft); border-radius:10px; background: rgba(255,255,255,.02); }
.product-status-grid strong { font-size:.9rem; }
.product-status-grid span { color: var(--muted); font-size:.78rem; line-height:1.35; }
.product-status-panel .disclosure { color: var(--dim); font-size:.78rem; font-style:italic; margin:.4rem 0 1rem; }
.product-status-actions { display:flex; flex-wrap:wrap; gap:.6rem .9rem; }

/* ---------- Bitácora (teaser editorial) ---------- */
.bitacora-grid { display:grid; gap:1rem; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.bitacora-card { display:flex; flex-direction:column; gap:.5rem; padding:.95rem 1rem; border:1px solid var(--border); border-radius: var(--radius-tile); background: var(--card-bg); }
.bitacora-card .chip-row { display:flex; flex-wrap:wrap; gap:.35rem; }
.bitacora-card .chip { font:600 .64rem var(--font-mono); text-transform:uppercase; letter-spacing:.04em; padding:.18rem .42rem; border:1px solid var(--border-soft); border-radius:999px; color: var(--accent); }
.bitacora-card h3 { margin:0; font-size:1rem; line-height:1.25; }
.bitacora-card p { margin:0; color: var(--muted); font-size:.82rem; line-height:1.4; }
.bitacora-card footer { margin-top:auto; display:flex; justify-content:space-between; gap:.5rem; color: var(--dim); font-size:.72rem; }
.bitacora-cta { display:flex; flex-wrap:wrap; align-items:center; gap:.7rem 1rem; margin-top:1rem; }
.bitacora-cta-primary { padding:.5rem .9rem; border-radius:999px; background: var(--accent); color: var(--bg); font-weight:600; font-size:.82rem; }
.bitacora-cta-secondary { padding:.5rem .9rem; border-radius:999px; border:1px solid var(--border); color: var(--text); font-size:.82rem; }
.bitacora-cta p { margin:0; color: var(--dim); font-size:.74rem; }

/* ---------- Reflow móvil ---------- */
@media (max-width: 880px) {
  .premium-access { grid-template-columns: 1fr; }
}
@media (max-width: 720px) {
  .kpi-grid { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
}
@media (max-width: 480px) {
  .kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .metric-card-grid { grid-template-columns: 1fr; }
  .kpi-value { font-size:1.3rem; }
  .metric-card-value { font-size:1.3rem; }
  .supply-market-cell { min-width: 100%; }
}

/* ============================================================================
   Los 21M · treemap dinámico (SB-247) — CSS RESTAURADO (SB-392).

   Por qué vive aquí: el board (#supply21m-board), las celdas (.treemap-cell)
   y el tooltip perdieron todo su CSS en la regresión SB-384..391 (el
   truncador de build_cycle_compass.py borraba el tail de styles.css). Sin
   estas reglas el board no tenía alto, supply-treemap.js::layout() abortaba
   con rect.height=0 y el board quedaba colgado en data-state="loading" en
   TODOS los viewports (desktop incluido). supply-treemap.js posiciona celdas
   absolutas dejando left/top/width/height + background-color inline; aquí se
   define el contexto de posicionamiento, el alto responsivo y la tipografía.
   Regla dura respetada: ninguna celda decorativa — cada celda sale del
   snapshot real data/supply-distribution-history.jsonl validado a 21M.
   ========================================================================== */
.supply21m-board {
  position: relative;
  width: 100%;
  height: clamp(360px, 46vw, 560px);
  margin: 1rem 0 0;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--card-bg);
  overflow: hidden;
}
.supply21m-board[data-state="loading"]::after,
.supply21m-board[data-state="error"]::after {
  content: attr(data-message);
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  padding: 1rem; text-align: center;
  color: var(--muted); font-size: .82rem; line-height: 1.4;
}
.supply21m-board[data-state="error"]::after { color: var(--yellow); }

.treemap-cell {
  position: absolute;
  box-sizing: border-box;
  overflow: hidden;
  border: 1px solid rgba(0,0,0,.28);
  border-radius: 4px;
  padding: .3rem .4rem;
  display: flex; flex-direction: column; justify-content: flex-end; gap: .1rem;
  font-family: var(--font-body);
  cursor: pointer;
  outline: 2px solid transparent; outline-offset: -2px;
  transition: filter .12s ease, outline-color .12s ease;
}
.treemap-cell:hover { filter: brightness(1.08); z-index: 2; }
.treemap-cell:focus-visible { outline-color: #fff; z-index: 3; }
.treemap-cell[data-is-meta="true"] {
  border-color: rgba(255,255,255,.14);
  background: transparent;
  pointer-events: none;
  border-radius: 6px;
  justify-content: flex-start;
}
.treemap-cell[data-no-label] { padding: 0; }
.cell-label {
  font-size: .72rem; font-weight: 600; line-height: 1.15;
  overflow: hidden; text-overflow: ellipsis;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.treemap-cell[data-is-meta="true"] > .cell-label {
  font-size: .62rem; text-transform: uppercase; letter-spacing: .05em;
  opacity: .8; -webkit-line-clamp: 1;
}
.cell-number {
  font: 600 .74rem/1 var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.treemap-cell[data-pattern="striped"] {
  background-image: repeating-linear-gradient(45deg, rgba(255,255,255,.06) 0 4px, transparent 4px 8px);
}
.treemap-cell[data-pattern="diagonal-subtle"] {
  background-image: repeating-linear-gradient(45deg, rgba(255,255,255,.05) 0 6px, transparent 6px 12px);
}
.treemap-cell[data-pattern="cross-hatch"] {
  background-image:
    repeating-linear-gradient(45deg, rgba(255,255,255,.05) 0 5px, transparent 5px 10px),
    repeating-linear-gradient(-45deg, rgba(255,255,255,.05) 0 5px, transparent 5px 10px);
}
.treemap-cell[data-pattern="dots"] {
  background-image: radial-gradient(rgba(255,255,255,.10) 1px, transparent 1.4px);
  background-size: 8px 8px;
}

/* Tooltip por celda */
.treemap-tooltip {
  position: absolute; z-index: 20;
  min-width: 180px; max-width: 260px;
  transform: translate(-50%, -100%);
  padding: .6rem .7rem;
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--panel); box-shadow: var(--shadow);
  color: var(--text); pointer-events: none; font-size: .76rem;
}
.treemap-tooltip[hidden] { display: none; }
.treemap-tooltip-title { font-weight: 700; font-size: .82rem; margin-bottom: .15rem; }
.treemap-tooltip-meta { color: var(--accent); font: 600 .62rem var(--font-mono); text-transform: uppercase; letter-spacing: .05em; margin-bottom: .35rem; }
.treemap-tooltip-row { display: flex; justify-content: space-between; gap: .8rem; padding: .12rem 0; }
.treemap-tooltip-label { color: var(--muted); }
.treemap-tooltip-value { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.treemap-tooltip-delta[data-dir="up"] .treemap-tooltip-value { color: var(--accent-orange); }
.treemap-tooltip-delta[data-dir="down"] .treemap-tooltip-value { color: var(--accent-green); }
.treemap-tooltip-unavailable { color: var(--dim); font-style: italic; }
.treemap-tooltip-source, .treemap-tooltip-ts { color: var(--dim); font-size: .68rem; margin-top: .3rem; line-height: 1.3; }
.treemap-tooltip-source a { color: var(--accent); }

/* Toolbar Los 21M (toggle 24h/30d + nota de colormap) */
.supply21m-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem 1rem; margin: 1.1rem 0 0; }
.supply21m-toggle { display: inline-flex; border: 1px solid var(--border); border-radius: 999px; overflow: hidden; }
.supply21m-toggle button {
  appearance: none; -webkit-appearance: none; border: 0; background: transparent;
  cursor: pointer; color: var(--muted); font: 600 .74rem var(--font-body); padding: .3rem .85rem;
}
.supply21m-toggle button.is-active { background: var(--accent); color: var(--bg); }
.supply21m-colormap-note { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem .5rem; margin: 0; color: var(--muted); font-size: .72rem; }
.supply21m-colormap-note .chip { font: 600 .62rem var(--font-mono); padding: .14rem .42rem; border: 1px solid var(--border-soft); border-radius: 999px; }
.supply21m-colormap-note[data-colormap-mode="inactive"] { opacity: .85; }
.supply21m-links { display: flex; flex-wrap: wrap; gap: .5rem 1rem; margin: .9rem 0 0; }
.supply21m-links a { color: var(--accent); font-size: .8rem; }

@media (max-width: 480px) {
  .supply21m-board { height: 380px; }
  .cell-label { font-size: .68rem; }
  .cell-number { font-size: .7rem; }
}
