Class: Studio::ThemeResolver

Inherits:
Object
  • Object
show all
Defined in:
lib/studio/theme_resolver.rb

Constant Summary collapse

ROLES =
%i[primary dark light success warning danger accent].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(colors = {}) ⇒ ThemeResolver

colors: hash of role => hex string (e.g. { primary: “#8E82FE”, dark: “#1A1535”, … })



8
9
10
# File 'lib/studio/theme_resolver.rb', line 8

def initialize(colors = {})
  @colors = colors.symbolize_keys
end

Instance Attribute Details

#colorsObject (readonly)

Returns the value of attribute colors.



5
6
7
# File 'lib/studio/theme_resolver.rb', line 5

def colors
  @colors
end

Instance Method Details

#dark_mode_varsObject



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/studio/theme_resolver.rb', line 30

def dark_mode_vars
  dark_base   = colors[:dark] || "#1A1535"
  primary     = colors[:primary] || "#8E82FE"
  border_rgb  = ColorScale.lighten(dark_base, 0.30)

  {
    "--color-page"           => dark_base,
    "--color-surface"        => ColorScale.lighten(dark_base, 0.15),
    "--color-surface-alt"    => ColorScale.darken(dark_base, 0.14),
    "--color-inset"          => ColorScale.darken(dark_base, 0.43),
    "--color-text"           => "#ffffff",
    "--color-text-body"      => "#e2e8f0",
    "--color-text-secondary" => "#94a3b8",
    "--color-text-muted"     => "#64748b",
    "--color-border"         => ColorScale.with_opacity(border_rgb, 0.2),
    "--color-border-strong"  => ColorScale.with_opacity(border_rgb, 0.4),
    "--color-shadow"         => "transparent",
    "--color-cta"            => primary,
    "--color-cta-hover"      => ColorScale.darken(primary, 0.30),
    "--color-success"        => colors[:success] || "#4BAF50",
    "--color-warning"        => colors[:warning] || "#FF7C47",
    "--color-danger"         => colors[:danger] || "#EF4444"
  }
end

#light_mode_varsObject



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/studio/theme_resolver.rb', line 75

def light_mode_vars
  light_base = colors[:light] || "#f8fafc"
  primary    = colors[:primary] || "#8E82FE"

  {
    "--color-page"           => light_base,
    "--color-surface"        => "#ffffff",
    "--color-surface-alt"    => ColorScale.darken(light_base, 0.03),
    "--color-inset"          => ColorScale.darken(light_base, 0.08),
    "--color-text"           => "#0f172a",
    "--color-text-body"      => "#334155",
    "--color-text-secondary" => "#64748b",
    "--color-text-muted"     => "#94a3b8",
    "--color-border"         => ColorScale.darken(light_base, 0.08),
    "--color-border-strong"  => ColorScale.darken(light_base, 0.15),
    "--color-shadow"         => "rgba(0,0,0,0.05)",
    "--color-cta"            => primary,
    "--color-cta-hover"      => ColorScale.darken(primary, 0.30),
    "--color-success"        => colors[:success] || "#4BAF50",
    "--color-warning"        => colors[:warning] || "#FF7C47",
    "--color-danger"         => colors[:danger] || "#EF4444"
  }
end

#primary_palette_varsObject

Generate –color-primary-Studio::ThemeResolver.50.50..900 + RGB variants for Tailwind opacity support



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/studio/theme_resolver.rb', line 56

def primary_palette_vars
  primary = colors[:primary] || "#8E82FE"
  scale = ColorScale.generate(primary)
  vars = {}

  scale.each do |shade, hex|
    vars["--color-primary-#{shade}"] = hex
    r, g, b = ColorScale.hex_to_rgb(hex)
    vars["--color-primary-#{shade}-rgb"] = "#{r} #{g} #{b}"
  end

  # DEFAULT aliases
  r, g, b = ColorScale.hex_to_rgb(primary)
  vars["--color-primary"] = primary
  vars["--color-primary-rgb"] = "#{r} #{g} #{b}"

  vars
end

#to_cssObject



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/studio/theme_resolver.rb', line 12

def to_css
  dark_vars  = dark_mode_vars.map { |k, v| "  #{k}: #{v};" }.join("\n")
  light_vars = light_mode_vars.map { |k, v| "  #{k}: #{v};" }.join("\n")
  palette_vars = primary_palette_vars.map { |k, v| "  #{k}: #{v};" }.join("\n")

  <<~CSS
    :root, .dark {
    #{dark_vars}
    #{palette_vars}
    }

    html:not(.dark) {
    #{light_vars}
    #{palette_vars}
    }
  CSS
end