oneiros / map /themes.py
Adinda Panca Mochamad
Day 2: SVG dream map, 5 mood palettes, entity panel
418ee9f
Raw
History Blame Contribute Delete
3.53 kB
"""5 mood palettes for the dream map SVG."""
from __future__ import annotations
import colorsys
from typing import TypedDict
class Palette(TypedDict):
bg: str
bg2: str # gradient stop
orbit: str # subtle ring lines
node_char: str # character fill
node_place: str # place fill
node_symbol: str # symbol fill
edge_solid: str # harmony / transformation
edge_dash: str # tension / pursuit
text: str
text_dim: str
title: str
badge_bg: str
PALET_MOOD: dict[str, Palette] = {
"mysterious": Palette(
bg="#0d0d1a",
bg2="#12103a",
orbit="rgba(151,116,255,0.12)",
node_char="#9774ff",
node_place="#4e8fcc",
node_symbol="#cc8844",
edge_solid="rgba(151,116,255,0.55)",
edge_dash="rgba(151,116,255,0.28)",
text="#e8e4f8",
text_dim="#9d95b8",
title="#c8b8ff",
badge_bg="rgba(151,116,255,0.20)",
),
"joyful": Palette(
bg="#0a150c",
bg2="#0f2214",
orbit="rgba(110,210,100,0.14)",
node_char="#6ed264",
node_place="#d4be48",
node_symbol="#d46ea4",
edge_solid="rgba(110,210,100,0.60)",
edge_dash="rgba(110,210,100,0.28)",
text="#e4f8e6",
text_dim="#8aba8e",
title="#aee8a0",
badge_bg="rgba(110,210,100,0.18)",
),
"anxious": Palette(
bg="#160a0a",
bg2="#2a0f0f",
orbit="rgba(220,72,72,0.14)",
node_char="#dc4848",
node_place="#dc9050",
node_symbol="#8080cc",
edge_solid="rgba(220,72,72,0.55)",
edge_dash="rgba(220,72,72,0.28)",
text="#f8e4e4",
text_dim="#b88888",
title="#f0a0a0",
badge_bg="rgba(220,72,72,0.18)",
),
"surreal": Palette(
bg="#050f14",
bg2="#091824",
orbit="rgba(48,200,200,0.14)",
node_char="#30c8c8",
node_place="#c830c8",
node_symbol="#c8c830",
edge_solid="rgba(48,200,200,0.55)",
edge_dash="rgba(200,48,200,0.32)",
text="#e4f8f8",
text_dim="#88b0b8",
title="#88e8e8",
badge_bg="rgba(48,200,200,0.18)",
),
"peaceful": Palette(
bg="#080f10",
bg2="#0d1a1e",
orbit="rgba(100,170,200,0.14)",
node_char="#64a8c8",
node_place="#68c890",
node_symbol="#c8a870",
edge_solid="rgba(100,170,200,0.55)",
edge_dash="rgba(100,170,200,0.28)",
text="#e4eff8",
text_dim="#7898a8",
title="#a0ccdc",
badge_bg="rgba(100,170,200,0.18)",
),
}
_FALLBACK: Palette = PALET_MOOD["mysterious"]
def get_palette(mood: str) -> Palette:
return PALET_MOOD.get(mood, _FALLBACK)
def _hex_to_hsl(hex_color: str) -> tuple[float, float, float]:
hex_color = hex_color.lstrip("#")
r, g, b = (int(hex_color[i:i+2], 16) / 255.0 for i in (0, 2, 4))
return colorsys.rgb_to_hls(r, g, b)
def _hsl_to_hex(h: float, l: float, s: float) -> str:
r, g, b = colorsys.hls_to_rgb(h, l, s)
return "#{:02x}{:02x}{:02x}".format(int(r * 255), int(g * 255), int(b * 255))
def terangkan(hex_color: str, amount: float = 0.15) -> str:
"""Lighten a hex color by HSL amount."""
h, l, s = _hex_to_hsl(hex_color)
return _hsl_to_hex(h, min(1.0, l + amount), s)
def gelapkan(hex_color: str, amount: float = 0.15) -> str:
"""Darken a hex color by HSL amount."""
h, l, s = _hex_to_hsl(hex_color)
return _hsl_to_hex(h, max(0.0, l - amount), s)