DE INNOVACIÓN
DE SANTIAGO
Iniciar sesión
Accede con una cuenta de la Compañía. Volverás al servicio solicitado.
¿Necesitas una cuenta? Crear cuenta
Patrón canónico de tarjeta de acceso para cuenta, admin, usaia, firmas y documentos.
Primero el componente, después la variación de marca y finalmente su uso dentro de una página.
Accede con una cuenta de la Compañía. Volverás al servicio solicitado.
¿Necesitas una cuenta? Crear cuenta
Usa tu cuenta de la Compañía. Volverás al documento que ibas a firmar.
Accede con una cuenta de la Compañía. Volverás al servicio solicitado.
¿Necesitas una cuenta? Crear cuenta
<section class="ui-sample ui-auth-stage" data-auth-source="cis-auth-authentik" data-login-card="true"><div class="ui-auth-shell"><header class="ui-auth-brand"><svg class="ui-lockup__mark" viewBox="0 0 200 200" fill="none" stroke="currentColor" aria-hidden="true"><circle cx="100" cy="100" r="92" stroke-width="4"></circle><circle cx="100" cy="100" r="56" stroke-width="18"></circle></svg><strong>COMPAÑÍA<br>DE INNOVACIÓN<br>DE SANTIAGO</strong></header><div class="ui-auth-body"><h3>Iniciar sesión</h3><p>Accede con una cuenta de la Compañía. Volverás al servicio solicitado.</p><div class="ui-auth-providers"><button class="ui-provider-pill" type="button"><span class="ui-provider-mark ui-provider-mark--google" aria-hidden="true"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="#4285f4" d="M21.6 12.2c0-.7-.1-1.4-.2-2H12v3.9h5.4a4.6 4.6 0 0 1-2 3v2.6h3.3c1.9-1.8 2.9-4.4 2.9-7.5Z"></path><path fill="#34a853" d="M12 22c2.7 0 5-.9 6.7-2.3l-3.3-2.6c-.9.6-2.1 1-3.4 1a5.9 5.9 0 0 1-5.5-4.1H3.1v2.6A10 10 0 0 0 12 22Z"></path><path fill="#fbbc05" d="M6.5 14a6 6 0 0 1 0-3.9V7.4H3.1a10 10 0 0 0 0 9.2L6.5 14Z"></path><path fill="#ea4335" d="M12 6a5.4 5.4 0 0 1 3.8 1.5l2.9-2.9A9.7 9.7 0 0 0 12 2a10 10 0 0 0-8.9 5.4l3.4 2.7A5.9 5.9 0 0 1 12 6Z"></path></svg></span><span>Continuar con Google</span></button><button class="ui-provider-pill" type="button"><span class="ui-provider-mark ui-provider-mark--microsoft" aria-hidden="true"><i></i><i></i><i></i><i></i></span><span>Continuar con Microsoft</span></button></div><div class="ui-auth-separator"><span>o usa tu correo</span></div><label for="auth-login-email-0">Correo electrónico</label><input class="input" id="auth-login-email-0" type="email" autocomplete="email"><button class="btn btn--primary" type="button">Continuar</button><a class="ui-auth-recovery" href="#recuperar">¿Problemas con tu cuenta?</a><p class="ui-auth-enroll">¿Necesitas una cuenta? <a href="#registro">Crear cuenta</a></p></div><footer>Compañía de Innovación de Santiago</footer></div></section>Cada cambio visible declara su autoridad; lo que permanece canónico no se vuelve a inventar en el producto.
Accede con una cuenta de la Compañía. Volverás al servicio solicitado.
¿Necesitas una cuenta? Crear cuenta
Usa tu cuenta de la Compañía. Volverás al documento que ibas a firmar.
Compara la propuesta con cortes reales del repositorio. La ausencia de una muestra se declara y nunca se reconstruye de memoria.
Preparando comparación histórica…
La comparación convierte una regla abstracta en una diferencia visible y verificable.
Accede con una cuenta de la Compañía. Volverás al servicio solicitado.
¿Necesitas una cuenta? Crear cuenta
La misma anatomía debe conservar lectura, foco y acciones sin cortar contenido ni crear scroll horizontal en la página.
Accede con una cuenta de la Compañía. Volverás al servicio solicitado.
¿Necesitas una cuenta? Crear cuenta
Usa tu cuenta de la Compañía. Volverás al documento que ibas a firmar.
| Dimensión | Contrato |
|---|---|
| Propietario canónico | Sistema de diseño CIS y cis-auth · core/core-style |
| Consumidores | Cuenta, Admin, usaia, Firmas y Documentos |
| Dependencias | HTML nativo, validación de servidor |
| Estado | candidato |
Patrón propuesto. 0 implementaciones observadas en 0 repositorios.
La observación demuestra uso existente; la aceptación canónica sigue dependiendo de esta ficha y de su propietario.
| Dato | Resultado |
|---|---|
| Clasificación | Patrón propuesto |
| Implementaciones | 0 implementaciones observadas |
| Repositorios | Ningún repositorio observado |
| Snapshot | kit/componentes/componentes-observados.json |
El inventario conserva repositorio, archivo fuente y criterio de asociación. Observar una implementación no la convierte automáticamente en canónica.
| Estado requerido |
|---|
| vacío |
| completo |
| inválido |
| disabled |
Copia el bloque completo; después cambia contenido y destinos, no su anatomía.
<section class="ui-sample ui-auth-stage" data-auth-source="cis-auth-authentik" data-login-card="true"><div class="ui-auth-shell"><header class="ui-auth-brand"><svg class="ui-lockup__mark" viewBox="0 0 200 200" fill="none" stroke="currentColor" aria-hidden="true"><circle cx="100" cy="100" r="92" stroke-width="4"></circle><circle cx="100" cy="100" r="56" stroke-width="18"></circle></svg><strong>COMPAÑÍA<br>DE INNOVACIÓN<br>DE SANTIAGO</strong></header><div class="ui-auth-body"><h3>Iniciar sesión</h3><p>Accede con una cuenta de la Compañía. Volverás al servicio solicitado.</p><div class="ui-auth-providers"><button class="ui-provider-pill" type="button"><span class="ui-provider-mark ui-provider-mark--google" aria-hidden="true"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="#4285f4" d="M21.6 12.2c0-.7-.1-1.4-.2-2H12v3.9h5.4a4.6 4.6 0 0 1-2 3v2.6h3.3c1.9-1.8 2.9-4.4 2.9-7.5Z"></path><path fill="#34a853" d="M12 22c2.7 0 5-.9 6.7-2.3l-3.3-2.6c-.9.6-2.1 1-3.4 1a5.9 5.9 0 0 1-5.5-4.1H3.1v2.6A10 10 0 0 0 12 22Z"></path><path fill="#fbbc05" d="M6.5 14a6 6 0 0 1 0-3.9V7.4H3.1a10 10 0 0 0 0 9.2L6.5 14Z"></path><path fill="#ea4335" d="M12 6a5.4 5.4 0 0 1 3.8 1.5l2.9-2.9A9.7 9.7 0 0 0 12 2a10 10 0 0 0-8.9 5.4l3.4 2.7A5.9 5.9 0 0 1 12 6Z"></path></svg></span><span>Continuar con Google</span></button><button class="ui-provider-pill" type="button"><span class="ui-provider-mark ui-provider-mark--microsoft" aria-hidden="true"><i></i><i></i><i></i><i></i></span><span>Continuar con Microsoft</span></button></div><div class="ui-auth-separator"><span>o usa tu correo</span></div><label for="auth-login-email-0">Correo electrónico</label><input class="input" id="auth-login-email-0" type="email" autocomplete="email"><button class="btn btn--primary" type="button">Continuar</button><a class="ui-auth-recovery" href="#recuperar">¿Problemas con tu cuenta?</a><p class="ui-auth-enroll">¿Necesitas una cuenta? <a href="#registro">Crear cuenta</a></p></div><footer>Compañía de Innovación de Santiago</footer></div></section>Copia el bloque completo; después cambia contenido y destinos, no su anatomía.
<section class="ui-sample ui-auth-stage border border-slate-300 bg-white p-4 text-slate-950 grid gap-3" data-auth-source="cis-auth-authentik" data-login-card="true"><div class="ui-auth-shell"><header class="ui-auth-brand flex flex-wrap items-center justify-between gap-3"><svg class="ui-lockup__mark h-auto w-full" viewBox="0 0 200 200" fill="none" stroke="currentColor" aria-hidden="true"><circle cx="100" cy="100" r="92" stroke-width="4"></circle><circle cx="100" cy="100" r="56" stroke-width="18"></circle></svg><strong>COMPAÑÍA<br>DE INNOVACIÓN<br>DE SANTIAGO</strong></header><div class="ui-auth-body"><h3>Iniciar sesión</h3><p>Accede con una cuenta de la Compañía. Volverás al servicio solicitado.</p><div class="ui-auth-providers"><button class="ui-provider-pill border border-slate-950 px-3 py-2 focus-visible:outline-2 focus-visible:outline-offset-2 disabled:cursor-not-allowed" type="button"><span class="ui-provider-mark ui-provider-mark--google" aria-hidden="true"><svg class="h-auto w-full" viewBox="0 0 24 24" aria-hidden="true"><path fill="#4285f4" d="M21.6 12.2c0-.7-.1-1.4-.2-2H12v3.9h5.4a4.6 4.6 0 0 1-2 3v2.6h3.3c1.9-1.8 2.9-4.4 2.9-7.5Z"></path><path fill="#34a853" d="M12 22c2.7 0 5-.9 6.7-2.3l-3.3-2.6c-.9.6-2.1 1-3.4 1a5.9 5.9 0 0 1-5.5-4.1H3.1v2.6A10 10 0 0 0 12 22Z"></path><path fill="#fbbc05" d="M6.5 14a6 6 0 0 1 0-3.9V7.4H3.1a10 10 0 0 0 0 9.2L6.5 14Z"></path><path fill="#ea4335" d="M12 6a5.4 5.4 0 0 1 3.8 1.5l2.9-2.9A9.7 9.7 0 0 0 12 2a10 10 0 0 0-8.9 5.4l3.4 2.7A5.9 5.9 0 0 1 12 6Z"></path></svg></span><span>Continuar con Google</span></button><button class="ui-provider-pill border border-slate-950 px-3 py-2 focus-visible:outline-2 focus-visible:outline-offset-2 disabled:cursor-not-allowed" type="button"><span class="ui-provider-mark ui-provider-mark--microsoft" aria-hidden="true"><i></i><i></i><i></i><i></i></span><span>Continuar con Microsoft</span></button></div><div class="ui-auth-separator"><span>o usa tu correo</span></div><label for="auth-login-email-0">Correo electrónico</label><input class="input border border-slate-400 bg-white px-3 py-2 focus-visible:outline-2 focus-visible:outline-offset-2" id="auth-login-email-0" type="email" autocomplete="email"><button class="btn btn--primary border border-slate-950 px-3 py-2 focus-visible:outline-2 focus-visible:outline-offset-2 disabled:cursor-not-allowed" type="button">Continuar</button><a class="ui-auth-recovery underline underline-offset-4" href="#recuperar">¿Problemas con tu cuenta?</a><p class="ui-auth-enroll">¿Necesitas una cuenta? <a class="underline underline-offset-4" href="#registro">Crear cuenta</a></p></div><footer class="flex flex-wrap items-center justify-between gap-3">Compañía de Innovación de Santiago</footer></div></section>Copia el bloque completo; después cambia contenido y destinos, no su anatomía.
import type { ChangeEventHandler, MouseEventHandler } from "react";
const NAME_LINES = ["COMPAÑÍA", "DE INNOVACIÓN", "DE SANTIAGO"];
const PROVIDER_LABELS = { google: "Continuar con Google", microsoft: "Continuar con Microsoft" } as const;
export interface LoginCardProvider {
/** Proveedor de identidad; define la marca. */
provider: "google" | "microsoft";
/** Texto del botón; por defecto, «Continuar con» y el nombre del proveedor. */
label?: string;
}
export interface LoginCardProps {
/** Nombre de la Compañía en la cabecera, una línea por elemento. */
nameLines?: string[];
/** URL del símbolo de la marca (SVG o PNG cuadrado); reemplaza el aro de la Compañía cuando la tarjeta es de otra marca. Va junto con `nameLines`. */
markSrc?: string;
title?: string;
/** Texto bajo el título: con qué cuenta se entra y adónde se vuelve. */
description?: string;
/** Botones de proveedores externos, en orden. */
providers?: LoginCardProvider[];
/** Se llama al pulsar el botón de un proveedor. */
onProviderClick?: (provider: LoginCardProvider, index: number) => void;
/** Texto del separador entre los proveedores y el correo. */
separatorLabel?: string;
/** Etiqueta visible del campo de correo. */
label?: string;
/** Id del campo de correo. Usa uno distinto por tarjeta en la página. */
id?: string;
name?: string;
/** Correo inicial de un campo no controlado. */
defaultValue?: string;
/** Correo de un campo controlado; va junto con `onChange`. */
value?: string;
onChange?: ChangeEventHandler<HTMLInputElement>;
/** Texto del botón que sigue con el correo. */
continueLabel?: string;
onContinue?: MouseEventHandler<HTMLButtonElement>;
/** Texto del enlace de recuperación de acceso. */
recoveryLabel?: string;
recoveryHref?: string;
/** Pregunta antes del enlace para crear cuenta. */
registerText?: string;
registerLabel?: string;
registerHref?: string;
/** Línea al pie de la tarjeta: titular del servicio de acceso. */
footer?: string;
className?: string;
}
/**
* Tarjeta de inicio de sesión con marca, proveedores externos, acceso por correo, recuperación y creación de cuenta; se usa como pantalla de acceso de un servicio de la Compañía.
*
* Las marcas de los proveedores y el símbolo de la cabecera son decorativos (`aria-hidden` o `alt` vacío); el nombre accesible de cada botón es su texto. Para otra marca, cambia `nameLines` y `markSrc` juntos.
*
* @example <LoginCard id="acceso-correo" onProviderClick={entrarCon} onContinue={seguirConCorreo} recoveryHref="/auth/recuperar" registerHref="/auth/registro" />
* @example <LoginCard nameLines={["FIRMAS Y", "DOCUMENTOS"]} markSrc="/marca/firmas-simbolo.svg" providers={[{ provider: "google" }]} registerLabel="" />
*/
export function LoginCard({
nameLines = NAME_LINES,
markSrc,
title = "Iniciar sesión",
description = "Accede con una cuenta de la Compañía. Volverás al servicio solicitado.",
providers = [{ provider: "google" }, { provider: "microsoft" }],
onProviderClick,
separatorLabel = "o usa tu correo",
label = "Correo electrónico",
id = "auth-login-email-0",
name,
defaultValue,
value,
onChange,
continueLabel = "Continuar",
onContinue,
recoveryLabel = "¿Problemas con tu cuenta?",
recoveryHref = "#recuperar",
registerText = "¿Necesitas una cuenta?",
registerLabel = "Crear cuenta",
registerHref = "#registro",
footer = "Compañía de Innovación de Santiago",
className,
}: LoginCardProps) {
const controlado = value !== undefined && onChange !== undefined;
return (
<section className={["ui-auth-stage", className].filter(Boolean).join(" ")} data-auth-source="cis-auth-authentik" data-login-card>
<div className="ui-auth-shell">
<header className="ui-auth-brand">
{markSrc ? (
<img className="ui-lockup__mark" src={markSrc} alt="" />
) : (
<svg className="ui-lockup__mark" viewBox="0 0 200 200" fill="none" stroke="currentColor" aria-hidden="true"><circle cx="100" cy="100" r="92" strokeWidth="4"></circle><circle cx="100" cy="100" r="56" strokeWidth="18"></circle></svg>
)}
{nameLines.length ? <strong>{nameLines.flatMap((linea, i) => (i ? [<br key={i} />, linea] : [linea]))}</strong> : null}
</header>
<div className="ui-auth-body">
{title ? <h3>{title}</h3> : null}
{description ? <p>{description}</p> : null}
{providers.length ? (
<div className="ui-auth-providers">
{providers.map((item, i) => (
<button key={`${i}-${item.provider}`} className="ui-provider-pill" type="button" onClick={onProviderClick ? () => onProviderClick(item, i) : undefined}>
<span className={`ui-provider-mark ui-provider-mark--${item.provider}`} aria-hidden="true">
{item.provider === "google" ? (
<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="#4285f4" d="M21.6 12.2c0-.7-.1-1.4-.2-2H12v3.9h5.4a4.6 4.6 0 0 1-2 3v2.6h3.3c1.9-1.8 2.9-4.4 2.9-7.5Z"></path><path fill="#34a853" d="M12 22c2.7 0 5-.9 6.7-2.3l-3.3-2.6c-.9.6-2.1 1-3.4 1a5.9 5.9 0 0 1-5.5-4.1H3.1v2.6A10 10 0 0 0 12 22Z"></path><path fill="#fbbc05" d="M6.5 14a6 6 0 0 1 0-3.9V7.4H3.1a10 10 0 0 0 0 9.2L6.5 14Z"></path><path fill="#ea4335" d="M12 6a5.4 5.4 0 0 1 3.8 1.5l2.9-2.9A9.7 9.7 0 0 0 12 2a10 10 0 0 0-8.9 5.4l3.4 2.7A5.9 5.9 0 0 1 12 6Z"></path></svg>
) : (
<><i></i><i></i><i></i><i></i></>
)}
</span>
<span>{item.label ?? PROVIDER_LABELS[item.provider]}</span>
</button>
))}
</div>
) : null}
{providers.length && separatorLabel ? <div className="ui-auth-separator"><span>{separatorLabel}</span></div> : null}
<label htmlFor={id}>{label}</label>
<input
className="input"
id={id}
name={name}
type="email"
autoComplete="email"
{...(controlado ? { value, onChange } : { defaultValue: value ?? defaultValue })}
/>
<button className="btn btn--primary" type="button" onClick={onContinue}>{continueLabel}</button>
{recoveryLabel ? <a className="ui-auth-recovery" href={recoveryHref}>{recoveryLabel}</a> : null}
{registerLabel ? (
<p className="ui-auth-enroll">{registerText ? `${registerText} ` : null}<a href={registerHref}>{registerLabel}</a></p>
) : null}
</div>
{footer ? <footer>{footer}</footer> : null}
</div>
</section>
);
}