/*
 * Hoja de estilos del panel de actividad.
 *
 * Mobile primero: los estilos de arriba son para un teléfono de 320 px y las dos
 * únicas media queries son de escritorio. Nada de framework ni de CDN: se sirve
 * desde el mismo origen (la CSP no permite otra cosa) y no hay paso de build.
 *
 * Números: `tabular-nums` en todo lo que sea importe o cuenta, para que las
 * columnas no bailen cuando cambia un dígito.
 */

:root {
    color-scheme: light dark;

    --fondo: #f6f7f9;
    --panel: #ffffff;
    --panel-alt: #f0f2f5;
    --borde: #d9dde3;
    --texto: #14171c;
    --tenue: #5c6572;
    --acento: #3b5bdb;
    --ok: #1f7a4d;
    --alerta: #a3341f;
    --radio: 10px;
    --sombra: 0 1px 2px rgb(0 0 0 / 6%);
}

@media (prefers-color-scheme: dark) {
    :root {
        --fondo: #14171c;
        --panel: #1b1f26;
        --panel-alt: #222833;
        --borde: #313947;
        --texto: #eef1f5;
        --tenue: #9aa4b2;
        --acento: #8fa7ff;
        --ok: #66d19e;
        --alerta: #ff9b8a;
        --sombra: none;
    }
}

*,
*::before,
*::after {
    box-sizing: border-box;
}

body {
    margin: 0;
    background: var(--fondo);
    color: var(--texto);
    font-family:
        system-ui,
        -apple-system,
        "Segoe UI",
        roboto,
        sans-serif;
    font-size: 1rem;
    line-height: 1.5;
    -webkit-text-size-adjust: 100%;
}

h1,
h2 {
    margin: 0;
    line-height: 1.25;
    text-wrap: balance;
}

h1 {
    font-size: clamp(1.35rem, 1.2rem + 1vw, 1.85rem);
}

h2 {
    font-size: clamp(1.05rem, 1rem + 0.4vw, 1.3rem);
}

/* Solo para lectores de pantalla, hasta que recibe foco. */
.saltar {
    position: absolute;
    left: -9999px;
}

.saltar:focus {
    left: 0.5rem;
    top: 0.5rem;
    z-index: 10;
    padding: 0.6rem 0.9rem;
    background: var(--panel);
    border: 2px solid var(--acento);
    border-radius: var(--radio);
}

/* La cabecera (`.cabecera*`, el chip de estado y su comportamiento) vive en
   `css/cabecera.css`, que se carga despues de esta hoja: es la pieza que mas
   cambia y no queremos que su crecimiento arrastre a la hoja entera. Aca quedan
   los botones (`.boton`) y el foco, que los usa tambien el login. */

.boton {
    min-height: 2.5rem; /* objetivo táctil cómodo */
    padding: 0 1rem;
    background: var(--acento);
    color: #fff;
    border: 0;
    border-radius: var(--radio);
    box-shadow: var(--sombra);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    /*
     * Los botones no tenían **ningún** estado: pasabas el mouse y no pasaba nada. El cambio es de
     * fondo y de sombra (y un pelo de elevación, más abajo): se nota que responde, sin llamar la
     * atención. La mezcla va con `--texto`, así que oscurece en claro y aclara en oscuro, en vez de
     * quedar mal en uno de los dos temas.
     */
    transition:
        background-color 140ms ease,
        border-color 140ms ease,
        box-shadow 140ms ease,
        transform 140ms ease;
}

/* El hover y el apretado, **solo** si el botón se puede apretar: uno deshabilitado no invita a nada. */
.boton:not([disabled]):hover {
    background: color-mix(in srgb, var(--acento) 88%, var(--texto));
    box-shadow:
        var(--sombra),
        0 6px 16px -8px color-mix(in srgb, var(--acento) 70%, transparent);
}

.boton:not([disabled]):active {
    background: color-mix(in srgb, var(--acento) 78%, var(--texto));
    box-shadow: var(--sombra);
}

/* La elevación es movimiento: va adentro de `no-preference` (el fondo y la sombra sí quedan). */
@media (prefers-reduced-motion: no-preference) {
    /* 2 px, no 1: el botón se despega lo suficiente para que se note que responde. */
    .boton:not([disabled]):hover {
        transform: translateY(-2px);
    }

    /* Y al apretarlo se hunde: la escala mínima se siente sin que el botón se corra de lugar. */
    .boton:not([disabled]):active {
        transform: translateY(0) scale(0.985);
    }
}

.boton[disabled] {
    opacity: 0.6;
    cursor: progress;
}

.boton:focus-visible {
    outline: 3px solid var(--acento);
    outline-offset: 2px;
}

.contenido {
    display: grid;
    gap: 1.25rem;
    max-width: 78rem;
    margin: 0 auto;
    padding: 1rem;
}

.seccion {
    display: grid;
    gap: 0.6rem;
}

.seccion__nota {
    margin: 0;
    color: var(--tenue);
    font-size: 0.85rem;
}

/* La cabecera de una sección: el título a la izquierda y su control a la derecha (el rango
   del período, el orden de una lista). Vivía en `css/graficas/base.css` y se mudó acá: es
   layout de página —lo usa también la página Equipos, que no tiene gráficas—. */
.seccion__cabecera {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1rem;
    align-items: baseline;
    justify-content: space-between;
}

/* El control de rango: la etiqueta y el desplegable. El desplegable en sí vive en
   `css/selector.css`, que es genérico. */
.rango {
    display: flex;
    gap: 0.4rem;
    align-items: center;
    color: var(--tenue);
    font-size: 0.85rem;
}

.rango__etiqueta {
    font-weight: 600;
}

/* En celular el rango ocupa el ancho: el desplegable queda alineado con el campo y no se sale
   de la pantalla (la etiqueta y el selector en la misma fila, el selector flexible). */
@media (width < 60rem) {
    .rango {
        width: 100%;
        justify-content: space-between;
    }

    .rango .selector {
        flex: 1 1 auto;
    }

    .rango .selector__boton {
        width: 100%;
    }
}

/* Tarjetas de totales: se acomodan solas, sin media queries, y nunca se hacen
   más angostas que su contenido mínimo. */
.tarjetas {
    display: grid;
    gap: 0.6rem;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
}

.tarjeta {
    padding: 0.8rem 0.9rem;
    background: var(--panel);
    border: 1px solid var(--borde);
    border-radius: var(--radio);
    box-shadow: var(--sombra);
}

.tarjeta__etiqueta {
    margin: 0;
    color: var(--tenue);
    font-size: 0.8rem;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.tarjeta__valor {
    margin: 0.25rem 0 0;
    font-size: clamp(1.15rem, 1rem + 0.8vw, 1.5rem);
    font-variant-numeric: tabular-nums;
    font-weight: 650;
}

/* -----------------------------------------------------------------------
   El protagonista: «Por pagar».

   Medido el 2026-10-15 en el navegador: las seis tarjetas eran del mismo
   tamaño y «Por pagar» era la cuarta, así que el número sobre el que se actúa
   competía con «Cuentas verificadas». La jerarquía visual (posición + tamaño,
   *visual emphasis* de Few) se resuelve haciendo que ese número sea
   inequívocamente el primero que se ve: más grande, con su borde, y ocupando
   el ancho completo de la fila en vez de una sexta parte.

   El color lo pone la tarjeta, no la regla: `.tarjeta--alerta` y `--ok` ya
   existen y el que se pinta sigue siendo el que corresponde al dato. Acá solo
   se define la escala, no el color de «cuánto hay que pagar».
   ----------------------------------------------------------------------- */
.tarjeta--protagonista {
    grid-column: span 2;
    padding: 1rem 1.1rem;
    border-width: 2px;
    border-color: color-mix(in srgb, var(--acento) 45%, var(--borde));
    background: color-mix(in srgb, var(--acento) 5%, var(--panel));
}

.tarjeta--protagonista .tarjeta__valor {
    /* Por debajo del `clamp` de las otras para que no crezca sin límite en
       pantallas anchas: el `2.5rem` es un tope, no un piso. */
    font-size: clamp(1.9rem, 1.2rem + 2.4vw, 2.6rem);
    line-height: 1.05;
}

@media (max-width: 47.99rem) {
    .tarjeta--protagonista {
        grid-column: span 1;
    }
}

.tarjeta--ok .tarjeta__valor {
    color: var(--ok);
}

.tarjeta--alerta .tarjeta__valor {
    color: var(--alerta);
}

/* `.lista`, `.fila`, `.fila__*` y `.barra` se fueron con la lista «Por equipo»
   (ver el comentario en `js/render.js`). Verificado el 2026-10-15: ninguna de esas
   clases aparece en el HTML ni en el JS, así que también se borró su
   `:focus-visible` de arriba. */

.cargando {
    margin: 0;
    padding: 0.7rem 0;
    color: var(--tenue);
    font-size: 0.9rem;
}

.aviso {
    margin: 0;
    padding: 0.75rem 0.9rem;
    border-radius: var(--radio);
    font-size: 0.92rem;
}

.aviso--error {
    background: color-mix(in srgb, var(--alerta) 12%, var(--panel));
    border: 1px solid color-mix(in srgb, var(--alerta) 45%, var(--borde));
    color: var(--texto);
}

.pie {
    max-width: 78rem;
    margin: 0 auto;
    padding: 0 1rem 1.5rem;
    color: var(--tenue);
    font-size: 0.8rem;
}

/* A partir de tablet ancha, equipos y días conviven en dos columnas. */
@media (min-width: 48rem) {
    .contenido {
        grid-template-columns: 1fr 1fr;
        align-items: start;
    }

    .contenido > .seccion:first-of-type,
    .aviso {
        grid-column: 1 / -1;
    }

    /* El Pareto («Dónde está el dinero») ocupa las dos columnas: es la gráfica que
       responde la pregunta del tablero y la que más barras trae. A media página
       las barras quedaban cortas y el escalón del acumulado, apretado. */
    .seccion--ancha {
        grid-column: 1 / -1;
    }

    /* **El detalle también, y sin esto no sirve de nada su rejilla de a dos.**
       `.contenido` es una rejilla de dos columnas y el detalle es un hijo suyo, así
       que sin esta regla ocupa **una** mitad de la página: las dos columnas de
       adentro repartían 289 px cada una (medido el 2026-10-15 con
       `scripts/medir-detalle.mjs`), o sea la mitad del ancho de las tarjetas del
       resumen y un montón de pantalla vacía al lado. Con esto el detalle mide el
       ancho completo y sus columnas son las mismas que las del resumen. */
    .detalle {
        grid-column: 1 / -1;
    }
}

/* -----------------------------------------------------------------------
   El detalle.

   Un botón, no un `details`: el panel ya se sirve con el script diferido y el
   `<details>` nativo se comporta distinto entre navegadores al ocultar el
   contenido. Con un `button` + `aria-expanded` el estado es explícito y
   accesible, y el CSS no depende de cómo el navegador pinte el resumen.

   La grilla del detalle es propia y **no** es la de dos columnas del resumen:
   el resumen tiene que leerse de a pares (una pregunta, una gráfica) y el
   detalle es un bloque de apoyo. Acá el ancho completo le sirve mejor a las
   gráficas de19 categorías que antes se apiñaban.
   ----------------------------------------------------------------------- */
/* -----------------------------------------------------------------------
   El detalle se despliega.

   `hidden` es `display: none` y **no se puede animar**, así que el alto va por la
   rejilla `0fr → 1fr`: es interpolable y no hace falta **conocer el alto** —que es
   justo lo que no se sabe, porque depende de cuántas gráficas traigan datos—. El
   contenido lleva `overflow: hidden` y `min-height: 0` para poder encogerse a cero;
   sin el `min-height` el ítem no baja de su contenido y el detalle nunca cierra.

   Ocupa las dos columnas de `.contenido` (ver la media query de escritorio): el
   detalle tiene su propia rejilla adentro, así que partir la página dos veces era
   dejarle la mitad del ancho.
   ----------------------------------------------------------------------- */
.detalle {
    display: grid;
    /* El botón (auto) y el contenido (0fr cerrado / 1fr abierto). */
    grid-template-rows: auto 0fr;
    margin-top: 0.5rem;
    transition: grid-template-rows 320ms cubic-bezier(0.22, 1, 0.36, 1);
}

.detalle.es-abierto {
    grid-template-rows: auto 1fr;
}

.detalle__boton {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.25rem 0.75rem;
    width: 100%;
    padding: 0.85rem 1rem;
    background: var(--panel);
    border: 1px dashed var(--borde);
    border-radius: var(--radio);
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease;
}

.detalle__boton:hover {
    border-color: var(--acento);
    background: color-mix(in srgb, var(--acento) 6%, var(--panel));
}

.detalle__boton:focus-visible {
    outline: 3px solid var(--acento);
    outline-offset: 2px;
}

.detalle__titulo {
    font-size: 1.05rem;
    font-weight: 650;
    color: var(--acento);
}

/* El indicador: un `+` que rota a `×` cuando está abierto. Se hace con dos
   pseudoelementos y una rotación, así que respects `prefers-reduced-motion`
   con el bloque de más abajo. */
.detalle__boton::after {
    content: '+';
    margin-left: auto;
    font-size: 1.2rem;
    font-weight: 400;
    color: var(--tenue);
    transition: transform 0.15s ease;
}

.detalle__boton[aria-expanded='true']::after {
    content: '−';
}

.detalle__pista {
    color: var(--tenue);
    font-size: 0.85rem;
}

.detalle__contenido {
    display: grid;
    gap: 1.75rem;
    /* Para poder encogerse a cero en la fila `0fr` (ver el comentario de `.detalle`). */
    overflow: hidden;
    min-height: 0;
    /* El contenido entra con un fundido corto que arranca cuando el alto ya avanzó,
       así no se ve el texto pegado al borde mientras se abre. */
    opacity: 0;
    transition: opacity 200ms linear 60ms;
}

.detalle.es-abierto .detalle__contenido {
    opacity: 1;
}

/* El aire entre el botón y el contenido va en el **primer bloque**, no en un margen
   del contenido: el margen de un ítem de rejilla queda fuera de su caja y el
   `overflow: hidden` no lo recorta, así que el detalle cerrado dejaría el hueco. */
.detalle__contenido > :first-child {
    margin-top: 1.25rem;
}

/* ---------------------------------------------------------------------------
   Un tema por bloque, y las gráficas de a dos.

   Por qué: con las seis tarjetas en una sola columna, el detalle era una lista
   larga —una gráfica por fila— donde ninguna se comparaba con la de al lado, que
   es justo para lo que están agrupadas. Medido el 2026-10-15 con el arnés
   (`scripts/medir-detalle.mjs`): las parejas comparten fila a partir de 60rem y en
   celular todo vuelve a una columna (el mismo corte que usa `.contenido`).
   --------------------------------------------------------------------------- */
.detalle__grupo {
    display: grid;
    gap: 1.25rem;
}

/* El rótulo del bloque ocupa la fila entera, no una celda: si no, quedaría de
   compañero de la primera gráfica. */
.detalle__grupo-titulo {
    grid-column: 1 / -1;
    margin: 0;
    color: var(--texto);
    font-size: 1.05rem;
    font-weight: 650;
}

/* Cada tarjeta con su alto, sin estirarse al de su vecina: las dos gráficas de un
   bloque no miden lo mismo (una lista de 19 equipos es más alta que un histograma
   de 7 tramos) y estirar la corta dejaría un hueco de panel vacío abajo. */
.detalle__grupo > .seccion {
    align-self: start;
}

@media (width >= 60rem) {
    .detalle__grupo {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* Con `prefers-reduced-motion` el despliegue no se anima: el estado cambia igual, sin
   movimiento. Es el mismo criterio que el resto del panel (la barra de la cabecera y
   las gráficas también lo respetan). */
@media (prefers-reduced-motion: reduce) {
    .detalle,
    .detalle__contenido {
        transition: none;
    }
}

.detalle__contenido .seccion > h2 {
    font-size: 1rem;
    color: var(--tenue);
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        transition: none !important;
        animation: none !important;
    }
}

/* El login tiene su propia hoja (`css/login.css`): su diseño cambió y vive aparte. Acá queda solo
   lo que comparte con el resto del panel. */

.boton--tenue {
    background: transparent;
    color: var(--texto);
    border: 1px solid var(--borde); /* el borde es su único relieve: por eso el hover lo usa */
}

/*
 * Los **tenues** no tenían estado propio: heredaban el del botón lleno (`background` al acento) y al
 * pasar el mouse se teñían de azul con el texto oscuro encima. Ahora se quedan tenues: se aclara el
 * fondo un pelo y el **borde** toma el acento, que es la señal de que se puede apretar.
 */
.boton--tenue:not([disabled]):hover {
    background: color-mix(in srgb, var(--panel-alt) 70%, var(--acento));
    border-color: var(--acento);
}

.boton--tenue:not([disabled]):active {
    background: color-mix(in srgb, var(--panel-alt) 55%, var(--acento));
    border-color: var(--acento);
}

.salir {
    margin: 0;
}

/* ===================== LOS DIÁLOGOS ===================== */

/*
 * Los diálogos del panel: el mismo `<dialog>` nativo y el mismo aspecto en todas las páginas que lo
 * usan (la ficha de un equipo y el inventario de SSIDs). Vivían en `css/equipos.css` y se mudaron acá
 * cuando la segunda página los necesitó: una pieza compartida no puede depender de la hoja de una
 * página.
 */

.dialogo {
    --peligro: #c0341c;
    width: min(100% - 2rem, 30rem);
    margin: auto;
    padding: 0;
    background: var(--panel);
    color: var(--texto);
    border: 1px solid var(--borde);
    border-radius: calc(var(--radio) + 4px);
    box-shadow: 0 30px 70px -40px color-mix(in srgb, var(--texto) 70%, transparent);
}

@media (prefers-color-scheme: dark) {
    .dialogo {
        --peligro: #d4563c;
    }
}

.dialogo::backdrop {
    background: color-mix(in srgb, var(--texto) 45%, transparent);
}

/*
 * Los diálogos **entraban de golpe**: aparecían en el medio de la pantalla sin ninguna transición, y
 * el fondo oscurecido también. Ahora entran subiendo un pelo —y el fondo aparece con un fundido—, que
 * es lo que hace que se lea como «esto se abrió y atrás hay una página».
 *
 * El **cierre** lo anima `cerrarDialogo()` (`js/equipos/comun.js`), porque un `<dialog>` se cierra con
 * `close()` y eso no se anima desde el CSS: la clase `dialogo--cerrando` es la que lo hace. Por eso el
 * selector del cierre lleva el `[open]` adelante: si no, el `[open]` de arriba (más específico) le
 * ganaría y la animación de salida no se vería nunca.
 *
 * La regla global de `prefers-reduced-motion` de `app.css` apaga todo esto de una.
 */
.dialogo[open] {
    animation: entra-dialogo 180ms cubic-bezier(0.2, 0.9, 0.3, 1) both;
}

.dialogo[open]::backdrop {
    animation: entra-fondo 180ms ease both;
}

.dialogo[open].dialogo--cerrando {
    animation: sale-dialogo 140ms ease both;
}

.dialogo[open].dialogo--cerrando::backdrop {
    animation: sale-fondo 140ms ease both;
}

@keyframes entra-dialogo {
    from {
        opacity: 0;
        transform: translateY(0.6rem) scale(0.985);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes sale-dialogo {
    from {
        opacity: 1;
    }
    to {
        opacity: 0;
        transform: translateY(0.35rem) scale(0.99);
    }
}

@keyframes entra-fondo {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

@keyframes sale-fondo {
    from {
        opacity: 1;
    }
    to {
        opacity: 0;
    }
}

.dialogo__caja {
    display: grid;
    gap: 0.7rem;
    padding: 1.1rem 1.2rem;
}

.dialogo__eyebrow {
    margin: 0;
    color: var(--tenue);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.dialogo__titulo {
    margin: 0;
    font-size: 1.25rem;
}

/*
 * El ID de quien se está tocando, monoespaciado y debajo del nombre.
 *
 * Va porque el nombre no alcanza para confirmar a quién: se puede cambiar, y dos personas pueden
 * llamarse igual. Es la misma regla que la tabla de integrantes (AGENTS §4.9): el ID no se borra.
 */
.dialogo__id {
    margin: -0.35rem 0 0;
    color: var(--tenue);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.78rem;
    letter-spacing: 0;
}

.dialogo__texto {
    margin: 0;
    color: var(--tenue);
    font-size: 0.9rem;
}

.dialogo__datos {
    display: grid;
    gap: 0.3rem;
    margin: 0;
}

/* El botón que sí cambia las cosas va a la derecha y con el color del acento; Cancelar queda a la
   izquierda y con el foco puesto al abrir (la opción segura es la que está por defecto). */
.dialogo__acciones {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    justify-content: flex-end;
    padding-top: 0.2rem;
}

/* ---- El botón de copiar ---------------------------------------------------- */


/* ===================== LA PERSONA (ID + NOMBRE + AVATAR) ===================== */

/*
 * Cómo se muestra una persona del panel: su avatar, su nombre y **el ID abajo**, que nunca se
 * borra. Vivía en `css/equipos.css` y se mudó acá cuando la bandeja de SSIDs la necesitó: es
 * una pieza compartida, y los avatares los sirve el panel (`/api/avatar/<id>`), nunca el CDN
 * de Discord (AGENTS §4.10: la máquina del Owner está detrás de un proxy).
 */

.persona__avatar {
    grid-row: span 2;
}

.persona {
    margin-top: 0.2rem;
    font-size: 0.82rem;
}
.persona__id {
    font-size: 0.68rem;
}
.persona {
    display: grid;
    /*
     * `1fr` y **no** `minmax(0, 1fr)`: el mínimo de la columna tiene que ser el del contenido, o
     * la tabla no reserva lugar para los 19 dígitos del ID y lo aplasta contra la columna de al
     * lado (medido con la ficha abierta: la columna jefe quedaba en 118 px y el ID necesita ~155).
     * El nombre no se estira de más igual: se parte con `overflow-wrap: anywhere`.
     */
    grid-template-columns: 1fr;
    gap: 0.05rem;
}
/* Con avatar, el nombre y el ID se corren a la derecha de la imagen. */
.persona[data-avatar='si'] {
    grid-template-columns: auto 1fr;
    gap: 0.1rem 0.5rem;
    align-items: center;
}
.persona__avatar {
    position: relative;
    display: grid;
    place-items: center;
    width: 1.75rem;
    height: 1.75rem;
    background: var(--panel-alt);
    border: 1px solid var(--borde);
    border-radius: 50%;
    overflow: hidden;
}
.persona__marca {
    color: var(--tenue);
    font-size: 0.8rem;
    font-weight: 650;
    line-height: 1;
}
/* La imagen tapa la inicial cuando carga; si falla, el manejador la saca y se ve la inicial. */
.persona__imagen {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.persona__nombre {
    font-weight: 650;
    overflow-wrap: anywhere;
}
.persona__id {
    color: var(--tenue);
}
.persona__nota {
    color: var(--alerta);
    font-size: 0.75rem;
}

/* ===================== UN TEXTO DE PLANTILLA, COMO SE VA A VER ===================== */

/*
 * El render aproximado de un texto de plantilla (títulos, negritas, enlaces) y sus variables resueltas
 * con datos de ejemplo. Lo usan la página de Plantillas y la de SSID: por eso vive acá y no en la hoja
 * de una página.
 */
.texto-plantilla__bloques {
    display: grid;
    gap: 0.6rem;
}

.texto-plantilla {
    display: grid;
    gap: 0.35rem;
    padding: 0.7rem 0.8rem;
    background: var(--panel-alt);
    border: 1px solid var(--borde);
    border-radius: var(--radio);
}

.texto-plantilla__linea {
    margin: 0;
    font-size: 0.92rem;
    overflow-wrap: anywhere;
}

.texto-plantilla__linea--titulo {
    margin-top: 0.3rem;
    font-weight: 700;
    font-size: 0.98rem;
}

/* Los enlaces se ven como enlaces, pero no son un clic desde el panel. */
.texto-plantilla__enlace {
    color: var(--acento);
    overflow-wrap: anywhere;
}
