:root {
  /* Named color values */
  --lch-black: 0% 0 0;
  --lch-white: 100% 0 0;
  --lch-gray: 96% 0.005 96;
  --lch-gray-dark: 92% 0.005 96;
  --lch-gray-darker: 75% 0.005 96;
  /* El acento, en tres piezas.
     Antes era una terna entera escrita en `--lch-blue` como estilo en linea, y
     eso rompia dos cosas. Una: `-light` y `-dark` llevaban el tono a mano
     (255), asi que elegir Rojo dejaba el enlace y el foco en rojo mientras el
     FONDO de la sala abierta y las burbujas propias seguian azules -- dos
     acentos peleados en la misma fila. Y dos: un estilo en linea gana a
     `.theme-dark`, asi que el tema oscuro perdia su azul aclarado y el enlace
     caia a ~4,1:1 sobre negro.
     En tres piezas, cada tema puede quedarse con lo que le toca: el tono viaja
     a las tres variantes, y la luminosidad la sube el tema oscuro por su
     cuenta. Medido con canvas sobre los dos fondos, los seis acentos pasan AA
     en claro (4,62:1 el peor, el verde azulado) y en oscuro el suelo es 7,34:1
     (el rojo). */
  --accent-l: 54%;
  --accent-c: 0.23;
  --accent-h: 255;

  --lch-blue: var(--accent-l) var(--accent-c) var(--accent-h);
  --lch-blue-light: 95% 0.03 var(--accent-h);
  --lch-blue-dark: 80% 0.08 var(--accent-h);
  --lch-orange: 70% 0.2 44;
  --lch-red: 51% 0.2 31;
  --lch-green: 65.59% 0.234 142.49;
  --lch-always-black: 0% 0 0;

  /* Cuanto se invierte un icono.
     Los <img> no heredan color, asi que la app los voltea con filter. Ese
     filtro estaba escrito nueve veces en nueve hojas, cada una con su propia
     media query: nueve sitios que consultar para saber que hace un icono, y
     ninguno capaz de responder a una preferencia que no fuera la del sistema.
     Ahora es un numero, y se decide aqui. */
  --icon-invert: 0;
  --icon-invert-reverse: 1;

  /* Lo que pinta el navegador tambien tiene que seguir al tema elegido.
     El <meta name="color-scheme"> del layout delega en el sistema, asi que con
     sistema en claro y tema Oscuro elegido quedaba una barra de scroll clara
     pegada a una columna negra, y los controles nativos y los desplegables en
     claro sobre papel negro. Al reves igual.
     De paso arregla en su raiz el texto de los <dialog>: el UA los pinta con
     `canvastext`, que atiende a esto y no a la clase de tema. */
  color-scheme: light;

  /* Grises con contraste suficiente para texto y para borde de campo.
     --color-border-darker (75% de luminosidad) se estaba usando como color de
     TEXTO en .txt-subtle y en el badge de version: 2,22:1 sobre el papel,
     cuando AA pide 4,5:1. Y como borde de input daba esos mismos 2,22:1
     frente a los 3:1 que pide el criterio 1.4.11.
     Van en tokens propios y no bajando el gris global, porque ese gris
     tambien pinta bordes decorativos que no necesitan estos minimos. */
  --lch-gray-text: 56% 0.005 96;
  --lch-gray-border-strong: 62% 0.005 96;

  /* El fondo de las burbujas.
     Vive aqui y no como literal dentro de .messages por dos razones: un valor
     suelto en una hoja ignora cualquier :root que ponga un admin en Custom
     Styles, y declararlo alli obligaba a una @media anidada que dejaba el
     resto del bloque sin aplicar en los navegadores que aun no soportan
     CSSNestedDeclarations. */
  --color-message-bubble: oklch(93% 0.005 96);

  /* La barra lateral y el rail tienen su propio color, independiente del
     papel de la conversacion: es lo que hace que la app se lea como Slack. La
     paleta por defecto es grafito, la neutra: sigue al tema, clara sobre claro
     y oscura sobre oscuro. Las demas se eligen en Preferencias y llegan como
     `data-palette` en <html>. Solo cambian estos tokens; la fila
     activa toma el acento, asi que las dos preferencias se combinan. */
  --sb-bg: oklch(96.5% 0.004 260);
  --sb-bg-rail: oklch(93% 0.005 260);
  --sb-text: oklch(28% 0.01 260);
  --sb-text-strong: oklch(12% 0.01 260);
  --sb-text-muted: oklch(50% 0.01 260);
  --sb-hover: oklch(0% 0 0 / 0.06);
  --sb-line: oklch(0% 0 0 / 0.1);
  --sb-line-strong: oklch(0% 0 0 / 0.25);
  --sb-active: oklch(var(--accent-l) var(--accent-c) var(--accent-h));
  --sb-active-text: oklch(100% 0 0);
  --sb-badge: oklch(58% 0.21 10);
  --sb-icon-invert: 0;

  /* Los valores oscuros, en dos sitios a proposito.
     La media query atiende a quien no ha elegido nada -- el sistema manda --
     y el `:not(.theme-light)` deja que una eleccion explicita le gane.
     La clase atiende a quien si eligio. CSS no permite reutilizar un bloque
     de declaraciones, asi que la unica alternativa a repetirlas seria que el
     tema no se pudiera elegir.

     El papel oscuro es una pizarra (20 %) y no negro puro: es el gris de la
     conversacion de Slack, y sobre el las filas iluminadas y los bordes se
     separan sin necesitar mas contraste del que hay. */
  @media (prefers-color-scheme: dark) {
    &:not(.theme-light) {
    --lch-black: 93% 0.004 260;
    --lch-white: 20% 0.006 260;
    --lch-gray: 26% 0.006 260;
    --lch-gray-dark: 31% 0.006 260;
    --lch-gray-darker: 46% 0.006 260;
    /* El aclarado del tema, +18,25 puntos, que es la distancia que ya habia
       entre el azul claro (54%) y el oscuro (72,25%). Asi el acento elegido
       llega tambien aqui sin traerse la luminosidad del papel blanco. */
    --lch-blue: calc(var(--accent-l) + 18.25%) var(--accent-c) var(--accent-h);
    --lch-blue-light: 30% 0.05 var(--accent-h);
    --lch-blue-dark: 44% 0.07 var(--accent-h);
    --lch-red: 73.8% 0.184 29.18;
    --lch-green: 75% 0.21 141.89;
    --lch-gray-text: 66% 0.005 260;
    --lch-gray-border-strong: 55% 0.005 260;
    --color-message-bubble: oklch(var(--lch-gray));
    --icon-invert: 1;
    --icon-invert-reverse: 0;
    color-scheme: dark;
    --sb-bg: oklch(17% 0.008 260);
    --sb-bg-rail: oklch(14% 0.008 260);
    --sb-text: oklch(86% 0.005 260);
    --sb-text-strong: oklch(100% 0 0);
    --sb-text-muted: oklch(66% 0.005 260);
    --sb-hover: oklch(100% 0 0 / 0.08);
    --sb-line: oklch(100% 0 0 / 0.12);
    --sb-line-strong: oklch(100% 0 0 / 0.28);
    --sb-icon-invert: 1;
    }
  }

  &.theme-dark {
    --lch-black: 93% 0.004 260;
    --lch-white: 20% 0.006 260;
    --lch-gray: 26% 0.006 260;
    --lch-gray-dark: 31% 0.006 260;
    --lch-gray-darker: 46% 0.006 260;
    --lch-blue: calc(var(--accent-l) + 18.25%) var(--accent-c) var(--accent-h);
    --lch-blue-light: 30% 0.05 var(--accent-h);
    --lch-blue-dark: 44% 0.07 var(--accent-h);
    --lch-red: 73.8% 0.184 29.18;
    --lch-green: 75% 0.21 141.89;
    --lch-gray-text: 66% 0.005 260;
    --lch-gray-border-strong: 55% 0.005 260;
    --color-message-bubble: oklch(var(--lch-gray));
    --icon-invert: 1;
    --icon-invert-reverse: 0;
    color-scheme: dark;
    --sb-bg: oklch(17% 0.008 260);
    --sb-bg-rail: oklch(14% 0.008 260);
    --sb-text: oklch(86% 0.005 260);
    --sb-text-strong: oklch(100% 0 0);
    --sb-text-muted: oklch(66% 0.005 260);
    --sb-hover: oklch(100% 0 0 / 0.08);
    --sb-line: oklch(100% 0 0 / 0.12);
    --sb-line-strong: oklch(100% 0 0 / 0.28);
    --sb-icon-invert: 1;
  }
}

/* Las abstracciones, en `:root` y en `.surface`.
   `#sidebar` y `#rail` las remapean a los tokens de la barra para que todo lo
   que hay dentro -- botones, campos, avatares -- se pinte sobre su color sin
   reescribir cada regla. Pero un <dialog> que vive en el DOM de la barra (el
   salto) hereda ese remapeo aunque flote en la capa superior: `.surface` le
   devuelve el papel de la conversacion. Declararlo en la propia caja gana a lo
   heredado, que es lo que hace falta. */
:root,
.surface {
  --color-negative: oklch(var(--lch-red));
  --color-positive: oklch(var(--lch-green));
  --color-bg: oklch(var(--lch-white));
  --color-message-bg: oklch(var(--lch-gray));
  --color-text: oklch(var(--lch-black));
  --color-text-reversed: oklch(var(--lch-white));
  --color-link: oklch(var(--lch-blue));
  --color-border: oklch(var(--lch-gray));
  --color-border-dark: oklch(var(--lch-gray-dark));
  --color-border-darker: oklch(var(--lch-gray-darker));
  --color-selected: oklch(var(--lch-blue-light));
  --color-selected-dark: oklch(var(--lch-blue-dark));
  --color-alert: oklch(var(--lch-orange));
  --color-text-subtle: oklch(var(--lch-gray-text));
  --color-border-input: oklch(var(--lch-gray-border-strong));
}

/* `.surface` tambien deshace el volteo de iconos de la barra. En `:root` el
   valor ya es el del tema; aqui se toma del token que la barra no toca. */
.surface {
  --icon-invert: var(--surface-icon-invert);
  --icon-invert-reverse: calc(1 - var(--surface-icon-invert));
}

:root {
  /* El volteo de icono del papel, congelado en `:root` para que `.surface`
     pueda recuperarlo desde dentro de la barra, donde `--icon-invert` ya vale
     otra cosa. Una custom property se resuelve donde se declara, asi que esta
     baja ya como numero. */
  --surface-icon-invert: var(--icon-invert);
}

/* Las paletas de la barra.
   Solo tinen la barra y el rail, y no dependen del tema: son oscuras siempre,
   como la de Slack. */
:root[data-palette="berenjena"] {
  --sb-bg: oklch(25% 0.07 320);
  --sb-bg-rail: oklch(21% 0.065 320);
  --sb-text: oklch(88% 0.02 320);
  --sb-text-muted: oklch(72% 0.03 320);
}

:root[data-palette="berenjena"],
:root[data-palette="medianoche"],
:root[data-palette="bosque"],
:root[data-palette="arcilla"],
:root[data-palette="oceano"] {
  --sb-text-strong: oklch(100% 0 0);
  --sb-hover: oklch(100% 0 0 / 0.09);
  --sb-line: oklch(100% 0 0 / 0.12);
  --sb-line-strong: oklch(100% 0 0 / 0.28);
  --sb-icon-invert: 1;
}

:root[data-palette="medianoche"] {
  --sb-bg: oklch(24% 0.06 265);
  --sb-bg-rail: oklch(20% 0.055 265);
  --sb-text: oklch(88% 0.02 265);
  --sb-text-muted: oklch(72% 0.03 265);
}

:root[data-palette="bosque"] {
  --sb-bg: oklch(26% 0.06 155);
  --sb-bg-rail: oklch(22% 0.055 155);
  --sb-text: oklch(90% 0.02 155);
  --sb-text-muted: oklch(74% 0.03 155);
}

:root[data-palette="arcilla"] {
  --sb-bg: oklch(30% 0.05 40);
  --sb-bg-rail: oklch(25% 0.045 40);
  --sb-text: oklch(92% 0.02 50);
  --sb-text-muted: oklch(76% 0.03 50);
}

:root[data-palette="oceano"] {
  --sb-bg: oklch(28% 0.06 220);
  --sb-bg-rail: oklch(24% 0.055 220);
  --sb-text: oklch(90% 0.02 220);
  --sb-text-muted: oklch(74% 0.03 220);
}

/* Dentro de la barra y del rail, los tokens del papel apuntan a los de la
   paleta. Asi los partials, los botones y los campos que ya existen se pintan
   bien sin una regla por pieza, y una hoja de Custom Styles que redefina
   `--sb-*` en :root cambia el color de toda la barra de una vez. */
#sidebar,
#rail {
  --color-bg: var(--sb-bg);
  --color-text: var(--sb-text);
  --color-text-reversed: var(--sb-bg);
  --color-text-subtle: var(--sb-text-muted);
  --color-message-bg: var(--sb-hover);
  --color-border: var(--sb-line);
  --color-border-dark: var(--sb-line);
  --color-border-darker: var(--sb-line-strong);
  --color-border-input: var(--sb-line-strong);
  --color-selected: var(--sb-active);
  --color-selected-dark: var(--sb-active);
  --color-link: var(--sb-text-strong);
  --icon-invert: var(--sb-icon-invert);
  --icon-invert-reverse: calc(1 - var(--sb-icon-invert));
  --hover-color: var(--sb-line-strong);
}

#rail {
  --color-bg: var(--sb-bg-rail);
  --color-text-reversed: var(--sb-bg-rail);
}
