/* Componentes compartidos: avisos, menú, diálogo, hoja lateral, campos. */

/* ---------- Avisos ---------- */
.toasts { position: fixed; right: var(--space-4); bottom: calc(var(--dock-height, 0px) + var(--space-4)); z-index: 60; display: flex; flex-direction: column; gap: var(--space-2); align-items: flex-end; pointer-events: none; }
.toast {
	position: relative; overflow: hidden; pointer-events: auto; cursor: pointer;
	display: flex; align-items: center; gap: var(--space-3);
	min-width: 240px; max-width: min(420px, calc(100vw - 32px));
	padding: var(--space-3) var(--space-4) calc(var(--space-3) + 2px);
	/* Siempre oscuro y con su propio texto: dentro de un modal claro (papel, plan activado) no se tiñe de él. */
	color: #f3f5f8; background: #23262d; border: 1px solid rgba(255, 255, 255, 0.08); border-radius: 24px;
	box-shadow: 0 16px 40px rgba(0, 0, 0, 0.45);
	animation: toast-in 180ms var(--ease);
}
.toast.leaving { opacity: 0; transform: translateY(4px); transition: opacity 180ms, transform 180ms; }
.toast-title { margin: 0; flex: 1; font-size: var(--text-sm); }
.toast-action { border-radius: var(--radius-pill); min-height: 32px; padding: 0 var(--space-3); font-size: var(--text-sm); font-weight: 600; background: transparent; border-color: #3a3e47; }
.toast-bar { position: absolute; left: 0; bottom: 0; width: 100%; height: 2px; background: var(--text-muted); opacity: 0.5; transform-origin: left; transition-property: transform; transition-timing-function: linear; }
.toast-bar.run { transform: scaleX(0); }
.toast.error .toast-bar { background: var(--accent); opacity: 1; }
@keyframes toast-in { from { opacity: 0; transform: translateY(6px); } }

/* ---------- Globo de ayuda (common/tooltip.js) ---------- */
.tooltip { position: fixed; z-index: 80; width: max-content; max-width: 280px; padding: 6px 12px; pointer-events: none; background: #0c0e14; border: 1px solid var(--hairline); border-radius: 14px; box-shadow: var(--shadow-float); font-size: var(--text-xs); line-height: 1.45; color: var(--text); white-space: normal; text-wrap: pretty; animation: toast-in 140ms var(--ease); } /* un texto largo salta de línea en vez de cortarse */

/* ---------- Menú ---------- */
.menu {
	position: fixed; z-index: 70; min-width: 196px; padding: 6px;
	background: var(--panel-raised); border: 1px solid var(--hairline); border-radius: 22px;
	box-shadow: var(--shadow-float);
	max-height: min(420px, calc(100dvh - 16px)); overflow-y: auto; scrollbar-width: none;
}
.menu::-webkit-scrollbar { display: none; }
.menu-item {
	display: flex; width: 100%; align-items: center; min-height: 36px; padding: 0 var(--space-3);
	border: 0; border-radius: var(--radius-pill); background: none; text-align: left; font-size: var(--text-sm);
}
/* La nota de cabecera de un menú no es una opción: ni se resalta ni responde al ratón. */
.menu-item:hover:not([aria-disabled]), .menu-item:focus-visible { background: #2d3139; outline: none; }
.menu-item[aria-disabled] { cursor: default; }
.menu-item.danger { color: #ff8a80; }
/* Una nota en el menú (título y explicación), sin acción: va como ítem desactivado. */
.menu-note { display: grid; gap: 2px; max-width: 240px; padding: 2px 0; white-space: normal; }
.menu-note strong { font-size: var(--text-xs); font-weight: 600; color: var(--text); }
.menu-note span { font-size: 11px; line-height: 1.4; color: var(--text-muted); }
/* Interruptor: en un menú (.menu-switch) o en una barra (.switch-button). Encendido = azul de la marca. */
.switch-track { display: block; position: relative; flex: none; width: 30px; height: 18px; border-radius: 9px; background: rgba(255, 255, 255, 0.16); transition: background 0.2s ease, box-shadow 0.2s ease; }
.switch-track::after { content: ''; position: absolute; left: 2px; top: 2px; width: 14px; height: 14px; border-radius: 50%; background: #fff; opacity: 0.8; transition: translate 0.2s var(--ease), opacity 0.2s ease; }
[aria-checked="true"] > .switch-track { background: var(--brand); box-shadow: 0 0 12px rgba(var(--brand-rgb), 0.45); }
[aria-checked="true"] > .switch-track::after { translate: 12px; opacity: 1; }
.menu-switch { justify-content: space-between; gap: var(--space-4); }
.menu-switch-label { padding-left: calc(16px + var(--space-2)); } /* alineado con los textos que llevan marca de elegido */
.menu-check { flex: none; display: inline-grid; place-items: center; width: 16px; margin-right: var(--space-2); color: var(--selection); }
/*
 * Los menús de elegir una opción (.is-choice: idioma, moneda, modo…): la elegida, en una pastilla celeste con el texto
 * en tinta; sin marca de elegido. Vale en los de papel y en los oscuros.
 */
.menu.is-choice .menu-check { display: none; }
.menu.is-choice .menu-item { padding: 0 14px; border-radius: var(--radius-pill); }
.menu.is-choice .menu-item[aria-checked="true"]:not(.menu-switch) { font-weight: 700; color: var(--on-brand); background: var(--brand); }
.menu.is-choice .menu-item[aria-checked="true"]:not(.menu-switch):is(:hover, :focus-visible) { color: var(--on-brand); background: var(--brand-hover); }
/* Sin marcas de elegido en el menú, el texto de un interruptor o de una fila de opciones va pegado a la izquierda. */
.menu:not(:has(.menu-check)) .menu-switch-label { padding-left: 0; }
/* Fila de opciones (Voz | Escritura): el texto a la izquierda y la pastilla a la derecha; la elegida, en azul. */
.menu-segmented { justify-content: space-between; gap: var(--space-4); }
.menu-segments { flex: none; display: inline-flex; gap: 2px; padding: 3px; background: rgba(255, 255, 255, 0.08); border-radius: var(--radius-pill); }
.menu-segment { padding: 4px 11px; font-size: 12.5px; font-weight: 600; line-height: 1.2; color: var(--text-muted); border-radius: var(--radius-pill); transition: background 0.16s var(--ease), color 0.16s var(--ease); }
.menu-segment:hover:not(.is-on) { color: var(--text); }
.menu-segment.is-on { color: var(--on-brand); background: var(--brand); }
.menu-separator { height: 1px; margin: var(--space-1) 0; border: 0; background: var(--border); }
.menu-icon { flex: none; display: inline-grid; place-items: center; width: 16px; height: 16px; margin-right: 12px; color: var(--text-muted); }
.menu-icon .icon { width: 16px; height: 16px; }
/*
 * Papel: el menú en marfil, como el del usuario (es el de todos los menús de la casa; { paper: false } lo deja
 * oscuro). Opciones más altas, con su icono a la izquierda en gris, y el resalte en tinta suave. Dentro, los tokens
 * pasan a tinta sobre marfil: lo que cada menú pinta por su cuenta (el historial de una pantalla, las miniaturas de
 * Recursos, las notas, las teclas) se lee sin reescribirlo.
 */
.menu.paper {
	--text: var(--paper-text); --text-muted: var(--paper-muted); --border: var(--paper-line); --hairline: var(--paper-line);
	--panel-raised: var(--paper-card); --selection: var(--brand-deep); --live: #0f7a4a; --accent: #b3261e;
}
.menu.paper .menu-hint { background: rgba(0, 0, 0, 0.06); border-color: var(--paper-line); }
.menu.paper { min-width: 220px; padding: 8px; color: var(--paper-text); background: var(--paper-bg); border-color: var(--paper-line); border-radius: 18px; box-shadow: var(--paper-shadow); }
.menu.paper .menu-item { min-height: 38px; padding: 0 10px; font-size: 14px; font-weight: 500; color: var(--paper-text); border-radius: 10px; }
.menu.paper .menu-item:hover:not([aria-disabled]), .menu.paper .menu-item:focus-visible { background: var(--paper-hover); }
.menu.paper .menu-item.danger { color: #b3261e; }
.menu.paper .menu-icon, .menu.paper .menu-hint { color: var(--paper-muted); }
.menu.paper .menu-check { color: var(--brand-deep); }
.menu.paper .menu-separator { margin: 5px 6px; background: var(--paper-line); }
/* Etiquetas para leer dentro de un menú (la persona en Mis clientes). */
.menu-tags { display: grid; gap: 6px; max-width: 260px; padding: 6px 10px 8px; }
.menu-tags-label { font-size: 12px; font-weight: 600; color: var(--paper-muted, var(--text-muted)); }
.menu-tags-list { display: flex; flex-wrap: wrap; gap: 5px; }
.menu-tag { padding: 3px 9px; font-size: 12.5px; font-weight: 600; color: #08718b; background: rgba(8, 113, 139, 0.1); border-radius: 999px; }
.menu.paper .menu-note strong { color: var(--paper-text); }
.menu.paper .menu-note span { color: var(--paper-muted); }
.menu.paper .switch-track { background: rgba(0, 0, 0, 0.18); }
.menu.paper [aria-checked="true"] > .switch-track { background: var(--brand-deep); box-shadow: none; }
.menu.paper .menu-segments { background: rgba(0, 0, 0, 0.07); }
.menu.paper .menu-segment { color: var(--paper-muted); }
.menu.paper .menu-segment:hover:not(.is-on) { color: var(--paper-text); }
.menu.paper .menu-segment.is-on { color: var(--on-brand); background: var(--brand); }

/* ---------- Diálogo y hoja lateral ---------- */
dialog { color: var(--text); background: var(--panel); border: 1px solid var(--border); padding: 0; }
dialog::backdrop { background: rgba(8, 9, 11, 0.62); }
.dialog { width: min(440px, calc(100vw - 32px)); border-radius: var(--radius-lg); box-shadow: var(--shadow-float); }
.dialog form { padding: var(--space-5); }
.dialog h2 { margin: 0 0 var(--space-2); font-size: 17px; font-weight: 600; text-wrap: balance; }
.dialog p { margin: 0; color: var(--text-muted); font-size: var(--text-sm); }
.dialog-actions { display: flex; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-5); }
/* «No volver a preguntar»: a la izquierda, los botones se quedan a la derecha. */
.dialog-actions { align-items: center; }
.dialog:has(.dialog-remember) { width: min(540px, calc(100vw - 32px)); }
.dialog-remember { display: inline-flex; align-items: center; gap: 8px; margin-right: auto; padding-right: 32px; font-size: var(--text-sm); color: var(--text-muted); cursor: pointer; user-select: none; }
.dialog-remember input { width: 16px; height: 16px; margin: 0; accent-color: var(--brand); cursor: pointer; }
.dialog-remember:hover { color: var(--text); }
button.destructive { background: #b3261e; border-color: #b3261e; color: #fff; font-weight: 600; }

.sheet {
	/* Panel flotante, como la columna y la franja del lienzo: 10 px de aire y esquinas redondas. */
	position: fixed; inset: 10px 10px 10px auto; margin: 0; height: calc(100dvh - 20px); max-height: none; overflow: hidden;
	width: min(480px, calc(100vw - 20px)); border: 1px solid var(--hairline); border-radius: var(--radius-lg); box-shadow: var(--shadow-float);
	animation: sheet-in 220ms var(--ease);
}
.sheet[open] { display: flex; flex-direction: column; }
@keyframes sheet-in { from { transform: translateX(24px); opacity: 0; } }

/* ---------- Grupos de botones y botones de icono ---------- */
.segments { display: inline-flex; padding: 4px; gap: 2px; background: var(--panel); border: 1px solid var(--hairline); border-radius: var(--radius-pill); }
.segment {
	min-height: 34px; padding: 0 var(--space-3);
	display: inline-flex; align-items: center; gap: var(--space-2);
	border: 0; border-radius: var(--radius-pill); background: none; font-size: var(--text-sm); color: var(--text-muted);
}
.segment:hover { color: var(--text); }
.segment[aria-pressed="true"] { background: var(--panel-raised); color: var(--text); box-shadow: inset 0 0 0 1px var(--border); }
.segment .count { color: var(--text-muted); font-size: var(--text-xs); }
.icon-segment { padding: 0 var(--space-2); }
.icon-button {
	display: inline-grid; place-items: center; min-width: var(--touch); min-height: var(--touch); padding: 0;
	background: none; border: 0; border-radius: 50%; color: var(--text-muted);
}
.icon-button:hover { color: var(--text); background: var(--panel-raised); }


/* ---------- Campos ---------- */
.field { display: grid; gap: var(--space-1); }
.field > span, legend { font-size: var(--text-sm); font-weight: 600; }
/* La explicación bajo un campo es un span más: sin esto se llevaba la negrita del título. */
.field > .hint { font-size: var(--text-xs); font-weight: 400; line-height: 1.45; }
.field input, .field select, input.text {
	min-height: var(--touch); padding: 0 var(--space-3);
	background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-pill);
}
.field input:focus-visible, .field select:focus-visible, input.text:focus-visible { border-color: var(--selection); outline: none; }
/* Un desplegable y un texto largo con la misma piel que los campos: sin el gris del sistema. */
select.text, .field select {
	min-height: var(--touch); padding: 0 calc(var(--space-3) + 20px) 0 var(--space-3); appearance: none; -webkit-appearance: none; cursor: pointer;
	background: var(--bg) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23a3a9b4' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") no-repeat right var(--space-3) center;
	border: 1px solid var(--border); border-radius: var(--radius-pill);
}
select.text option, .field select option { background: var(--surface, #16191f); color: var(--text); }
textarea.text {
	min-height: 72px; padding: var(--space-2) var(--space-3); line-height: 1.45;
	background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-md);
}
textarea.text::placeholder { color: var(--text-muted); }
select.text:focus-visible, textarea.text:focus-visible { border-color: var(--selection); outline: none; }
.hint { margin: 0; font-size: var(--text-xs); color: var(--text-muted); }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* PROVISIONAL: el aviso de los selectores de propuestas (buscador, tipografías). Se apaga solo. */
.variant-chip { position: fixed; z-index: 80; left: 50%; bottom: 20px; translate: -50% 0; display: flex; align-items: baseline; gap: var(--space-2); padding: 8px var(--space-4); font-size: var(--text-sm); color: #ecedf0; background: rgba(12, 14, 22, 0.94); border: 1px solid rgba(var(--brand-rgb), 0.5); border-radius: var(--radius-pill); box-shadow: 0 0 24px rgba(var(--brand-rgb), 0.25), 0 14px 40px rgba(0, 0, 0, 0.5); pointer-events: none; }
.variant-chip[hidden] { display: none; }
.variant-chip.font-chip { bottom: 64px; }
.variant-chip-count { font-size: var(--text-xs); color: #a6e6f5; font-variant-numeric: tabular-nums; }
.variant-chip-keys { font-size: var(--text-xs); color: #8b92a0; }

/* Un globo con explicación: título y uno o dos párrafos (tooltip(el, () => h('div', { class: 'tooltip-rich' }, …))). */
.tooltip:has(.tooltip-rich) { max-width: 340px; padding: var(--space-4); white-space: normal; text-align: left; border-radius: 18px; }
.tooltip-rich { display: grid; gap: var(--space-2); }
.tooltip-rich strong { font-size: var(--text-sm); color: var(--text); }
.tooltip-rich p { margin: 0; font-size: var(--text-xs); line-height: 1.5; color: var(--text-muted); text-wrap: pretty; }

.flow-opt-screen { display: inline-flex; align-items: baseline; gap: var(--space-2); }
.flow-opt-used { font-size: var(--text-xs); color: var(--text-muted); }

/* Por qué una opción está apagada: en gris a su derecha, con aire, sin fondo. */
.menu-aside { margin-left: auto; padding-left: 28px; font-size: 12.5px; font-weight: 400; color: var(--text-muted); white-space: nowrap; }
.menu.paper .menu-aside { color: var(--paper-muted); }
/* Una opción que abre otro menú a su lado: la flecha a la derecha. */
.menu-more { display: grid; place-items: center; margin-left: auto; padding-left: 16px; opacity: 0.6; }
/* El menú de al lado (Asignar a…): personas con su foto o su inicial. */
.menu-sub { position: fixed; min-width: 220px; z-index: 71; }
.menu-person { gap: 10px; }
.menu-avatar { display: grid; place-items: center; flex: none; width: 26px; height: 26px; overflow: hidden; font-size: 11px; font-weight: 700; color: #08414f; background: #bfeaf4; border-radius: 50%; }
.menu-avatar img { width: 100%; height: 100%; object-fit: cover; }
.menu-person .menu-check { order: 3; margin-left: auto; }
/* «Invitar a alguien», al pie de la lista: el icono en el círculo de las caras, en el color de la marca. */
.menu-invite { font-weight: 600; color: #08718b; }
.menu.paper .menu-item.menu-invite { color: #08718b; }
.menu-invite .menu-avatar { color: #08718b; background: rgba(8, 113, 139, 0.1); }
.menu-empty { margin: 0; padding: 10px 12px; font-size: 13px; color: var(--paper-muted, var(--text-muted)); }

/* ---------- El selector de color abierto (common/color-field.js): Bocetos y el diálogo de cambiar un color ---------- */
.cf { display: grid; gap: 12px; }
.cf-area {
	position: relative; height: 150px; border-radius: 14px; cursor: crosshair; touch-action: none;
	background: linear-gradient(to top, #000, transparent), linear-gradient(to right, #fff, var(--hue, red));
}
.cf-thumb, .cf-hue-thumb {
	position: absolute; width: 18px; height: 18px; translate: -50% -50%; pointer-events: none;
	border: 3px solid #fff; border-radius: 50%; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25), 0 2px 6px rgba(0, 0, 0, 0.3);
}
.cf-hue { position: relative; height: 14px; border-radius: 999px; cursor: pointer; touch-action: none; background: linear-gradient(to right, #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00); }
.cf-hue-thumb { top: 50%; }
.cf-area:focus-visible, .cf-hue:focus-visible { outline: 2px solid var(--brand-deep); outline-offset: 2px; }
.cf-codes { display: grid; grid-template-columns: auto 1fr 1fr; align-items: end; gap: 8px; }
.cf-preview { width: 40px; height: 34px; border-radius: 10px; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12); }
.cf-label { display: grid; gap: 3px; min-width: 0; }
.cf-label span { font-size: 10px; font-weight: 700; letter-spacing: 0.08em; color: var(--paper-muted, #5f6570); }
.cf-code { width: 100%; min-width: 0; height: 34px; padding: 0 9px; font: 600 12.5px/1 var(--font); letter-spacing: 0.02em; color: var(--paper-text, #1d2126); background: #fff; border: 1px solid rgba(0, 0, 0, 0.12); border-radius: 10px; }
.cf-code:focus { outline: none; border-color: var(--brand-deep); }

/* ---------- Papel: superficies claras (como el modal de nuevo proyecto) ---------- */
/* Dentro, los tokens pasan a tinta sobre marfil: lo que cada pieza pinta con ellos se lee sin reescribirlo. */
.paper-surface, .paper-dialog {
	--text: var(--paper-text); --text-muted: var(--paper-muted); --border: var(--paper-line); --hairline: var(--paper-line);
	--panel: var(--paper-card); --panel-raised: var(--paper-card); --selection: var(--brand-deep); --live: #0f7a4a; --accent: #b3261e;
	color: var(--paper-text);
}
/* Los diálogos de cambiar (un color, un radio): papel, esquinas grandes y el botón de aplicar en el azul de la marca. */
.paper-dialog { width: min(460px, calc(100vw - 32px)); background: var(--paper-bg); border: 0; border-radius: 24px; box-shadow: 0 30px 80px rgba(0, 0, 0, 0.55); }
.paper-dialog::backdrop { background: rgba(4, 8, 14, 0.6); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.paper-dialog form { padding: 24px; }
.paper-dialog h2 { margin: 0 0 6px; font-family: var(--font-heading); font-size: 21px; font-weight: 600; letter-spacing: -0.01em; color: var(--paper-text); }
.paper-dialog p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--paper-muted); }
.paper-dialog .dialog-actions { margin-top: 20px; }
.paper-cancel { min-height: 40px; padding: 0 18px; font-weight: 600; color: var(--paper-text); background: #fff; border: 1px solid var(--paper-line); border-radius: 999px; }
.paper-cancel:hover { border-color: rgba(0, 0, 0, 0.22); }
.paper-apply { min-height: 40px; padding: 0 20px; font-weight: 700; color: #fff; background: var(--brand-deep, #08718b); border: 0; border-radius: 999px; }
.paper-apply:hover:not(:disabled) { background: #065d73; }
.paper-apply:disabled { opacity: 0.4; cursor: not-allowed; }
.paper-apply:focus-visible, .paper-cancel:focus-visible { outline: 2px solid var(--brand-deep); outline-offset: 2px; }

/* ---------- «En N pantallas» y su globo con las miniaturas (common/screens-tip.js) ---------- */
.has-screens-tip { cursor: help; text-decoration: underline dotted rgba(127, 127, 127, 0.6); text-underline-offset: 3px; }
.tooltip:has(.screens-tip) { max-width: min(640px, calc(100vw - 32px)); padding: 10px; }
.screens-tip { display: grid; gap: 8px; }
.screens-tip-grid { display: flex; gap: 8px; }
.screens-tip-item { display: grid; justify-items: center; gap: 5px; margin: 0; }
.screens-tip-item img, .screens-tip-blank { display: block; height: 120px; width: auto; max-width: 140px; object-fit: cover; object-position: top; border-radius: 8px; background: #fff; box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.12); }
.screens-tip-blank { width: 68px; background: rgba(255, 255, 255, 0.08); }
.screens-tip-item figcaption { max-width: 100px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11px; font-weight: 600; }
.screens-tip-more { margin: 0; font-size: 11px; color: var(--text-muted); }

/* ---------- La barrita de desplazamiento (common/scroll-thumb.js): la de por defecto en Bitácora ----------
   Sin la barra del navegador en los modales y en lo marcado: al desplazar sale esta, fina y por encima del contenido
   (no lo mueve), y se va sola. Va en el modal que contiene lo desplazado o, fija, en el cuerpo. */
.has-scroll-thumb, dialog, dialog * { scrollbar-width: none !important; }
:is(.has-scroll-thumb, dialog, dialog *)::-webkit-scrollbar { display: none !important; }
.scroll-thumb { position: absolute; top: 0; left: 0; z-index: 90; width: 4px; border-radius: 2px; background: rgba(255, 255, 255, 0.34); opacity: 0; pointer-events: none; transition: opacity 260ms var(--ease); }
.scroll-thumb.is-fixed { position: fixed; z-index: 1000; }
.scroll-thumb.on-light { background: rgba(8, 27, 33, 0.3); }
.scroll-thumb.is-on { opacity: 1; transition-duration: 80ms; }
@media (prefers-reduced-motion: reduce) { .scroll-thumb { transition: none; } }

/* Ya no tienes acceso a un proyecto (common/access.js): un modal de papel, con un candado. */
.access-lost { width: min(460px, calc(100vw - 32px)); }
.access-lost form { display: grid; gap: 10px; }
.access-lost-mark { display: grid; place-items: center; width: 44px; height: 44px; margin-bottom: 4px; color: #08718b; background: rgba(8, 113, 139, 0.1); border-radius: 50%; }
.access-lost h2 { margin: 0; text-wrap: balance; }
.access-lost p { margin: 0; line-height: 1.5; }
.access-lost .dialog-actions { margin-top: 8px; }

/* Un aviso que espera algo (kind 'loading'): con su cargando delante. */
.toast.loading .toast-title { display: flex; align-items: center; gap: 8px; }
.toast.loading .toast-title::before { content: ''; flex: none; width: 12px; height: 12px; border: 1.6px solid rgba(255, 255, 255, 0.28); border-top-color: #fff; border-radius: 50%; animation: toast-spin 0.8s linear infinite; }
@keyframes toast-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .toast.loading .toast-title::before { animation-duration: 2.4s; } }

/* El código de seis cifras en seis casillas (js/common/code-input.js). Cada página ajusta los colores con sus variables. */
.code-boxes { --code-bg: #0c0f16; --code-border: rgba(255, 255, 255, 0.14); --code-text: #fff; --code-focus: #56cce6; --code-radius: 12px;
	display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 8px; max-width: 360px; }
.code-cell { box-sizing: border-box; width: 100%; min-width: 0; height: 56px; padding: 0; font: 700 24px/1 var(--font); font-variant-numeric: tabular-nums; text-align: center; color: var(--code-text); caret-color: var(--code-focus);
	background: var(--code-bg); border: 1.5px solid var(--code-border); border-radius: var(--code-radius); }
.code-cell:focus { outline: none; border-color: var(--code-focus); box-shadow: 0 0 0 4px color-mix(in srgb, var(--code-focus) 22%, transparent); }
.code-boxes.is-invalid .code-cell { border-color: #e94b3f; }
.code-boxes.is-invalid { animation: code-shake 0.32s ease; }
@keyframes code-shake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-5px); } 75% { transform: translateX(5px); } }
@media (prefers-reduced-motion: reduce) { .code-boxes.is-invalid { animation: none; } }
@media (max-width: 380px) { .code-cell { height: 48px; font-size: 20px; } .code-boxes { gap: 6px; } }
