/* Generated scenic assets — intentionally separated from the dashboard layout. */
.sidebar {
  background: #011a3b;
}

.dashboard-content {
  position: relative;
  z-index: 12;
  isolation: isolate;
  margin-top: -24px;
  background: transparent;
}

.dashboard-content::before {
  content: "";
  position: absolute;
  z-index: 0;
  inset: 24px 0 0;
  pointer-events: none;
  background:
    radial-gradient(circle at 15% 15%, rgba(214, 231, 248, .35), transparent 30%),
    #E8EEF9;
}

.dashboard-content > * {
  position: relative;
  z-index: 1;
}

.hero-coast {
  background-color: #cfe7ff;
  background-image: url("../img/hrzn-header-coast.png");
  background-repeat: no-repeat;
  background-size: 125% auto;
  background-position: right 90%;
  border-bottom: 0;
}

.hero-coast::before {
  content: "";
  position: absolute;
  z-index: 5;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(90deg, rgba(220, 239, 255, .4) 0%, rgba(229, 243, 255, .12) 46%, transparent 72%),
    linear-gradient(180deg, rgba(255, 255, 255, .08), transparent 65%);
}

.hero-coast::after {
  content: "";
  display: block;
  position: absolute;
  z-index: 6;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 34px;
  pointer-events: none;
  background: linear-gradient(180deg,
    rgba(232, 238, 249, 0) 0%,
    rgba(232, 238, 249, .08) 35%,
    rgba(232, 238, 249, .52) 75%,
    #E8EEF9 100%);
}

.hero-cloud,
.bird,
.sunset,
.coast-water,
.mountains {
  display: none;
}

.lighthouse-scene {
  height: 220px;
  bottom: 225px;
  background-color: #011a3b;
  background-image:
    linear-gradient(180deg,
      rgba(1, 26, 59, .5) 0%,
      rgba(1, 26, 59, .08) 22%,
      transparent 52%,
      rgba(1, 26, 59, .22) 70%,
      #011a3b 100%),
    url("../img/hrzn-sidebar-lighthouse.png");
  background-repeat: no-repeat;
  background-size: 100% 100%, cover;
  background-position: center, center 66%;
}

.lighthouse-scene::after {
  content: "";
  display: block;
  position: absolute;
  z-index: 8;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 82px;
  pointer-events: none;
  background: linear-gradient(180deg,
    rgba(1, 26, 59, 0) 0%,
    rgba(1, 26, 59, .46) 45%,
    #011a3b 100%);
  clip-path: none;
}

.lighthouse-scene .topo,
.lighthouse-scene .beam,
.lighthouse-scene .island,
.lighthouse-scene .lighthouse {
  display: none;
}

@media (max-width: 1180px) {
  .hero-coast {
    background-size: 130% auto;
    background-position: right 90%;
  }
}

@media (max-width: 880px) {
  .dashboard-content {
    margin-top: -14px;
  }

  .dashboard-content::before {
    inset: 14px 0 0;
  }

  .hero-coast {
    background-size: 145% auto;
    background-position: right 89%;
  }
}

@media (max-width: 580px) {
  .hero-coast {
    background-size: auto 112%;
    background-position: 72% 88%;
  }

  .hero-coast::after {
    height: 28px;
  }
}

/* ============================================================
   LIVE RISK RADAR — a real scope: range rings, rotating sweep,
   and blips that flash as the sweep passes over them.
   ============================================================ */
.radar-live{display:inline-flex;align-items:center;gap:7px;padding:5px 11px;border-radius:999px;background:rgba(9,106,240,.08);color:#0a56c8;font-size:10px;font-weight:800;letter-spacing:.16em}
.radar-live i{width:6px;height:6px;border-radius:50%;background:#0a72ff;animation:radarLive 1.8s ease-in-out infinite}
@keyframes radarLive{0%,100%{box-shadow:0 0 0 0 rgba(10,114,255,.5)}70%{box-shadow:0 0 0 7px rgba(10,114,255,0)}}

.radar-scope{
  position:relative;width:100%;max-width:238px;aspect-ratio:1;margin:4px auto 18px;
  border-radius:50%;overflow:hidden;
  background:radial-gradient(circle at 50% 50%,#0d3266 0%,#08284f 55%,#061f45 100%);
  box-shadow:inset 0 0 34px rgba(2,12,30,.55),0 12px 30px rgba(8,45,93,.20);
  border:1px solid #0a2a55;
}
/* range rings + cardinal cross */
.radar-grid-lines{position:absolute;inset:0;border-radius:50%;
  background:
    repeating-radial-gradient(circle,transparent 0 27px,rgba(90,160,255,.20) 27px 28px),
    linear-gradient(to right,transparent calc(50% - .5px),rgba(90,160,255,.16) calc(50% - .5px) calc(50% + .5px),transparent calc(50% + .5px)),
    linear-gradient(to bottom,transparent calc(50% - .5px),rgba(90,160,255,.16) calc(50% - .5px) calc(50% + .5px),transparent calc(50% + .5px));
}
/* rotating sweep with a fading tail */
.radar-sweep{position:absolute;inset:0;border-radius:50%;
  background:conic-gradient(from 0deg,rgba(43,139,255,.55) 0deg,rgba(43,139,255,.16) 26deg,rgba(43,139,255,0) 78deg,rgba(43,139,255,0) 360deg);
  animation:radarSweep 4s linear infinite;transform-origin:50% 50%}
.radar-sweep::after{content:"";position:absolute;left:50%;top:0;bottom:50%;width:1.5px;
  background:linear-gradient(180deg,rgba(150,205,255,0),rgba(150,205,255,.95));transform:translateX(-50%)}
@keyframes radarSweep{to{transform:rotate(360deg)}}

/* contacts */
.radar-blip{position:absolute;left:var(--x);top:var(--y);width:9px;height:9px;margin:-4.5px 0 0 -4.5px;border-radius:50%;
  opacity:.18;animation:radarBlip 4s linear infinite;animation-delay:var(--delay)}
.radar-blip.crit{background:#ff5a4d;box-shadow:0 0 0 0 rgba(255,90,77,.7)}
.radar-blip.warn{background:#ffb547;box-shadow:0 0 0 0 rgba(255,181,71,.7)}
.radar-blip.low{background:#7fd8ff;width:7px;height:7px;margin:-3.5px 0 0 -3.5px}
@keyframes radarBlip{
  0%{opacity:1;transform:scale(1.45)}
  8%{opacity:.95;transform:scale(1)}
  55%{opacity:.30}
  100%{opacity:.16}
}
.radar-core{position:absolute;left:50%;top:50%;width:8px;height:8px;margin:-4px 0 0 -4px;border-radius:50%;
  background:#eaf4ff;box-shadow:0 0 12px 3px rgba(150,205,255,.65)}
.radar-range{position:absolute;left:0;right:0;bottom:12px;text-align:center;
  font-size:8.5px;font-weight:700;letter-spacing:.2em;color:rgba(170,208,255,.75)}

@media (prefers-reduced-motion:reduce){
  .radar-sweep{animation:none;opacity:.35}
  .radar-blip{animation:none;opacity:.85}
  .radar-live i{animation:none}
}

/* new transaction landing in the spend feed */
.spend-feed{transition:border-color .25s var(--ease),box-shadow .25s var(--ease),background .25s var(--ease)}
.spend-feed.is-new{border-color:#8fc0ff;background:rgba(234,244,255,.95);box-shadow:0 6px 20px rgba(10,114,255,.16)}
.spend-feed.is-new strong{animation:feedPop .7s var(--ease)}
@keyframes feedPop{0%{transform:translateY(-6px);opacity:0}40%{transform:translateY(0);opacity:1}}
.spend-feed .feed-icon{transition:transform .3s var(--ease)}
.spend-feed.is-new .feed-icon{transform:scale(1.18)}
@media (prefers-reduced-motion:reduce){.spend-feed.is-new strong{animation:none}.spend-feed.is-new .feed-icon{transform:none}}

/* ============================================================
   LIVE COAST — the hero landscape as a looping video. The PNG
   stays as poster + CSS fallback, so nothing breaks if the
   video is blocked, still loading, or motion is reduced.
   object-position keeps the horizon inside the short band.
   ============================================================ */
.hero-video{
  position:absolute;inset:0;z-index:0;
  width:100%;height:100%;
  object-fit:cover;object-position:50% 84%;
  pointer-events:none;border:0;
}
@media (prefers-reduced-motion:reduce){ .hero-video{display:none} }

/* ============================================================
   OPERATIONAL POLISH — calm micro-interactions. Everything here
   is a slow, low-contrast cue: the desk should feel attentive,
   never busy. No glow, no neon, no HUD.
   ============================================================ */

/* a value that just re-read itself */
.metric-value.is-updating,
.projection-value.is-updating{ animation: valueSettle .9s var(--ease); }
@keyframes valueSettle{
  0%  { color:#0a72ff; transform:translateY(-1px) }
  60% { color:#0a72ff }
  100%{ color:inherit; transform:none }
}

/* cards lift a hair on hover — acknowledgement, not decoration */
.metric-card,
.panel{ transition: box-shadow .28s var(--ease), transform .28s var(--ease), border-color .28s var(--ease); }
.metric-card:hover,
.panel:hover{ transform:translateY(-2px); box-shadow:0 14px 34px rgba(23,66,119,.10); }

/* sparklines breathe in when their card is hovered */
.sparkline{ transition: opacity .3s var(--ease); opacity:.92 }
.metric-card:hover .sparkline{ opacity:1 }

/* budget pressure animates to its new level instead of jumping */
.pressure-bar i{ transition: width .8s var(--ease) }

/* buttons: a real press, no bounce */
.review-button, .waste-button, .side-link, .period-button, .profile-card, .support-link{
  transition: background .18s var(--ease), color .18s var(--ease), transform .12s var(--ease), border-color .18s var(--ease);
}
.review-button:active, .waste-button:active{ transform:scale(.985) }

/* radar contacts respond to the panel */
.radar-panel:hover .radar-sweep{ animation-duration:3s }
.radar-scope{ transition: box-shadow .3s var(--ease) }
.radar-panel:hover .radar-scope{ box-shadow:inset 0 0 34px rgba(2,12,30,.55),0 16px 38px rgba(8,45,93,.26) }

/* the "left this month" figure settles when the budget is re-cut */
.hero-copy h1{ transition: color .3s var(--ease) }

@media (prefers-reduced-motion:reduce){
  .metric-value.is-updating,.projection-value.is-updating{ animation:none }
  .metric-card:hover,.panel:hover{ transform:none }
  .pressure-bar i{ transition:none }
}

/* ---------- los puntos de estado laten -------------------------------
   Un punto de color dice "asi esta esto AHORA". Si no se mueve no se
   distingue de una vineta decorativa: late para que se lea como una
   lectura viva y no como un adorno impreso.

   El latido es scale + opacity sobre el punto mismo, no un anillo que
   crece. Dos razones: es agnostico al color, asi que sirve igual para
   verde, ambar, rojo y azul sin nombrar el tono en el keyframe; y
   aguanta ocho puntos en pantalla sin volverse ruido. El anillo se lo
   dejamos al indicador "Live", que ya lo tenia y tiene que seguir
   siendo el mas fuerte de la pantalla.

   Las duraciones son distintas por familia a proposito: si todos
   latieran a 2.1s marcharian en bloque y parecerian una sola cosa.

   Quedan afuera los puntos que NO son estado sino leyenda o grafico:
   .adoption-people (12 puntos de distribucion), .adoption-band-actions
   y .score-reliability-key. Y los que ya latian, que conservan su
   animacion porque sus hojas cargan despues de esta.
   -------------------------------------------------------------------- */
@keyframes hz-state-beat {
  0%, 100% { transform: scale(1); opacity: 1; }
  50%      { transform: scale(.72); opacity: .5; }
}

@media (prefers-reduced-motion: no-preference) {
  /* franja de estado, veredicto y senales del hero */
  .hz-strip i                          { animation: hz-state-beat 2.4s ease-in-out infinite; }
  .hz-verdict::before                  { animation: hz-state-beat 2.2s ease-in-out infinite; }
  .hz-hero-signals i                   { animation: hz-state-beat 2.6s ease-in-out infinite; }

  /* el punto de estado del sistema, y la insignia */
  .hz-state::before                    { animation: hz-state-beat 2.1s ease-in-out infinite; }
  .hz-badge i                          { animation: hz-state-beat 2.7s ease-in-out infinite; }

  /* AI Adoption */
  .adoption-hero__signals i            { animation: hz-state-beat 2.5s ease-in-out infinite; }
  .adoption-live-feed__source i        { animation: hz-state-beat 1.9s ease-in-out infinite; }
  .adoption-live-feed__state span i    { animation: hz-state-beat 2.3s ease-in-out infinite; }
  .adoption-kpi header span i          { animation: hz-state-beat 2.1s ease-in-out infinite; }
  .adoption-briefing__states span i    { animation: hz-state-beat 2.6s ease-in-out infinite; }
  .adoption-team-card header > span i  { animation: hz-state-beat 2.4s ease-in-out infinite; }
  .adoption-progress > header > span i { animation: hz-state-beat 2.2s ease-in-out infinite; }

  /* AI Score */
  .score-hero__signals i               { animation: hz-state-beat 2.5s ease-in-out infinite; }
  .score-live em                       { animation: hz-state-beat 2.0s ease-in-out infinite; }
  .score-status i                      { animation: hz-state-beat 2.3s ease-in-out infinite; }
  .score-subject__button header em i   { animation: hz-state-beat 2.6s ease-in-out infinite; }
  .score-breakdown__score > span i     { animation: hz-state-beat 2.2s ease-in-out infinite; }
  .score-component-detail header span i { animation: hz-state-beat 2.4s ease-in-out infinite; }
  .score-live-rail__source i           { animation: hz-state-beat 1.9s ease-in-out infinite; }
  .score-live-rail__meta span i        { animation: hz-state-beat 2.5s ease-in-out infinite; }
  .score-live-detection__mode i        { animation: hz-state-beat 2.1s ease-in-out infinite; }
  .score-executive-brief__states span i { animation: hz-state-beat 2.7s ease-in-out infinite; }
  .score-provisional-chip i            { animation: hz-state-beat 2.3s ease-in-out infinite; }
  .score-table-tools > button i        { animation: hz-state-beat 2.0s ease-in-out infinite; }

  /* AI Score Settings */
  .score-config-access span i          { animation: hz-state-beat 2.4s ease-in-out infinite; }
}

/* ---------- el latido es de "en vivo", no de "estado" ----------------
   El bloque de arriba lo dice el mismo: "agnostico al color, sirve para
   verde, ambar, rojo y azul". Ese era el problema -- un punto en pausa,
   desconectado o en alerta tambien latia, y un latido significa "esto
   esta pasando ahora": en amarillo o rojo lee como una alarma activa, no
   como una pausa.

   El latido queda solo para el estado bueno/en vivo (el que no lleva
   modificador, o el .is-ok explicito). Las variantes que SI llevan
   modificador -- is-warn, is-bad, is-idle, is-unknown, is-course, y los
   dos puntos que son de un solo color por diseno (el chip "Provisional"
   siempre ambar, el boton "Reconnect" siempre rojo) -- se paran. */
@media (prefers-reduced-motion: no-preference) {
  .hz-strip.is-warn i,
  .hz-strip.is-bad i,
  .hz-verdict.is-warn::before,
  .hz-verdict.is-bad::before,
  .hz-state.is-warn::before,
  .hz-state.is-bad::before,
  .hz-state.is-idle::before,
  .hz-badge:not(.is-ok) i,
  .adoption-kpi header span.is-watch i,
  .adoption-kpi header span.is-course i,
  .adoption-briefing__states span.is-watch i,
  .adoption-live-feed__state span.is-watch i,
  .adoption-live-feed__state span.is-bad i,
  .score-status.is-watch i,
  .score-status.is-bad i,
  .score-status.is-unknown i,
  .score-live-rail__meta span.is-watch i,
  .score-live-rail__meta span.is-bad i,
  .score-breakdown__score > span.is-watch i,
  .score-breakdown__score > span.is-bad i,
  .score-breakdown__score > span.is-unknown i,
  .score-executive-brief__states span.is-watch i,
  .score-provisional-chip i,
  .score-table-tools > button i {
    animation: none !important;
  }
}

/* ---------- fuera la barra de progreso de los feeds ------------------
   Una linea de 3px con el degrade azul -> naranja que crecia de 0 a
   100% en loop, al pie del feed en vivo. Estaba en dos lugares con dos
   nombres distintos:

     .adoption-live-feed::after   5.6s  (AI Adoption)
     .score-live-rail::after      5.2s  (AI Score)

   Se saca: el movimiento no informaba nada — no medía ningún progreso
   real, solo daba vueltas — y le robaba atencion a los puntos de
   estado, que si dicen algo.

   Se apaga con display:none en vez de borrar las reglas del diseñador,
   asi la proxima entrega se sigue diffeando limpio.
   -------------------------------------------------------------------- */
.adoption-live-feed::after,
.score-live-rail::after { display: none; }
