feat(tahuantinsuyu): rueda 3D, hover-highlight, universo, themes papel

Segunda tanda de UX a partir de feedback de uso real:

- Zoom/pan reasignados: wheel = zoom puro (sin modifier). LMB drag
  fuera del anillo de signos = pan; sobre el anillo = jog-dial
  (rectificación). MMB sigue como pan secundario. Tecla `0`
  resetea zoom + pan.

- Planetas legibles: el "dot rellenado" se reduce a 3 px (solo
  marca el grado exacto). Encima va `planet_glyph` con disco-halo
  del bg_panel y border del color del planeta — el glyph unicode
  astronómico (☉☽☿♀♂♃♄♅♆♇) ahora se lee contra cualquier fondo.

- Aspectos hover-highlight: al hovear un planeta, sus líneas se
  mantienen al 100 % y el resto cae a 18 %. Resuelve el "¿quién
  contra quién?" sin desordenar la rueda.

- Ascensionales: cruz completa ASC-DESC + MC-IC (4 radios) con
  α=0.55. Labels ASC/MC/DESC/IC como pills con bg-halo y border
  `angle_highlight`, font 11 — antes eran texto chico que se
  fundía con el dial.

- Universo: el wheel pierde su bg de cuadrado (que cortaba contra
  el panel). El root del canvas pinta un starfield sutil ~130
  puntos deterministas (xorshift32 con seed fija, sin parpadeo
  entre frames). Solo activo en themes dark — sobre fondos claros
  generaría ruido.

- Estilo 3D anillos: `stroke_circle_3d` (highlight +luma + base +
  shadow -luma) reemplaza al stroke plano en sign_outer, sign_inner
  y el outer ring. Más `paint_dial_bevel` con 10 strokes finos en
  bell curve entre sign_inner y sign_outer — simula gradient radial
  que gpui canvas no soporta nativo.

- Theme `Print Color`: papel crema, paleta astro con luminancia
  0.26-0.34 y saturación alta, sin glow ni gradients.

- Theme `Print B&W`: monocromático sobre blanco puro. Aspectos
  diferenciados por dash pattern en lugar de color:
  conjunction/opposition sólidos, square dash medio, trine dash
  largo, sextile dotted, minors dotted finísimo. `paint_segment`
  con `dash: Option<(on,off)>` para implementar dashes (gpui
  canvas no tiene stroke dash nativo).

Todos los tests siguen verdes (6 shell + 5 yahweh-theme +
2 tahuantinsuyu-theme).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
sergio
2026-05-18 15:45:48 +00:00
parent e09207b152
commit 1078e433f2
3 changed files with 615 additions and 142 deletions
@@ -215,14 +215,132 @@ impl AstroPalette {
}
}
pub fn for_theme(theme: &yahweh_theme::Theme) -> Self {
if theme.is_dark {
Self::dark()
} else {
Self::light()
/// Variante "papel coloreado" — para preview de impresión. Hue de
/// cada slot mantenido; luminancia 0.26-0.34 y saturación alta
/// para que sobreviva el ink-bleed sin perder identidad. Sin glow.
pub fn print_color() -> Self {
Self {
is_dark: false,
fire: hsla(11.0 / 360.0, 0.78, 0.34, 1.0),
earth: hsla(95.0 / 360.0, 0.55, 0.26, 1.0),
air: hsla(48.0 / 360.0, 0.78, 0.34, 1.0),
water: hsla(210.0 / 360.0, 0.72, 0.32, 1.0),
cardinal: hsla(340.0 / 360.0, 0.65, 0.34, 1.0),
fixed: hsla(258.0 / 360.0, 0.55, 0.32, 1.0),
mutable: hsla(170.0 / 360.0, 0.55, 0.28, 1.0),
sun: hsla(35.0 / 360.0, 0.95, 0.34, 1.0),
moon: hsla(220.0 / 360.0, 0.35, 0.34, 1.0),
mercury: hsla(140.0 / 360.0, 0.55, 0.28, 1.0),
venus: hsla(330.0 / 360.0, 0.65, 0.36, 1.0),
mars: hsla(8.0 / 360.0, 0.85, 0.34, 1.0),
jupiter: hsla(38.0 / 360.0, 0.85, 0.34, 1.0),
saturn: hsla(28.0 / 360.0, 0.30, 0.26, 1.0),
uranus: hsla(195.0 / 360.0, 0.75, 0.34, 1.0),
neptune: hsla(225.0 / 360.0, 0.65, 0.34, 1.0),
pluto: hsla(280.0 / 360.0, 0.55, 0.28, 1.0),
chiron: hsla(75.0 / 360.0, 0.42, 0.30, 1.0),
north_node: hsla(35.0 / 360.0, 0.55, 0.36, 1.0),
south_node: hsla(35.0 / 360.0, 0.30, 0.28, 1.0),
lilith: hsla(310.0 / 360.0, 0.60, 0.26, 1.0),
conjunction: hsla(45.0 / 360.0, 0.75, 0.32, 1.0),
sextile: hsla(195.0 / 360.0, 0.70, 0.32, 1.0),
square: hsla(8.0 / 360.0, 0.85, 0.34, 1.0),
trine: hsla(140.0 / 360.0, 0.65, 0.28, 1.0),
opposition: hsla(280.0 / 360.0, 0.65, 0.36, 1.0),
minor_aspect: hsla(220.0 / 360.0, 0.40, 0.40, 0.85),
dial_ring: hsla(40.0 / 360.0, 0.30, 0.22, 1.0),
house_cusp: hsla(40.0 / 360.0, 0.20, 0.28, 0.90),
angle_highlight: hsla(15.0 / 360.0, 0.85, 0.36, 1.0),
}
}
/// Variante "papel B&N" — preview de impresión monocromática.
/// TODO los slots de planeta y aspecto se reducen a niveles de
/// gris. El canvas se encarga de diferenciar aspectos por dash
/// pattern y planetas por glyph (el unicode astronómico es
/// distintivo aunque pierda color).
pub fn print_bw() -> Self {
// Tres niveles funcionales: muy oscuro (texto, glyphs
// principales), medio (cusps, líneas), claro (fondos, minors).
let ink_strong = hsla(0.0, 0.0, 0.10, 1.0);
let ink_mid = hsla(0.0, 0.0, 0.30, 1.0);
let ink_soft = hsla(0.0, 0.0, 0.50, 0.90);
let ink_faint = hsla(0.0, 0.0, 0.55, 0.75);
Self {
is_dark: false,
fire: ink_strong,
earth: ink_strong,
air: ink_strong,
water: ink_strong,
cardinal: ink_mid,
fixed: ink_mid,
mutable: ink_mid,
// Planetas: todos en ink_strong para que los glyphs se
// lean fuerte. El usuario distingue por el unicode
// astronómico, no por hue.
sun: ink_strong,
moon: ink_strong,
mercury: ink_strong,
venus: ink_strong,
mars: ink_strong,
jupiter: ink_strong,
saturn: ink_strong,
uranus: ink_strong,
neptune: ink_strong,
pluto: ink_strong,
chiron: ink_mid,
north_node: ink_mid,
south_node: ink_mid,
lilith: ink_mid,
// Aspectos: el color es uniforme; la diferenciación es por
// dash pattern en el painter (square=dashed, trine=solid,
// sextile=dotted, etc.). Acá solo damos el "intensity"
// base que el painter modula.
conjunction: ink_strong,
sextile: ink_mid,
square: ink_strong,
trine: ink_mid,
opposition: ink_strong,
minor_aspect: ink_faint,
dial_ring: ink_mid,
house_cusp: ink_soft,
angle_highlight: ink_strong,
}
}
pub fn for_theme(theme: &yahweh_theme::Theme) -> Self {
// Dispatcher por nombre para los themes "papel"; el resto cae
// al binary dark/light según `is_dark`. Mantenemos el match
// case-insensitive por defensa contra cambios de naming.
match theme.name {
"Print Color" => Self::print_color(),
"Print B&W" => Self::print_bw(),
_ if theme.is_dark => Self::dark(),
_ => Self::light(),
}
}
/// Devuelve `true` si la paleta es monocromática — los painters
/// la usan para activar dash patterns en lugar de diferenciar
/// aspectos por color.
pub fn is_monochrome(&self) -> bool {
// Heurística simple: si conjunction y square (que en color
// siempre tienen hues distintos) tienen el mismo hue,
// estamos en BW.
(self.conjunction.h - self.square.h).abs() < 1e-3
}
pub fn element(&self, e: Element) -> Hsla {
match e {
Element::Fire => self.fire,