/* Capa de pantalla — los estilos que en los prototipos iban en `style="..."`.
   Todos los valores salen de los tokens de industry.css: aqui no hay ni un
   hex ni una fuente escritos a mano. */

:root {
  --shell-max: 1080px;
  --sidebar-w: 236px;
}

html,
body {
  height: 100%;
}

/* ── tipos y piezas compartidas ────────────────────────────────────────── */

.kicker {
  margin: 0 0 2px;
  color: var(--color-accent-700);
}

.page-title {
  margin: 0;
  font-size: 38px;
}

.muted-12 {
  font-size: 12px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

.stack {
  display: flex;
  flex-direction: column;
}

.tabular {
  font-variant-numeric: tabular-nums;
}

.cell-right {
  text-align: right;
}

/* Marco blueprint. El componente <Blueprint> pinta las cuatro marcas. */
.panel {
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.panel-table {
  padding: 14px 16px;
}

.panel-tight {
  padding: var(--space-4);
}

.panel-prose {
  padding: var(--space-8);
}

.panel-head {
  display: flex;
  align-items: center;
  gap: 12px;
}

.panel-head > h4 {
  margin: 0;
}

.push {
  margin-left: auto;
}

/* Filas y tarjetas que navegan. Son <a>/<button> reales, no <tr onclick>. */
.row-link {
  cursor: pointer;
}

.table tbody tr.row-link:focus-within {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}

/* El enlace cubre la fila entera para que el area de click sea la celda. */
.cell-link {
  color: inherit;
  text-decoration: none;
  display: block;
}

.cell-link:focus-visible {
  outline: none;
}

.field-error {
  margin-top: 4px;
  font-size: 11px;
  color: var(--color-accent-800);
}

.input:user-invalid,
.input[aria-invalid="true"] {
  border-color: var(--color-accent-800);
}

/* ── figuras ──────────────────────────────────────────────────────────── */

.figure {
  position: relative;
}

.figcap {
  font-size: 11px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

/* ── CMS: armazon ─────────────────────────────────────────────────────── */

.cms-shell {
  display: flex;
  min-height: 100vh;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
}

.cms-sidebar {
  width: var(--sidebar-w);
  flex: none;
  border-right: 1px solid var(--color-divider);
  padding: 20px 16px;
  display: flex;
  flex-direction: column;
  gap: 24px;
  position: sticky;
  top: 0;
  height: 100vh;
}

.cms-brand {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 20px;
  line-height: 1;
}

.cms-brand-label {
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 50%, transparent);
  margin-top: 4px;
}

.cms-nav {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.sb-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  padding: 7px 10px;
  border: 1px solid transparent;
  background: transparent;
  cursor: pointer;
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 15px;
  letter-spacing: 0.01em;
  color: var(--color-text);
  text-align: left;
  text-decoration: none;
}

.sb-item:hover {
  background: color-mix(in srgb, var(--color-text) 6%, transparent);
}

.sb-item[aria-current="page"] {
  border-color: var(--color-divider);
  color: var(--color-accent-700);
  background: color-mix(in srgb, var(--color-accent) 10%, transparent);
}

.sb-count {
  font-family: var(--font-body);
  font-size: 11px;
  opacity: 0.55;
}

.cms-foot {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.cms-chip {
  padding: 10px;
  display: flex;
  gap: 10px;
  align-items: center;
}

.cms-monogram {
  width: 36px;
  height: 36px;
  flex: none;
  border: 1px solid var(--color-divider);
  display: grid;
  place-items: center;
  overflow: hidden;
  background: color-mix(in srgb, var(--color-accent) 12%, transparent);
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 14px;
  color: var(--color-accent-800);
}

.cms-chip-name {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 14px;
  line-height: 1.15;
}

.cms-chip-role {
  font-size: 11px;
  color: color-mix(in srgb, var(--color-text) 50%, transparent);
}

.cms-foot .btn-block {
  margin-top: 0;
}

.cms-saved {
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 40%, transparent);
}

.cms-main {
  flex: 1;
  min-width: 0;
  padding: 28px 34px 60px;
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.view {
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.page-head {
  display: flex;
  align-items: flex-end;
  gap: 16px;
}

.page-head-actions {
  margin-left: auto;
  display: flex;
  gap: 8px;
  align-items: center;
}

.back-btn {
  align-self: flex-start;
  margin-bottom: 8px;
}

/* ── CMS: detalle de app ──────────────────────────────────────────────── */

.grid-details {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: 20px;
  align-items: start;
}

.grid-docs {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
  gap: 20px;
  align-items: start;
}

.col {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}

.grid-title-kind {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 14px;
}

.radio-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.doc-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.doc-card {
  gap: 6px;
  text-align: left;
  font: inherit;
  color: inherit;
  text-decoration: none;
  cursor: pointer;
}

.doc-card[aria-current="true"] {
  background: color-mix(in srgb, var(--color-accent) 9%, transparent);
}

.doc-card:hover {
  background: color-mix(in srgb, var(--color-accent) 5%, transparent);
}

.body-input {
  min-height: 320px;
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 12.5px;
  line-height: 1.6;
}

.desc-input {
  min-height: 140px;
}

.bio-input {
  min-height: 170px;
}

.save-row {
  display: flex;
  align-items: center;
  gap: 12px;
}

.save-note {
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 45%, transparent);
}

.empty-state {
  padding: var(--space-6);
  min-height: 260px;
  display: grid;
  place-items: center;
  text-align: center;
}

.empty-title {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 18px;
}

.empty-body {
  font-size: 13px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

/* ── CMS: about ───────────────────────────────────────────────────────── */

.grid-about-cms {
  display: grid;
  grid-template-columns: 300px minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}

.link-row {
  display: grid;
  grid-template-columns: 150px minmax(0, 1fr) 36px;
  gap: 10px;
  align-items: center;
}

/* ── prosa de documento ───────────────────────────────────────────────── */

.prose > * {
  margin: 0 0 var(--gap, 12px);
  line-height: 1.55;
  text-wrap: pretty;
}

.prose > *:last-child {
  margin-bottom: 0;
}

.prose-h1 {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 28px;
}

.prose-h2 {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 21px;
}

.prose-h3 {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 17px;
}

.prose-p,
.prose-li {
  font-size: 15px;
}

.prose-meta {
  font-size: 12px;
}

/* En el sitio publico la prosa sube un punto de escala. */
.prose-site {
  --gap: 14px;
}

.prose-site .prose-h1 {
  font-size: 30px;
}

.prose-site .prose-h2 {
  font-size: 22px;
}

.prose-site .prose-h3 {
  font-size: 18px;
}

.prose-site .prose-p,
.prose-site .prose-li {
  font-size: 16px;
}

/* ── sitio publico ────────────────────────────────────────────────────── */

.site-shell {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.site-header {
  border-bottom: 1px solid var(--color-divider);
}

.site-header-inner {
  max-width: var(--shell-max);
  margin: 0 auto;
  padding: 16px 28px;
  display: flex;
  align-items: center;
  gap: 26px;
}

.site-brand {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 19px;
  margin-right: auto;
  color: inherit;
  text-decoration: none;
}

.site-nav-lnk {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 14px;
  letter-spacing: 0.02em;
  color: var(--color-text);
  text-decoration: none;
}

.site-nav-lnk:hover {
  color: var(--color-accent);
}

.site-nav-lnk[aria-current="page"] {
  color: var(--color-accent-700);
}

.site-cms-lnk {
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 45%, transparent);
  text-decoration: none;
}

.site-cms-lnk:hover {
  color: var(--color-accent);
}

.site-main {
  flex: 1;
  max-width: var(--shell-max);
  width: 100%;
  margin: 0 auto;
  padding: 40px 28px 80px;
}

.site-footer {
  border-top: 1px solid var(--color-divider);
}

.site-footer-inner {
  max-width: var(--shell-max);
  margin: 0 auto;
  padding: 20px 28px;
  display: flex;
  gap: 20px;
  align-items: center;
  font-size: 12px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

.site-footer-inner a {
  color: inherit;
  text-decoration: none;
}

.site-footer-inner a:hover {
  color: var(--color-accent);
}

.home {
  display: flex;
  flex-direction: column;
  gap: 44px;
}

.hero-title {
  margin: 0 0 14px;
  font-size: 64px;
  line-height: 0.98;
  letter-spacing: -0.02em;
}

.hero-intro {
  margin: 0;
  font-size: 17px;
  max-width: 46ch;
  text-wrap: pretty;
}

.label-row {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 14px;
}

.label-row .kicker {
  margin: 0;
}

.label-rule {
  flex: 1;
  height: 1px;
  background: var(--color-divider);
}

.label-count {
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 45%, transparent);
}

.grid-3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px;
}

.grid-3-tight {
  gap: 16px;
}

.appcell {
  color: inherit;
  text-decoration: none;
}

.appcell:hover {
  background: color-mix(in srgb, var(--color-accent) 8%, transparent);
}

.appcell .card-meta {
  margin-top: auto;
}

.app-view {
  display: flex;
  flex-direction: column;
  gap: 34px;
}

.app-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 36px;
  align-items: start;
}

.app-title {
  margin: 0 0 6px;
  font-size: 56px;
  line-height: 1;
}

.app-desc {
  font-size: 16px;
  max-width: 60ch;
  text-wrap: pretty;
}

.app-actions {
  display: flex;
  gap: 10px;
  margin-top: 18px;
}

.spec-k {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

.spec-v {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.no-docs {
  font-size: 15px;
  color: color-mix(in srgb, var(--color-text) 60%, transparent);
  max-width: 52ch;
}

.doc-view {
  display: flex;
  flex-direction: column;
  gap: 22px;
  max-width: 760px;
}

.doc-view .kicker {
  margin-bottom: 6px;
}

.doc-title {
  margin: 0;
  font-size: 46px;
}

.doc-meta {
  font-size: 12px;
  color: color-mix(in srgb, var(--color-text) 50%, transparent);
  margin-top: 8px;
}

.about-grid {
  display: grid;
  grid-template-columns: 320px minmax(0, 1fr);
  gap: 40px;
  align-items: start;
}

.about-title {
  margin: 0 0 20px;
  font-size: 52px;
  line-height: 1;
}

.about-bio {
  font-size: 17px;
  max-width: 56ch;
  text-wrap: pretty;
}

.elsewhere {
  margin-top: 26px;
  max-width: 460px;
}

.legal-title {
  margin: 0;
  font-size: 52px;
}

/* ── login ────────────────────────────────────────────────────────────── */

.login-shell {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: var(--space-6);
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
}

.login-panel {
  width: min(380px, 100%);
}

/* ── responsive ───────────────────────────────────────────────────────── */

@media (max-width: 1000px) {
  .app-grid,
  .about-grid,
  .grid-details,
  .grid-docs,
  .grid-about-cms {
    grid-template-columns: minmax(0, 1fr);
  }

  .app-title {
    font-size: 42px;
  }

  .about-title,
  .legal-title {
    font-size: 40px;
  }

  .grid-3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 860px) {
  .cms-shell {
    flex-direction: column;
  }

  .cms-sidebar {
    width: auto;
    height: auto;
    position: static;
    border-right: 0;
    border-bottom: 1px solid var(--color-divider);
  }

  .cms-foot {
    margin-top: 0;
  }

  .cms-main {
    padding: 20px 18px 48px;
  }

  .grid-3 {
    grid-template-columns: minmax(0, 1fr);
  }

  .grid-2,
  .grid-title-kind,
  .link-row {
    grid-template-columns: minmax(0, 1fr);
  }

  .link-row .btn-icon {
    justify-self: start;
  }

  .page-head {
    flex-wrap: wrap;
  }

  .page-head-actions {
    margin-left: 0;
  }

  .doc-title,
  .page-title {
    font-size: 32px;
  }
}

/* ── extras de componente ─────────────────────────────────────────────── */

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Un <fieldset> con leyenda es lo correcto para un grupo de radios; hay que
   devolverle el aspecto de `.field > label`, que el navegador no le da. */
fieldset.field {
  border: 0;
  margin: 0;
  padding: 0;
  min-width: 0;
}

.field > legend {
  display: block;
  padding: 0;
  font-size: 12px;
  margin-bottom: 5px;
  color: color-mix(in srgb, var(--color-text) 70%, transparent);
}

/* La lista del documento se dibuja como en el diseno —"· texto"— pero sigue
   siendo un <ul> de verdad para quien lo escucha en vez de verlo. */
.prose-list {
  list-style: none;
  padding: 0;
}

.prose-list .prose-li {
  margin-bottom: 4px;
}

.prose-list .prose-li::before {
  content: "· ";
}

/* ── hueco de imagen ──────────────────────────────────────────────────── */

.image-slot-wrap {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* La imagen llena su marco, que siempre es `position: relative`. Esto lo
   ponia `next/image` con `fill` en estilos en linea; sin Next tiene que
   estar escrito aqui, o la imagen se sale del marco y tapa lo de abajo. */
.image-slot-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* La zona de click cubre el marco entero y solo se ve cuando esta vacio o
   cuando el puntero pasa por encima: la imagen manda, no el control. */
.image-slot-hit {
  position: absolute;
  inset: 0;
  width: 100%;
  display: grid;
  place-items: center;
  border: 0;
  background: transparent;
  cursor: pointer;
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

.image-slot-hit:hover,
.image-slot-hit:focus-visible {
  background: color-mix(in srgb, var(--color-accent) 12%, transparent);
  color: var(--color-accent-800);
}

.figure.is-dragging {
  border-color: var(--color-accent);
}

.figure.is-dragging .image-slot-hit {
  background: color-mix(in srgb, var(--color-accent) 18%, transparent);
}

.image-slot-clear {
  align-self: flex-start;
}

/* ── linea de estado ──────────────────────────────────────────────────── */

/* "All changes saved" en versalitas diminutas esta bien: es una nota de fondo
   que nadie necesita leer. Un error es lo contrario —hay que poder leerlo— y
   con el mismo tratamiento se convertia en un muro de mayusculas de 10px.
   Cuando la linea trae un error deja de ser una nota y pasa a ser una frase. */
.cms-saved[data-tone="error"],
.save-note[data-tone="error"] {
  color: var(--color-accent-800);
  font-size: 12px;
  letter-spacing: 0;
  text-transform: none;
  line-height: 1.4;
}

.cms-foot-row:has([data-tone="error"]) {
  align-items: flex-start;
  flex-wrap: wrap;
}

.cms-foot-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.cms-foot-row .cms-saved {
  flex: 1;
  min-width: 0;
}

.cms-signout {
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.intro-input {
  min-height: 80px;
}

/* ── dialogo ──────────────────────────────────────────────────────────── */

/* `.blueprint` lleva `position: relative` para poder colgar las marcas de las
   esquinas. Eso convierte a TODO panel del CMS en un elemento posicionado. El
   backdrop tambien esta posicionado y ninguno de los dos declara `z-index`,
   asi que entre iguales gana el que va despues en el DOM — y el dialogo se
   renderiza donde vive su boton, arriba del todo. Resultado: los paneles se
   pintan encima del dialogo y se comen el titulo.

   En el prototipo no pasaba porque alli el dialogo era el ultimo nodo del
   documento. Aqui hay que decirlo explicitamente: un modal va por encima. */
.dialog-backdrop {
  z-index: 100;
}


/* La regla del final de industry.css mete `.dialog` en el mismo saco que
   `.card` y le quita el relleno. En una tarjeta eso es la gracia del sistema;
   en una ventana modal es un fallo — la pagina se transparenta a traves del
   dialogo y el texto se vuelve ilegible. El propio DS lo tenia bien antes de
   esa linea (`background: var(--color-surface)`), asi que esto no inventa
   nada: le devuelve el fondo.

   Se usa `--color-bg` y no `--color-surface` para que los `.input` —que son
   de color surface— sigan leyendose como campos dentro del dialogo. */
.dialog {
  background: var(--color-bg);
}

.prose strong {
  font-weight: 700;
}

/* ── versiones descargables ─────────────────────────────────────────────── */

/* Version, archivo y boton en una linea; el boton alineado con los inputs. */
.release-upload {
  display: grid;
  grid-template-columns: 1fr 160px auto;
  gap: 10px;
  align-items: end;
}

.release-card {
  gap: 10px;
  text-align: left;
}

.release-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.release-notes textarea {
  min-height: 72px;
}

.release-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

@media (max-width: 720px) {
  .release-upload {
    grid-template-columns: 1fr;
  }
}

/* ── retoques sobre el sistema ─────────────────────────────────────────── */

/* Los circulos solo tienen sentido sobre una lamina de imagen. En un panel de
   formulario o en una tabla no adornan: hacen ruido. */
.blueprint:not(.figure) > .mark {
  display: none;
}

.mark {
  position: absolute;
  width: 9px;
  height: 9px;
  border: 1px solid var(--color-accent-600);
  border-radius: 50%;
  pointer-events: none;
}

/* Van por FUERA del marco, no encima de la imagen: dentro desaparecian sobre
   cualquier lamina de fondo claro. */
.mark.tl { top: -5px; left: -5px; }
.mark.tr { top: -5px; right: -5px; }
.mark.bl { bottom: -5px; left: -5px; }
.mark.br { bottom: -5px; right: -5px; }

/* ── portada: indice de aplicaciones ──────────────────────────────────── */

/* `.home` ya separa sus secciones 44px; este margen solo anade lo que le
   falta a un titular de 64px para respirar. Poner aqui los 58px enteros
   duplicaba el hueco. */
.masthead {
  margin-bottom: 18px;
}

.masthead .hero-title {
  max-width: 16ch;
}

.masthead .hero-intro {
  margin-top: 14px;
}

.index {
  border-top: 1px solid var(--color-divider);
}

.index-head,
.index-row {
  display: grid;
  grid-template-columns: 62px 132px minmax(0, 1fr) 244px;
  gap: 28px;
  align-items: start;
}

.index-head {
  padding: 12px 0;
  border-bottom: 1px solid var(--color-divider);
}

/* La cuenta de elementos se alinea al final de la fila, sobre la ficha. */
.index-count {
  grid-column: 4;
  text-align: right;
}

.colhead {
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

.index-row {
  padding: 30px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--color-text) 9%, transparent);
  color: inherit;
  text-decoration: none;
}

.index-row:hover {
  background: color-mix(in srgb, var(--color-accent) 6%, transparent);
}

.index-num {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 13px;
  letter-spacing: 0.1em;
  color: var(--color-accent-600);
  font-variant-numeric: tabular-nums;
  padding-top: 6px;
}

.index-plate {
  position: relative;
  display: block;
  height: 208px;
  background: var(--color-bg);
}

/* La imagen se recorta en un hijo, no en la lamina: si la lamina llevara
   overflow:hidden se comeria los circulos, que van por fuera del marco. */
.index-plate > .image-slot-img {
  clip-path: inset(0);
}

.index-main {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}

.index-name {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 30px;
  line-height: 1.05;
  letter-spacing: -0.015em;
}

.index-desc {
  max-width: 52ch;
  color: color-mix(in srgb, var(--color-text) 72%, transparent);
}

.index-tag {
  margin-top: 2px;
}

.index-spec {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-top: 5px;
}

.spec-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 7px;
  border-bottom: 1px solid color-mix(in srgb, var(--color-text) 9%, transparent);
}

.spec-row:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

@media (max-width: 1000px) {
  .index-head {
    display: none;
  }

  .index-row {
    grid-template-columns: 108px minmax(0, 1fr);
    gap: 20px;
  }

  .index-num {
    display: none;
  }

  .index-plate {
    height: 168px;
  }

  /* La ficha tecnica pasa debajo del texto, ocupando el ancho del contenido. */
  .index-spec {
    grid-column: 2;
  }
}

@media (max-width: 640px) {
  .index-row {
    grid-template-columns: minmax(0, 1fr);
  }

  .index-plate {
    height: 200px;
    max-width: 150px;
  }

  .index-spec {
    grid-column: 1;
  }

  .index-name {
    font-size: 26px;
  }
}

/* ── notas de version, en la ficha publica ──────────────────────────────── */

/* Una linea de tiempo: el hilo a la izquierda y un punto por version. Se lee
   de arriba abajo como lo que es, un historial. */
.releases {
  list-style: none;
  margin: 0;
  padding: 0 0 0 26px;
  border-left: 1px solid var(--color-divider);
  display: flex;
  flex-direction: column;
  gap: var(--space-7);
}

.release {
  position: relative;
}

.release::before {
  content: "";
  position: absolute;
  left: -32px;
  top: 9px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--color-bg);
  border: 2px solid var(--color-neutral-400);
}

/* La ultima destaca sin gritar: el punto en color de marca. */
.release:first-child::before {
  background: var(--color-accent);
  border-color: var(--color-accent);
}

.release-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 12px;
}

.release-v {
  font-family: var(--font-heading);
  font-size: 26px;
  line-height: 1;
  margin: 0;
  letter-spacing: -0.01em;
}

.release-meta {
  font-size: 13px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

/* Empuja la descarga al extremo: se busca con el ojo, no leyendo. */
.release-get {
  margin-left: auto;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid currentColor;
}

.release-body {
  padding: var(--space-5) var(--space-6);
  background: var(--color-neutral-100);
}

.release:first-child .release-body {
  background: var(--color-accent-100);
}

.release-silent {
  margin: 0;
  font-size: 15px;
  color: color-mix(in srgb, var(--color-text) 45%, transparent);
}

@media (max-width: 640px) {
  .releases { padding-left: 20px; }
  .release::before { left: -26px; }
  .release-get { margin-left: 0; }
}

/* ── trayectoria ──────────────────────────────────────────────────────── */

.experience {
  margin-top: 40px;
  max-width: 56ch;
}

.exp-entry {
  padding: 22px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--color-text) 9%, transparent);
}

.exp-entry:last-child {
  border-bottom: 0;
}

/* Empresa, cargo y fechas en una linea; las fechas se van al extremo. */
.exp-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 10px;
}

.exp-company {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 22px;
  line-height: 1.1;
  margin: 0;
}

.exp-role {
  font-size: 13px;
  color: color-mix(in srgb, var(--color-text) 60%, transparent);
}

.exp-period {
  margin-left: auto;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 50%, transparent);
  font-variant-numeric: tabular-nums;
}

.exp-entry .prose > * {
  --gap: 8px;
}

/* ── CMS: lista de trayectoria ────────────────────────────────────────── */

.exp-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 36px;
  gap: 8px;
  align-items: start;
}

.exp-move {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.exp-move .btn-icon {
  height: 28px;
}

/* ── estados ──────────────────────────────────────────────────────────── */

/* Tonos apagados a proposito: en un sistema de una sola tinta, un verde de
   semaforo o un rojo de alerta gritarian. Estos comparten la claridad del
   resto de la paleta, asi que informan sin romper la pagina. */

.tag-live {
  background: #d5e3c4;
  color: #3a4a29;
}

.tag-beta {
  background: #dbe6f2;
  color: #2f4a6b;
}

.tag-wait {
  background: #f7e9cd;
  color: #6a4d16;
}

/* El borrador es el unico sin color: no esta esperando a nadie ni funciona
   todavia, asi que tampoco tiene por que llamar la atencion. */
.tag-draft {
  background: var(--color-neutral-200);
  color: var(--color-neutral-700);
}

/* ── traer de la App Store ────────────────────────────────────────────── */

.store-fetch {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  padding: 14px 0 2px;
  border-top: 1px solid color-mix(in srgb, var(--color-text) 9%, transparent);
}

.store-fetch-note {
  margin: 0;
  font-size: 12px;
  color: color-mix(in srgb, var(--color-text) 60%, transparent);
}

/* ── el panel en pantallas estrechas ──────────────────────────────────── */

@media (max-width: 860px) {
  /* Una tabla de seis columnas no cabe en un movil. Antes se salia de la
     pantalla y la ultima columna quedaba cortada sin manera de alcanzarla;
     ahora el panel se desplaza en horizontal y la tabla conserva su ancho. */
  .panel-table,
  .panel-tight {
    overflow-x: auto;
  }

  .panel-table .table,
  .panel-tight .table {
    min-width: 580px;
  }

  /* La barra lateral pasaba a cabecera pero seguia apilada: ocupaba la
     primera pantalla entera y habia que hacer scroll para ver cualquier dato.
     En horizontal cabe en una franja. */
  .cms-sidebar {
    gap: 14px;
  }

  .cms-nav {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 6px;
  }

  .cms-nav .sb-item {
    width: auto;
    gap: 6px;
  }

  /* El nombre ya esta arriba, en la marca: el retrato y el cargo sobran. */
  .cms-chip {
    display: none;
  }

  .cms-foot {
    flex-direction: row;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
  }

  .cms-foot .btn-block {
    width: auto;
  }

  .cms-foot-row {
    margin-left: auto;
  }
}

/* ── esqueletos de carga ──────────────────────────────────────────────── */

/* Bloques del color del papel, latiendo despacio. Nada de degradados
   deslizantes: en un sistema de linea fina cantarian. */
.skeleton {
  background: color-mix(in srgb, var(--color-text) 7%, transparent);
  animation: latido 1.4s ease-in-out infinite;
}

@keyframes latido {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

/* Quien ha pedido menos animacion no la recibe. */
@media (prefers-reduced-motion: reduce) {
  .skeleton {
    animation: none;
  }
}

.skeleton-kicker {
  width: 90px;
  height: 11px;
  margin-bottom: 10px;
}

.skeleton-title {
  width: 210px;
  height: 34px;
}

.skeleton-panel {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.skeleton-row {
  height: 22px;
}

.skeleton-row:nth-child(2) { width: 82%; }
.skeleton-row:nth-child(3) { width: 64%; }

/* ── navegacion en curso ──────────────────────────────────────────────── */

/* El punto aparece en el elemento pulsado mientras su pagina viaja. Es la
   diferencia entre "no ha registrado mi clic" y "esta yendo". */
.sb-dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--color-accent-600);
  animation: latido 1s ease-in-out infinite;
}

.is-pending {
  opacity: 0.55;
}

/* ── visitantes ───────────────────────────────────────────────────────── */

.vis-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: 20px;
  align-items: start;
}

.vis-total {
  font-size: 13px;
  color: color-mix(in srgb, var(--color-text) 60%, transparent);
}

.vis-total strong {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 20px;
  color: var(--color-text);
}

.mapa-svg {
  display: block;
  width: 100%;
  height: auto;
}

.mapa-tierra {
  fill: color-mix(in srgb, var(--color-text) 9%, transparent);
}

.mapa-punto {
  fill: var(--color-accent);
  fill-opacity: 0.55;
  stroke: var(--color-accent-800);
  stroke-width: 1.2;
}

.vis-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 9px;
}

/* La barra va en su propia pista para que no empuje al nombre ni a la cifra. */
.vis-row {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr) 34px;
  align-items: center;
  gap: 8px;
  position: relative;
  padding-bottom: 9px;
  border-bottom: 1px solid color-mix(in srgb, var(--color-text) 8%, transparent);
}

.vis-row:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

.vis-row-page {
  grid-template-columns: minmax(0, 1fr) 34px;
}

.vis-flag {
  font-size: 15px;
  line-height: 1;
}

.vis-name {
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.vis-path {
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 12.5px;
  color: color-mix(in srgb, var(--color-text) 75%, transparent);
}

.vis-bar {
  position: absolute;
  left: 28px;
  bottom: 2px;
  height: 3px;
  max-width: calc(100% - 66px);
  background: var(--color-accent-400);
}

.vis-hits {
  text-align: right;
  font-size: 13px;
  color: color-mix(in srgb, var(--color-text) 65%, transparent);
}

.vis-note {
  margin: 0;
  font-size: 12px;
  max-width: 62ch;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

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

/* El nombre que manda en una fila de tabla: el documento en /legal, la app
   en el catalogo del panel. Antes iba como estilo suelto en el JSX. */
.cell-strong {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 16px;
}

/* Las pestanas de una app son enlaces, no radios: cambiar de pestana cambia
   la URL para que la vuelta atras funcione. El tema pinta el segmento activo
   con `:has(input:checked)`, que aqui no aplica, asi que se repite el mismo
   aspecto sobre una clase. */
.seg-opt.is-on { background: var(--color-accent); color: var(--color-bg); }
.seg-opt:not(.is-on):hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); }
.seg-opt:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }
