Make tablo icon selection dynamic based on color using nearest palette
match Instead of selecting icons based on tablo name length, compute the closest matching icon from a predefined palette by comparing hex color values. This ensures consistent icon-color pairing and better visual harmony.
This commit is contained in:
parent
c780dd1625
commit
3232309388
9 changed files with 244 additions and 14 deletions
|
|
@ -7,6 +7,7 @@ import (
|
|||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
|
@ -23,6 +24,29 @@ var tabloColorPattern = regexp.MustCompile(`^#[0-9A-Fa-f]{6}$`)
|
|||
const defaultTabloColor = "#3B82F6"
|
||||
const tabloColorValidationMessage = "La couleur du projet doit être un code hexadécimal au format #RRGGBB"
|
||||
|
||||
type tabloPaletteEntry struct {
|
||||
icon string
|
||||
bg string
|
||||
fg string
|
||||
accent string
|
||||
r int
|
||||
g int
|
||||
b int
|
||||
}
|
||||
|
||||
var tabloIconPalette = []tabloPaletteEntry{
|
||||
{icon: "bolt", bg: "bg-blue-500", fg: "text-white", accent: "blue", r: 59, g: 130, b: 246},
|
||||
{icon: "leaf", bg: "bg-green-500", fg: "text-white", accent: "green", r: 34, g: 197, b: 94},
|
||||
{icon: "gem", bg: "bg-purple-500", fg: "text-white", accent: "purple", r: 168, g: 85, b: 247},
|
||||
{icon: "flame", bg: "bg-red-500", fg: "text-white", accent: "red", r: 239, g: 68, b: 68},
|
||||
{icon: "star", bg: "bg-yellow-500", fg: "text-gray-700", accent: "yellow", r: 234, g: 179, b: 8},
|
||||
{icon: "compass", bg: "bg-indigo-500", fg: "text-white", accent: "indigo", r: 99, g: 102, b: 241},
|
||||
{icon: "heart", bg: "bg-pink-500", fg: "text-white", accent: "pink", r: 236, g: 72, b: 153},
|
||||
{icon: "waves", bg: "bg-teal-500", fg: "text-white", accent: "teal", r: 20, g: 184, b: 166},
|
||||
{icon: "sun", bg: "bg-orange-500", fg: "text-white", accent: "orange", r: 249, g: 115, b: 22},
|
||||
{icon: "sparkles", bg: "bg-cyan-500", fg: "text-gray-700", accent: "cyan", r: 6, g: 182, b: 212},
|
||||
}
|
||||
|
||||
type TabloStatus = tablomodel.Status
|
||||
|
||||
const (
|
||||
|
|
@ -455,12 +479,13 @@ func buildTabloCardViews(tablos []TabloRecord, state TablosPageState) []views.Ta
|
|||
items := make([]views.TabloCardView, 0, len(tablos))
|
||||
for _, tablo := range tablos {
|
||||
statusLabel, statusClass, progress, statusTone := tabloStatusPresentation(tablo.Status)
|
||||
iconKind, bgClass, fgClass, accent := tabloIconPresentation(tablo.Name)
|
||||
color := storedTabloColor(tablo.Color)
|
||||
iconKind, bgClass, fgClass, accent := tabloIconPresentation(color)
|
||||
|
||||
items = append(items, views.TabloCardView{
|
||||
ID: tablo.ID.String(),
|
||||
Name: tablo.Name,
|
||||
Color: storedTabloColor(tablo.Color),
|
||||
Color: color,
|
||||
Status: string(tablo.Status),
|
||||
StatusLabel: statusLabel,
|
||||
StatusClass: statusClass,
|
||||
|
|
@ -512,15 +537,53 @@ func tabloStatusPresentation(status TabloStatus) (string, string, int, string) {
|
|||
}
|
||||
}
|
||||
|
||||
func tabloIconPresentation(name string) (string, string, string, string) {
|
||||
switch len(strings.TrimSpace(name)) % 3 {
|
||||
case 1:
|
||||
return "gem", "bg-purple-500", "text-white", "purple"
|
||||
case 2:
|
||||
return "sparkles", "bg-cyan-500", "text-gray-700", "red"
|
||||
default:
|
||||
return "bolt", "bg-blue-500", "text-white", "blue"
|
||||
func tabloIconPresentation(color string) (string, string, string, string) {
|
||||
r, g, b, ok := parseHexColor(color)
|
||||
if !ok {
|
||||
fallback := tabloIconPalette[0]
|
||||
return fallback.icon, fallback.bg, fallback.fg, fallback.accent
|
||||
}
|
||||
|
||||
best := tabloIconPalette[0]
|
||||
bestDistance := colorDistanceSquared(r, g, b, best.r, best.g, best.b)
|
||||
for _, entry := range tabloIconPalette[1:] {
|
||||
distance := colorDistanceSquared(r, g, b, entry.r, entry.g, entry.b)
|
||||
if distance < bestDistance {
|
||||
best = entry
|
||||
bestDistance = distance
|
||||
}
|
||||
}
|
||||
|
||||
return best.icon, best.bg, best.fg, best.accent
|
||||
}
|
||||
|
||||
func parseHexColor(color string) (int, int, int, bool) {
|
||||
trimmed := strings.TrimSpace(color)
|
||||
if len(trimmed) != 7 || trimmed[0] != '#' {
|
||||
return 0, 0, 0, false
|
||||
}
|
||||
|
||||
r, err := strconv.ParseInt(trimmed[1:3], 16, 0)
|
||||
if err != nil {
|
||||
return 0, 0, 0, false
|
||||
}
|
||||
g, err := strconv.ParseInt(trimmed[3:5], 16, 0)
|
||||
if err != nil {
|
||||
return 0, 0, 0, false
|
||||
}
|
||||
b, err := strconv.ParseInt(trimmed[5:7], 16, 0)
|
||||
if err != nil {
|
||||
return 0, 0, 0, false
|
||||
}
|
||||
|
||||
return int(r), int(g), int(b), true
|
||||
}
|
||||
|
||||
func colorDistanceSquared(r1 int, g1 int, b1 int, r2 int, g2 int, b2 int) int {
|
||||
dr := r1 - r2
|
||||
dg := g1 - g2
|
||||
db := b1 - b2
|
||||
return dr*dr + dg*dg + db*db
|
||||
}
|
||||
|
||||
func formatFrenchDate(value time.Time) string {
|
||||
|
|
|
|||
|
|
@ -493,6 +493,33 @@ func TestFormatCardDateUsesFrenchMonthNames(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestTabloIconPresentationUsesClosestPaletteColor(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
color string
|
||||
icon string
|
||||
}{
|
||||
{name: "blue maps to bolt", color: "#3B82F6", icon: "bolt"},
|
||||
{name: "green maps to leaf", color: "#22C55E", icon: "leaf"},
|
||||
{name: "purple maps to gem", color: "#A855F7", icon: "gem"},
|
||||
{name: "red maps to flame", color: "#EF4444", icon: "flame"},
|
||||
{name: "yellow maps to star", color: "#EAB308", icon: "star"},
|
||||
{name: "indigo maps to compass", color: "#6366F1", icon: "compass"},
|
||||
{name: "pink maps to heart", color: "#EC4899", icon: "heart"},
|
||||
{name: "teal maps to waves", color: "#14B8A6", icon: "waves"},
|
||||
{name: "orange maps to sun", color: "#F97316", icon: "sun"},
|
||||
{name: "cyan maps to sparkles", color: "#06B6D4", icon: "sparkles"},
|
||||
{name: "nearby blue still maps to bolt", color: "#4F86F7", icon: "bolt"},
|
||||
} {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
icon, _, _, _ := tabloIconPresentation(tt.color)
|
||||
if icon != tt.icon {
|
||||
t.Fatalf("expected icon %q for color %q, got %q", tt.icon, tt.color, icon)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTablosPageGridUsesProjectCardMarkup(t *testing.T) {
|
||||
repo := NewInMemoryAuthRepository()
|
||||
handler := NewAuthHandler(repo)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
.ui-button {
|
||||
align-items: center;
|
||||
border: 0;
|
||||
border-radius: 0.7rem;
|
||||
border-radius: 0.35rem;
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
font-weight: 600;
|
||||
|
|
|
|||
|
|
@ -60,6 +60,29 @@ func TestOverviewProjectsSectionRendersColorAndEditAction(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestTabloListRowRendersLeafIconKind(t *testing.T) {
|
||||
component := TabloListRow(TabloCardView{
|
||||
ID: "11111111-1111-1111-1111-111111111111",
|
||||
Name: "Palette",
|
||||
Color: "#22C55E",
|
||||
StatusLabel: "À faire",
|
||||
StatusTone: "info",
|
||||
Progress: 0,
|
||||
ProgressLabel: "0%",
|
||||
CreatedAtLabel: "10 mai 2026",
|
||||
DeleteRequestURL: "/tablos/11111111-1111-1111-1111-111111111111",
|
||||
EditRequestURL: "/tablos/11111111-1111-1111-1111-111111111111/edit",
|
||||
IconKind: "leaf",
|
||||
Initial: "P",
|
||||
})
|
||||
|
||||
html := renderViewToString(t, component)
|
||||
|
||||
if !strings.Contains(html, `<path d="M11 20A7 7 0 0 1 4 13V6a1 1 0 0 1 1-1h7a7 7 0 0 1 7 7v0a8 8 0 0 1-8 8Z"></path>`) {
|
||||
t.Fatalf("expected leaf icon markup, got %q", html)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTabloListRowDoesNotRenderSpacerBetweenEditAndDelete(t *testing.T) {
|
||||
component := TabloListRow(TabloCardView{
|
||||
ID: "11111111-1111-1111-1111-111111111111",
|
||||
|
|
|
|||
|
|
@ -5,9 +5,10 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/a-h/templ"
|
||||
tablomodel "xtablo-backend/internal/tablos"
|
||||
"xtablo-backend/internal/web/dates"
|
||||
|
||||
"github.com/a-h/templ"
|
||||
)
|
||||
|
||||
const overviewProjectsPreviewLimit = 6
|
||||
|
|
|
|||
|
|
@ -125,6 +125,54 @@ templ SidebarIcon(kind string) {
|
|||
<path d="M11 3 8 9l4 13 4-13-3-6"></path>
|
||||
<path d="M2 9h20"></path>
|
||||
</svg>
|
||||
case "leaf":
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M11 20A7 7 0 0 1 4 13V6a1 1 0 0 1 1-1h7a7 7 0 0 1 7 7v0a8 8 0 0 1-8 8Z"></path>
|
||||
<path d="M12 10 4 18"></path>
|
||||
</svg>
|
||||
case "flame":
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M8.5 14.5A5.5 5.5 0 1 0 19 18c0-1.57-.52-3.09-1.48-4.3C16.1 12 14 10.82 14 7.5c0-1.5.5-3 1.5-4-4 1-7 4.5-7 8.5 0 1.61.49 3.16 1.4 4.45"></path>
|
||||
<path d="M12 22c2.21 0 4-1.79 4-4 0-1.5-.83-2.8-2.05-3.49-.61 1.03-1.6 1.83-2.82 2.2"></path>
|
||||
</svg>
|
||||
case "star":
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="m12 3 2.9 5.88 6.5.95-4.7 4.58 1.11 6.47L12 17.77 6.19 20.88l1.11-6.47-4.7-4.58 6.5-.95Z"></path>
|
||||
</svg>
|
||||
case "compass":
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<circle cx="12" cy="12" r="10"></circle>
|
||||
<path d="m16.24 7.76-2.12 6.36-6.36 2.12 2.12-6.36z"></path>
|
||||
</svg>
|
||||
case "heart":
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="m12 21-1.45-1.32C5.4 15.02 2 11.93 2 8.1 2 5 4.42 2.5 7.5 2.5c1.74 0 3.41.81 4.5 2.09A6 6 0 0 1 16.5 2.5C19.58 2.5 22 5 22 8.1c0 3.83-3.4 6.92-8.55 11.58Z"></path>
|
||||
</svg>
|
||||
case "waves":
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M2 6c1.5 1.5 3 2 4.5 2S9.5 7.5 11 6s3-2 4.5-2S18.5 4.5 20 6s3 2 4 2"></path>
|
||||
<path d="M2 12c1.5 1.5 3 2 4.5 2s3-.5 4.5-2 3-2 4.5-2 3 .5 4.5 2 3 2 4 2"></path>
|
||||
<path d="M2 18c1.5 1.5 3 2 4.5 2s3-.5 4.5-2 3-2 4.5-2 3 .5 4.5 2 3 2 4 2"></path>
|
||||
</svg>
|
||||
case "sun":
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<circle cx="12" cy="12" r="4"></circle>
|
||||
<path d="M12 2v2"></path>
|
||||
<path d="M12 20v2"></path>
|
||||
<path d="m4.93 4.93 1.41 1.41"></path>
|
||||
<path d="m17.66 17.66 1.41 1.41"></path>
|
||||
<path d="M2 12h2"></path>
|
||||
<path d="M20 12h2"></path>
|
||||
<path d="m6.34 17.66-1.41 1.41"></path>
|
||||
<path d="m19.07 4.93-1.41 1.41"></path>
|
||||
</svg>
|
||||
case "sparkles":
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M9.94 3.06 12 8l2.06-4.94L19 1l-2.06 4.94L22 8l-5.06 2.06L14.88 15 12 10.06 9.12 15 7.06 10.06 2 8l5.06-2.06Z"></path>
|
||||
<path d="M5 19v-2"></path>
|
||||
<path d="M19 19v-2"></path>
|
||||
<path d="M12 22v-2"></path>
|
||||
</svg>
|
||||
default:
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z"></path>
|
||||
|
|
|
|||
|
|
@ -157,8 +157,48 @@ func SidebarIcon(kind string) templ.Component {
|
|||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
case "leaf":
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M11 20A7 7 0 0 1 4 13V6a1 1 0 0 1 1-1h7a7 7 0 0 1 7 7v0a8 8 0 0 1-8 8Z\"></path> <path d=\"M12 10 4 18\"></path></svg>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
case "flame":
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M8.5 14.5A5.5 5.5 0 1 0 19 18c0-1.57-.52-3.09-1.48-4.3C16.1 12 14 10.82 14 7.5c0-1.5.5-3 1.5-4-4 1-7 4.5-7 8.5 0 1.61.49 3.16 1.4 4.45\"></path> <path d=\"M12 22c2.21 0 4-1.79 4-4 0-1.5-.83-2.8-2.05-3.49-.61 1.03-1.6 1.83-2.82 2.2\"></path></svg>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
case "star":
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"m12 3 2.9 5.88 6.5.95-4.7 4.58 1.11 6.47L12 17.77 6.19 20.88l1.11-6.47-4.7-4.58 6.5-.95Z\"></path></svg>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
case "compass":
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle> <path d=\"m16.24 7.76-2.12 6.36-6.36 2.12 2.12-6.36z\"></path></svg>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
case "heart":
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"m12 21-1.45-1.32C5.4 15.02 2 11.93 2 8.1 2 5 4.42 2.5 7.5 2.5c1.74 0 3.41.81 4.5 2.09A6 6 0 0 1 16.5 2.5C19.58 2.5 22 5 22 8.1c0 3.83-3.4 6.92-8.55 11.58Z\"></path></svg>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
case "waves":
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M2 6c1.5 1.5 3 2 4.5 2S9.5 7.5 11 6s3-2 4.5-2S18.5 4.5 20 6s3 2 4 2\"></path> <path d=\"M2 12c1.5 1.5 3 2 4.5 2s3-.5 4.5-2 3-2 4.5-2 3 .5 4.5 2 3 2 4 2\"></path> <path d=\"M2 18c1.5 1.5 3 2 4.5 2s3-.5 4.5-2 3-2 4.5-2 3 .5 4.5 2 3 2 4 2\"></path></svg>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
case "sun":
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"4\"></circle> <path d=\"M12 2v2\"></path> <path d=\"M12 20v2\"></path> <path d=\"m4.93 4.93 1.41 1.41\"></path> <path d=\"m17.66 17.66 1.41 1.41\"></path> <path d=\"M2 12h2\"></path> <path d=\"M20 12h2\"></path> <path d=\"m6.34 17.66-1.41 1.41\"></path> <path d=\"m19.07 4.93-1.41 1.41\"></path></svg>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
case "sparkles":
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M9.94 3.06 12 8l2.06-4.94L19 1l-2.06 4.94L22 8l-5.06 2.06L14.88 15 12 10.06 9.12 15 7.06 10.06 2 8l5.06-2.06Z\"></path> <path d=\"M5 19v-2\"></path> <path d=\"M19 19v-2\"></path> <path d=\"M12 22v-2\"></path></svg>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
default:
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z\"></path></svg>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z\"></path></svg>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -394,7 +394,7 @@ input {
|
|||
.ui-button {
|
||||
align-items: center;
|
||||
border: 0;
|
||||
border-radius: 0.7rem;
|
||||
border-radius: 0.35rem;
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
font-weight: 600;
|
||||
|
|
|
|||
|
|
@ -3,13 +3,18 @@
|
|||
:root, :host {
|
||||
--color-red-50: oklch(97.1% 0.013 17.38);
|
||||
--color-red-200: oklch(88.5% 0.062 18.334);
|
||||
--color-red-500: oklch(63.7% 0.237 25.331);
|
||||
--color-red-700: oklch(50.5% 0.213 27.518);
|
||||
--color-orange-500: oklch(70.5% 0.213 47.604);
|
||||
--color-yellow-500: oklch(79.5% 0.184 86.047);
|
||||
--color-green-50: oklch(98.2% 0.018 155.826);
|
||||
--color-green-200: oklch(92.5% 0.084 155.995);
|
||||
--color-green-400: oklch(79.2% 0.209 151.711);
|
||||
--color-green-500: oklch(72.3% 0.219 149.579);
|
||||
--color-green-600: oklch(62.7% 0.194 149.214);
|
||||
--color-green-800: oklch(44.8% 0.119 151.328);
|
||||
--color-green-950: oklch(26.6% 0.065 152.934);
|
||||
--color-teal-500: oklch(70.4% 0.14 182.503);
|
||||
--color-cyan-500: oklch(71.5% 0.143 215.221);
|
||||
--color-blue-50: oklch(97% 0.014 254.604);
|
||||
--color-blue-200: oklch(88.2% 0.059 254.128);
|
||||
|
|
@ -18,11 +23,13 @@
|
|||
--color-blue-600: oklch(54.6% 0.245 262.881);
|
||||
--color-blue-800: oklch(42.4% 0.199 265.638);
|
||||
--color-blue-950: oklch(28.2% 0.091 267.935);
|
||||
--color-indigo-500: oklch(58.5% 0.233 277.117);
|
||||
--color-purple-50: oklch(97.7% 0.014 308.299);
|
||||
--color-purple-400: oklch(71.4% 0.203 305.504);
|
||||
--color-purple-500: oklch(62.7% 0.265 303.9);
|
||||
--color-purple-600: oklch(55.8% 0.288 302.321);
|
||||
--color-purple-950: oklch(29.1% 0.149 302.717);
|
||||
--color-pink-500: oklch(65.6% 0.241 354.308);
|
||||
--color-gray-50: oklch(98.5% 0.002 247.839);
|
||||
--color-gray-100: oklch(96.7% 0.003 264.542);
|
||||
--color-gray-200: oklch(92.8% 0.006 264.531);
|
||||
|
|
@ -310,6 +317,18 @@
|
|||
.bg-green-50 {
|
||||
background-color: var(--color-green-50);
|
||||
}
|
||||
.bg-green-500 {
|
||||
background-color: var(--color-green-500);
|
||||
}
|
||||
.bg-indigo-500 {
|
||||
background-color: var(--color-indigo-500);
|
||||
}
|
||||
.bg-orange-500 {
|
||||
background-color: var(--color-orange-500);
|
||||
}
|
||||
.bg-pink-500 {
|
||||
background-color: var(--color-pink-500);
|
||||
}
|
||||
.bg-purple-50 {
|
||||
background-color: var(--color-purple-50);
|
||||
}
|
||||
|
|
@ -322,6 +341,12 @@
|
|||
.bg-red-50 {
|
||||
background-color: var(--color-red-50);
|
||||
}
|
||||
.bg-red-500 {
|
||||
background-color: var(--color-red-500);
|
||||
}
|
||||
.bg-teal-500 {
|
||||
background-color: var(--color-teal-500);
|
||||
}
|
||||
.bg-white {
|
||||
background-color: var(--color-white);
|
||||
}
|
||||
|
|
@ -333,6 +358,9 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
.bg-yellow-500 {
|
||||
background-color: var(--color-yellow-500);
|
||||
}
|
||||
.px-4 {
|
||||
padding-inline: calc(var(--spacing) * 4);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue