cis-style · hub

kit v9 · f417275 · base/chrome.css + chrome.js

Chrome del kit

La barra, el pie y el bloque de sesión que comparten todos los sitios del grupo. Todo lo que ves acá carga las hojas reales del CDN por versión fijada: si un ejemplo se ve mal en esta página, se ve mal en producción.

El toggle de tema de los ejemplos funciona de verdad: pruébalo y toda esta página cambia entre claro y oscuro.

Qué es el chrome

El chrome es el esqueleto único del grupo: navbar (.gr-nav), footer (.gr-footer) y bloque de sesión (.gr-login), con prefijo gr- para distinguirlo de los componentes de cada sitio. Lo define base/chrome.css y lo acompaña un único script, chrome.js.

REGLA · El chrome se genera estático en build o deploy: el HTML lo emite el sitio o su backend. Está prohibido montarlo como web component de runtime. El único JavaScript permitido es chrome.js (toggle claro/oscuro y hamburguesa, con guard one-shot). Fuente: cabecera de base/chrome.css.

REGLA H12 · Todo consumidor fija la versión que carga: la URL lleva /v9/<digest>/ explícito, nunca una ruta genérica. Fuente: cis-modelo/modelo/reglas.py y core/CONTRACTS.md.

Integración completa en 7 líneas

Un sitio nuevo integra todo el sistema con seis hojas y un script. El orden importa: fuentes, tokens base, chrome, componentes y al final los tokens de la marca (que sobreescriben el acento). chrome.js vive en la raíz del kit versionado, no dentro de base/.

Pega esto en el <head> y tu sitio ya habla el idioma del grupo. Cambia cis por la marca que corresponda (cds, cochid, ...).

<link rel=stylesheet href="https://style.innovacionsantiago.cl/v9/f417275cbb1c390a6b158f2f6574db1b36e2a6cc61e734029530ef90b9d1dd77/fonts/css/ibm-plex-sans.css">
<link rel=stylesheet href="https://style.innovacionsantiago.cl/v9/f417275cbb1c390a6b158f2f6574db1b36e2a6cc61e734029530ef90b9d1dd77/fonts/css/jetbrains-mono.css">
<link rel=stylesheet href="https://style.innovacionsantiago.cl/v9/f417275cbb1c390a6b158f2f6574db1b36e2a6cc61e734029530ef90b9d1dd77/base/tokens.css">
<link rel=stylesheet href="https://style.innovacionsantiago.cl/v9/f417275cbb1c390a6b158f2f6574db1b36e2a6cc61e734029530ef90b9d1dd77/base/chrome.css">
<link rel=stylesheet href="https://style.innovacionsantiago.cl/v9/f417275cbb1c390a6b158f2f6574db1b36e2a6cc61e734029530ef90b9d1dd77/base/components.css">
<link rel=stylesheet href="https://style.innovacionsantiago.cl/v9/f417275cbb1c390a6b158f2f6574db1b36e2a6cc61e734029530ef90b9d1dd77/brands/cis/tokens.css">
<script defer src="https://style.innovacionsantiago.cl/v9/f417275cbb1c390a6b158f2f6574db1b36e2a6cc61e734029530ef90b9d1dd77/chrome.js"></script>

REGLA H14 · Las fuentes (IBM Plex Sans y JetBrains Mono) las sirve el propio grupo desde /v9/<digest>/fonts/. Nunca Google Fonts, nunca Inter ni Roboto. Fuente: CANON.md y ADR-021.

La barra del grupo: gr-nav

Sticky arriba, fondo del papel con blur, borde inferior de un píxel. Cuatro zonas en una grilla: marca, hamburguesa (solo móvil), links agrupados con separador vertical y acciones a la derecha. El link activo lleva .is-active (subrayado de dos píxeles en el acento). Bajo 860 px la hamburguesa despliega los links en columna.

<header class="gr-nav">
  <div class="gr-nav__inner">
    <a class="gr-nav__brand" href="/">
      <svg width="32" height="32" viewBox="0 0 200 200" fill="none" stroke="currentColor"><circle cx="100" cy="100" r="92" stroke-width="4"/><circle cx="100" cy="100" r="56" stroke-width="18"/></svg>
      <span class="gr-nav__wordmark"><span>Compañía</span><span>de Innovación</span><span>de Santiago</span></span>
    </a>
    <button class="gr-nav__toggle" aria-label="Abrir menú" aria-expanded="false"><span></span><span></span><span></span></button>
    <nav class="gr-nav__links" aria-label="Navegación principal">
      <div class="gr-nav__group">
        <a class="gr-nav__link is-active" href="/">Inicio</a>
        <a class="gr-nav__link" href="/productos">Productos</a>
      </div>
      <div class="gr-nav__group">
        <a class="gr-nav__link" href="/firmas">Firmas y Documentos</a>
        <a class="gr-nav__link" href="/atlas">Atlas</a>
      </div>
      <div class="gr-nav__group">
        <a class="gr-nav__link" href="/docs">Docs</a>
        <a class="gr-nav__link" href="/estado">Estado</a>
      </div>
    </nav>
    <div class="gr-nav__actions">
      <button class="gr-nav__theme" data-theme-toggle aria-label="Cambiar tema">
        <svg class="icon-sun" ...></svg>
        <svg class="icon-moon" ...></svg>
      </button>
      <div class="gr-login" data-state="anon">
        <a class="gr-login__enter" href="/entrar">Iniciar sesión</a>
      </div>
    </div>
  </div>
</header>

NOTA · En esta galería solo corre el toggle de tema. La hamburguesa, el cierre con Escape y el resto del comportamiento los da chrome.js, que un sitio real carga con la séptima línea de la integración.

Detalles que fija la hoja: los links usan --fs-small con peso 500; cada .gr-nav__group se separa del siguiente con un borde vertical de un píxel; el botón de tema es cuadrado y sin radio (la geometría de la casa es recta); los CTA usan --radius-ctl. Nada de sombras: la jerarquía la hacen los bordes.

Lockups de marca por sociedad

El mark va siempre en stroke: currentColor (nunca fill fijo) y el wordmark tiene tres variantes según la sociedad. Los tres marks canónicos salen de LOGOS-CANONICOS.md; inventar o regenerar logos viola la regla H15.

Compañíade Innovaciónde Santiago
Círculode Santiago
Compañía Chilenade Inteligenciade Datos
cochiddatos
<!-- CIS: anillos concéntricos (r92 sw4 + r56 sw18) + wordmark 3 líneas uppercase 800 -->
<svg width="32" height="32" viewBox="0 0 200 200" fill="none" stroke="currentColor"><circle cx="100" cy="100" r="92" stroke-width="4"/><circle cx="100" cy="100" r="56" stroke-width="18"/></svg>
<span class="gr-nav__wordmark"><span>Compañía</span><span>de Innovación</span><span>de Santiago</span></span>

<!-- CDS: UN círculo de contorno sw2 (nunca disco relleno) + wordmark --lg 2 líneas -->
<svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/></svg>
<span class="gr-nav__wordmark gr-nav__wordmark--lg"><span>Círculo</span><span>de Santiago</span></span>

<!-- cochid primario: cuadrado en el azul de la marca + wordmark apilado 3 líneas -->
<svg width="28" height="28" viewBox="0 0 24 24"><rect x="2" y="2" width="20" height="20" rx="1" style="fill:var(--accent)"/></svg>
<span class="gr-nav__wordmark"><span>Compañía Chilena</span><span>de Inteligencia</span><span>de Datos</span></span>

<!-- cochid secundario (contextos compactos): wordmark tipográfico mono -->
<span class="gr-nav__wordmark gr-nav__wordmark--mono">cochid<span class="gr-nav__sub">datos</span></span>

NOTA · Esta galería carga los tokens de CIS, así que el cuadrado cochid se pinta con el acento navy de CIS. En un sitio cochid, brands/cochid/tokens.css vuelve ese mismo var(--accent) azul cochid. El lockup mono es la forma secundaria para contextos compactos; el primario es cuadrado + wordmark apilado. Fuente: comentarios de base/chrome.css y brands/cochid/tokens.css.

Tamaños canónicos del mark CIS: 32 px en la barra, 34 px en la marca del pie. El wordmark base usa --fs-micro, peso 800 y mayúsculas; la variante --lg (CDS) sube a 16 px sin mayúsculas; la variante --mono pasa a JetBrains Mono en fila, con el subtítulo en el acento vía .gr-nav__sub.

Sesión y CTAs: gr-login

El bloque de sesión vive en .gr-nav__actions. Su estado (anónimo o autenticado) se decide en el servidor o en el build: cero JavaScript de sesión en el cliente. El atributo data-state documenta qué variante se emitió.

<!-- Variante anónima: píldora de entrada -->
<div class="gr-login" data-state="anon">
  <a class="gr-login__enter" href="/entrar">Iniciar sesión</a>
</div>

<!-- Variante autenticada: punto de acento + nombre (máx 14ch, con elipsis) + salida -->
<div class="gr-login" data-state="auth">
  <a class="gr-login__user" href="/cuenta"><span class="gr-login__dot"></span><span class="gr-login__name">martin</span></a>
  <a class="gr-login__exit" href="/salir">Salir</a>
</div>

Cuando el sitio vende cuentas, la barra usa CTAs en vez de la píldora: una primaria (tinta sobre papel invertido) y una secundaria fantasma. En móvil la secundaria se oculta sola.

<a class="gr-nav__cta gr-nav__cta--primary" href="/crear-cuenta">Crear cuenta</a>
<a class="gr-nav__cta gr-nav__cta--secondary" href="/entrar">Iniciar sesión</a>

REGLA H19 · El login real siempre es cis-auth por OIDC con core-auth-lib. El chrome solo pinta el estado que el backend ya decidió; ningún sitio implementa emisión de token propia. Fuente: CANON.md y cis-modelo/modelo/reglas.py.

Toggle claro/oscuro con data-theme

El tema vive en un solo lugar: el atributo data-theme de <html>. Tres estados posibles:

EstadoQuién lo poneEfecto
data-theme="light"el HTML emitido, o chrome.jspaleta clara fija, ignora el sistema
data-theme="dark"chrome.js tras el clickpaleta oscura fija
sin atributochrome.js cuando no hay preferencia guardadasigue al sistema vía prefers-color-scheme

Las variables cambian solas: base/tokens.css define la paleta clara en :root, la oscura en :root[data-theme="dark"] y la oscura automática en :root:not([data-theme="light"]) dentro del media query. Por eso ningún componente necesita saber en qué tema está.

Haz click: toda la página cambia de tema y la elección persiste en localStorage.
<button class="gr-nav__theme" data-theme-toggle aria-label="Cambiar tema">
  <svg class="icon-sun" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">...</svg>
  <svg class="icon-moon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">...</svg>
</button>

PATRÓN · El botón emite ambos íconos, sol y luna, y el CSS esconde el que no toca según data-theme (y según prefers-color-scheme cuando no hay override). Así el toggle pinta bien incluso antes de que cargue el script. Fuente: base/chrome.css, bloque del .gr-nav__theme.

chrome.js: el único JS del chrome

Un IIFE sin dependencias, cargado con defer desde la raíz del kit versionado. Hace exactamente cuatro cosas:

ComportamientoCómo
Restaura el tema guardadolee localStorage["group-theme"]; si hay dark o light lo estampa en data-theme; si el storage está bloqueado, cae a claro sin romper
Alterna el temaclick en cualquier [data-theme-toggle] invierte el tema, lo persiste y marca aria-pressed en todos los toggles de la página
Abre y cierra la hamburguesa.gr-nav__toggle alterna .is-open en .gr-nav__links y sincroniza aria-expanded
Cierra el menú soloal hacer click en un link, al presionar Escape (y devuelve el foco al botón) y al pasar de 860 px de ancho

El corazón del script, tal como está publicado en el CDN:

const applyTheme = (theme) => {
  if (theme === "dark" || theme === "light") {
    root.setAttribute("data-theme", theme);
  } else {
    root.removeAttribute("data-theme");
  }
  document.querySelectorAll("[data-theme-toggle]").forEach((button) => {
    button.setAttribute("aria-pressed", theme === "dark" ? "true" : "false");
  });
};

REGLA · Nada más de JavaScript en el chrome. La historia detrás: un navbar montado como web component de runtime congeló el browser con un bucle infinito de eventos. El chrome estático con un script one-shot es la respuesta a ese incidente. Fuente: cabecera de base/chrome.css.

El pie del grupo: gr-footer

Cuatro franjas de arriba hacia abajo: marca con tagline mono, grilla de cuatro columnas, línea de vinculación societaria y base legal con los dominios del grupo. Todo separado por bordes de un píxel; el borde superior del pie es el fuerte (--line-strong).

<footer class="gr-footer">
  <div class="gr-footer__top">
    <div class="gr-footer__brand">
      <svg width="34" height="34" ...mark de la marca...></svg>
      <div>
        <div class="gr-footer__brand-name">Compañía de Innovación de Santiago</div>
        <div class="gr-footer__brand-tag">software e infraestructura del grupo</div>
      </div>
    </div>
    <div class="gr-footer__grid">
      <section class="gr-footer__col">
        <h4>Empresa</h4>
        <ul>
          <li><a href="/quienes-somos">Quiénes somos</a></li>
          <li><a href="/firmas">Firmas y Documentos</a><span class="gr-footer__sub">docs.circulodesantiago.cl</span></li>
        </ul>
      </section>
      <!-- x4 columnas: Empresa / Productos / Recursos / Sitios del grupo -->
    </div>
  </div>
  <div class="gr-footer__attrib">...vinculación societaria, ver abajo...</div>
  <div class="gr-footer__base">
    <div class="gr-footer__base-inner">
      <span>© 2026 Compañía de Innovación de Santiago SpA · <a href="/privacidad">Privacidad</a></span>
      <span class="gr-footer__sites">innovacionsantiago.cl · circulodesantiago.cl · cochid.cl</span>
    </div>
  </div>
</footer>

Piezas con regla propia: los h4 de columna van en mono, mayúsculas y --fs-mono-label; el sublabel .gr-footer__sub anota el dominio bajo un link (patrón de los programas CDS); .gr-footer__sites lista los dominios del grupo en mono chico. La base legal es siempre estática, server-first.

Vinculación societaria en el pie

Quién opera y quién es dueño no coinciden, y el pie lo dice con tres formas distintas según el sitio. La forma vigente para sitios CIS y cochid es la línea única v7.1 que viste en el ejemplo vivo de arriba.

Línea única v7.1 (sitios CIS y cochid)

<div class="gr-footer__attrib">
  <div class="gr-footer__attrib-inner gr-footer__attrib-inner--line">
    <span class="gr-footer__attrib-eyebrow">Operado por</span>
    <span class="gr-footer__attrib-name">Compañía Chilena de Inteligencia de Datos SpA</span>
    <span class="gr-footer__attrib-sep">·</span>
    <span>una empresa de</span>
    <svg class="gr-footer__attrib-mark" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/></svg>
    <a class="gr-footer__attrib-link" href="https://circulodesantiago.cl"><span class="gr-footer__attrib-name">Círculo de Santiago</span></a>
  </div>
</div>

Variante A apilada (discreta, producto o filial hacia la matriz)

<div class="gr-footer__attrib">
  <div class="gr-footer__attrib-inner">
    <span class="gr-footer__attrib-eyebrow">Una empresa de</span>
    <a class="gr-footer__attrib-link" href="https://circulodesantiago.cl">
      <svg width="16" height="16" ...mark CDS...></svg>
      <span class="gr-footer__attrib-name">Círculo de Santiago SpA</span>
    </a>
  </div>
</div>

<!-- Espejo producto → CIS: el nombre sube de peso con --lg -->
<span class="gr-footer__attrib-name gr-footer__attrib-name--lg">Compañía de Innovación de Santiago SpA</span>

Variante B prominente (matriz hacia la operadora)

<a class="gr-footer__sibling" href="https://innovacionsantiago.cl">
  <svg width="30" height="30" ...mark CIS...></svg>
  <span class="gr-footer__sibling-text">
    <span class="gr-footer__sibling-eyebrow">Operado por</span>
    <span class="gr-footer__sibling-name">Compañía de Innovación de Santiago</span>
  </span>
  <span class="gr-footer__sibling-arrow">→</span>
</a>

REGLA · En la variante A la matriz va con "SpA"; en la variante B la operadora va sin "SpA" y la fila entera es clickeable. Los sitios propios de la matriz dicen "Círculo de Santiago SpA · RUT 78.372.913-K" a secas: una sociedad nunca es "una empresa de" sí misma. El mark CDS de la línea única va inline (.gr-footer__attrib-mark). Fuente: comentarios v7.1 de base/chrome.css (feedback de Martín, 2026-07-31) y core/core-style/ESTRUCTURA.md.

Fuentes

Estructura y clases de nav, footer y login: v9/f417275.../base/chrome.css (cabecera y comentarios inline) · comportamiento del script: v9/f417275.../chrome.js (leído del CDN, IIFE publicado) · data-theme y paletas: v9/f417275.../base/tokens.css · acentos por marca: v9/f417275.../brands/{cis,cds,cochid}/tokens.css · marks canónicos: cis-style/brands/LOGOS-CANONICOS.md · sociedades, marcas y quién opera qué: core/core-style/ESTRUCTURA.md · reglas H12, H14, H15 y H19: cis-modelo/modelo/reglas.py y CANON.md · norma de escritura de esta página: core/prosa/NORMA.md.