Tema surreal + logo koala baru
- assets/logo.svg (dream sky koala) + assets/icon.png hasil render 512x512 (skrip render: oksvg/rasterx, sparkle di-inline karena <use> tidak didukung) - tema: langit malam ungu (#140E24), kartu violet, primer dusk pink, aksen amber<->magenta yang berdenyut; varian terang jadi lavender lembut - ikon monokrom dari Iconify ikut diwarnai dusk pink (#c25c9e), bukan indigo lama - screenshot README diperbarui
No files matched your search
@@ -10,6 +10,9 @@ Desktop app (Go + Fyne) that creates application shortcuts on Linux in a few cli
|
||||
from an executable file, or from a web URL as a PWA. Ships as a single-file
|
||||
AppImage, no terminal needed.
|
||||
|
||||
*Dream-sky theme: night violet, dusk pink and a moon-coloured accent that subtly
|
||||
breathes while the app is open (the koala in `assets/logo.svg` is the mascot).*
|
||||
|
||||

|
||||
|
||||
<p align="center">
|
||||
|
||||
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 102 KiB |
@@ -0,0 +1,85 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 272" width="256" height="272" role="img" aria-label="lazyrun koala logo">
|
||||
<title>lazyrun</title>
|
||||
|
||||
<defs>
|
||||
<!-- dream sky -->
|
||||
<linearGradient id="sky" x1="0" y1="0" x2="0.3" y2="1">
|
||||
<stop offset="0" stop-color="#241247"/>
|
||||
<stop offset="0.45" stop-color="#6a3d9a"/>
|
||||
<stop offset="0.78" stop-color="#c25c9e"/>
|
||||
<stop offset="1" stop-color="#ff9a76"/>
|
||||
</linearGradient>
|
||||
<!-- soft sun halo -->
|
||||
<radialGradient id="sun" cx="0.5" cy="0.5" r="0.5">
|
||||
<stop offset="0" stop-color="#fff3c4" stop-opacity="0.95"/>
|
||||
<stop offset="0.6" stop-color="#ffd166" stop-opacity="0.45"/>
|
||||
<stop offset="1" stop-color="#ffd166" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<!-- glow behind koala -->
|
||||
<radialGradient id="glow" cx="0.5" cy="0.5" r="0.5">
|
||||
<stop offset="0" stop-color="#ffffff" stop-opacity="0.28"/>
|
||||
<stop offset="1" stop-color="#ffffff" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
|
||||
</defs>
|
||||
|
||||
<!-- surreal background -->
|
||||
<rect x="0" y="0" width="256" height="272" rx="46" fill="url(#sky)"/>
|
||||
<circle cx="128" cy="148" r="96" fill="url(#sun)"/>
|
||||
<circle cx="66" cy="196" r="52" fill="url(#glow)"/>
|
||||
<circle cx="196" cy="96" r="44" fill="url(#glow)"/>
|
||||
|
||||
<!-- floating ringed planet -->
|
||||
<g opacity="0.95">
|
||||
<circle cx="212" cy="62" r="13" fill="#ffd166"/>
|
||||
<ellipse cx="212" cy="62" rx="24" ry="7" fill="none" stroke="#fff3c4" stroke-width="2" opacity="0.8" transform="rotate(-20 212 62)"/>
|
||||
</g>
|
||||
|
||||
<!-- floating orbs -->
|
||||
<circle cx="34" cy="150" r="7" fill="#ffd166" opacity="0.85"/>
|
||||
<circle cx="224" cy="150" r="4" fill="#ffffff" opacity="0.6"/>
|
||||
<circle cx="46" cy="96" r="3.5" fill="#ffffff" opacity="0.55"/>
|
||||
<circle cx="206" cy="188" r="5" fill="#c25c9e" opacity="0.7"/>
|
||||
|
||||
<!-- sparkles -->
|
||||
<g fill="#ffffff" opacity="0.85">
|
||||
<path d="M44 37 C44.9 43.3 46.7 45.1 53 46 C46.7 46.9 44.9 48.7 44 55 C43.1 48.7 41.3 46.9 35 46 C41.3 45.1 43.1 43.3 44 37 Z"/>
|
||||
<path d="M208 23 C208.7 27.9 210.1 29.3 215 30 C210.1 30.7 208.7 32.1 208 37 C207.3 32.1 205.9 30.7 201 30 C205.9 29.3 207.3 27.9 208 23 Z"/>
|
||||
<path d="M30 202 C30.6 206.2 31.8 207.4 36 208 C31.8 208.6 30.6 209.8 30 214 C29.4 209.8 28.2 208.6 24 208 C28.2 207.4 29.4 206.2 30 202 Z"/>
|
||||
<path d="M226 206 C226.8 211.6 228.4 213.2 234 214 C228.4 214.8 226.8 216.4 226 222 C225.2 216.4 223.6 214.8 218 214 C223.6 213.2 225.2 211.6 226 206 Z"/>
|
||||
<path d="M128 16.5 C128.55 20.35 129.65 21.45 133.5 22 C129.65 22.55 128.55 23.65 128 27.5 C127.45 23.65 126.35 22.55 122.5 22 C126.35 21.45 127.45 20.35 128 16.5 Z"/>
|
||||
<path d="M96 189.5 C96.45 192.65 97.35 193.55 100.5 194 C97.35 194.45 96.45 195.35 96 198.5 C95.55 195.35 94.65 194.45 91.5 194 C94.65 193.55 95.55 192.65 96 189.5 Z"/>
|
||||
</g>
|
||||
|
||||
<!-- koala -->
|
||||
<g>
|
||||
<!-- ears -->
|
||||
<circle cx="74" cy="72" r="30" fill="#9aa5b1"/>
|
||||
<circle cx="74" cy="72" r="16" fill="#d9dee3"/>
|
||||
<circle cx="182" cy="72" r="30" fill="#9aa5b1"/>
|
||||
<circle cx="182" cy="72" r="16" fill="#d9dee3"/>
|
||||
|
||||
<!-- head -->
|
||||
<ellipse cx="128" cy="118" rx="68" ry="62" fill="#a7b2bd"/>
|
||||
|
||||
<!-- eyes -->
|
||||
<circle cx="104" cy="110" r="8" fill="#2b2f36"/>
|
||||
<circle cx="101.5" cy="107" r="2.6" fill="#ffffff"/>
|
||||
<circle cx="152" cy="110" r="8" fill="#2b2f36"/>
|
||||
<circle cx="149.5" cy="107" r="2.6" fill="#ffffff"/>
|
||||
|
||||
<!-- nose -->
|
||||
<ellipse cx="128" cy="140" rx="16" ry="11" fill="#2b2f36"/>
|
||||
<ellipse cx="123" cy="137" rx="4" ry="3" fill="#4b5058"/>
|
||||
|
||||
<!-- mouth -->
|
||||
<path d="M128 151 v6 q0 6 -9 6" fill="none" stroke="#2b2f36" stroke-width="3" stroke-linecap="round"/>
|
||||
<path d="M128 157 q0 6 9 6" fill="none" stroke="#2b2f36" stroke-width="3" stroke-linecap="round"/>
|
||||
</g>
|
||||
|
||||
<!-- wordmark -->
|
||||
<text x="128" y="240" text-anchor="middle"
|
||||
font-family="'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
|
||||
font-size="42" font-weight="700" letter-spacing="-1"
|
||||
fill="#ffffff">lazyrun</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 54 KiB |
@@ -11,8 +11,9 @@ import (
|
||||
"github.com/srwiley/rasterx"
|
||||
)
|
||||
|
||||
// currentColor diisi ke SVG yang memakai fill="currentColor".
|
||||
const currentColor = "#4f46e5"
|
||||
// currentColor diisi ke SVG yang memakai fill="currentColor"
|
||||
// (warna brand: dusk pink, terlihat di background terang maupun gelap).
|
||||
const currentColor = "#c25c9e"
|
||||
|
||||
// Rasterize mengubah SVG menjadi PNG persegi `size`x`size`.
|
||||
//
|
||||
|
||||
@@ -76,9 +76,9 @@ func TestRasterizeColorsCurrentColorIcons(t *testing.T) {
|
||||
if a == 0 {
|
||||
t.Fatal("ikon currentColor tidak terwarnai (transparan)")
|
||||
}
|
||||
// brand indigo #4F46E5: biru > merah > hijau
|
||||
if !(b > r && r > g) {
|
||||
t.Errorf("warna pengganti bukan brand indigo: r=%d g=%d b=%d", r>>8, g>>8, b>>8)
|
||||
// brand dusk pink #C25C9E: merah > biru > hijau
|
||||
if !(r > b && b > g) {
|
||||
t.Errorf("warna pengganti bukan warna brand: r=%d g=%d b=%d", r>>8, g>>8, b>>8)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
|
||||
// pulseGradient membuat garis aksen bergerak bolak-balik antara indigo dan cyan.
|
||||
func pulseGradient(bar *canvas.LinearGradient) {
|
||||
anim := canvas.NewColorRGBAAnimation(brandIndigo, brandCyan, 3*time.Second, func(c color.Color) {
|
||||
anim := canvas.NewColorRGBAAnimation(brandAmber, brandMagenta, 3*time.Second, func(c color.Color) {
|
||||
bar.EndColor = c
|
||||
canvas.Refresh(bar)
|
||||
})
|
||||
|
||||
@@ -32,6 +32,7 @@ type app struct {
|
||||
icons *iconCache
|
||||
count *canvas.Text // angka jumlah shortcut di header daftar
|
||||
versionText *canvas.Text // versi di footer; berubah kalau ada update
|
||||
accent *canvas.LinearGradient
|
||||
version string
|
||||
}
|
||||
|
||||
@@ -87,9 +88,9 @@ func build(a fyne.App, version string) (*app, error) {
|
||||
ui.versionText,
|
||||
)
|
||||
|
||||
accent := accentBar()
|
||||
pulseGradient(accent)
|
||||
top := container.NewVBox(header, accent,
|
||||
ui.accent = accentBar()
|
||||
pulseGradient(ui.accent)
|
||||
top := container.NewVBox(header, ui.accent,
|
||||
container.NewHBox(sectionLabel(T("installed")), countChip))
|
||||
body := container.NewBorder(
|
||||
top,
|
||||
|
||||
@@ -78,7 +78,7 @@ func chipLabel(text string, bg fyne.ThemeColorName) (fyne.CanvasObject, *canvas.
|
||||
|
||||
// accentBar adalah garis gradien brand di bawah header.
|
||||
func accentBar() *canvas.LinearGradient {
|
||||
bar := canvas.NewLinearGradient(brandIndigo, brandCyan, 90)
|
||||
bar := canvas.NewLinearGradient(brandAmber, brandMagenta, 90)
|
||||
bar.SetMinSize(fyne.NewSize(0, 3))
|
||||
return bar
|
||||
}
|
||||
|
||||
@@ -7,10 +7,11 @@ import (
|
||||
"fyne.io/fyne/v2/theme"
|
||||
)
|
||||
|
||||
// Palet brand LazyRun, diambil dari ikon aplikasi.
|
||||
// Palet brand LazyRun, diambil dari logo (dream sky: ungu malam, senja pink, bulan amber).
|
||||
var (
|
||||
brandIndigo = color.NRGBA{R: 0x4F, G: 0x46, B: 0xE5, A: 0xFF}
|
||||
brandCyan = color.NRGBA{R: 0x06, G: 0xB6, B: 0xD4, A: 0xFF}
|
||||
brandPurple = color.NRGBA{R: 0x6A, G: 0x3D, B: 0x9A, A: 0xFF}
|
||||
brandMagenta = color.NRGBA{R: 0xC2, G: 0x5C, B: 0x9E, A: 0xFF}
|
||||
brandAmber = color.NRGBA{R: 0xFF, G: 0xD1, B: 0x66, A: 0xFF}
|
||||
)
|
||||
|
||||
// Nama warna tambahan di luar tema standar Fyne.
|
||||
@@ -31,31 +32,34 @@ func (b brand) Color(name fyne.ThemeColorName, variant fyne.ThemeVariant) color.
|
||||
dark := variant == theme.VariantDark
|
||||
switch name {
|
||||
case theme.ColorNamePrimary:
|
||||
return pick(dark, color.NRGBA{R: 0x7C, G: 0x7A, B: 0xFF, A: 0xFF}, brandIndigo)
|
||||
// senja pink di malam hari, ungu tua di tema terang
|
||||
return pick(dark, brandMagenta, color.NRGBA{R: 0x8E, G: 0x3F, B: 0xA8, A: 0xFF})
|
||||
case theme.ColorNameBackground:
|
||||
return pick(dark, color.NRGBA{R: 0x13, G: 0x13, B: 0x1B, A: 0xFF}, color.NRGBA{R: 0xF5, G: 0xF5, B: 0xFA, A: 0xFF})
|
||||
// langit malam surreal
|
||||
return pick(dark, color.NRGBA{R: 0x14, G: 0x0E, B: 0x24, A: 0xFF}, color.NRGBA{R: 0xF5, G: 0xEF, B: 0xF9, A: 0xFF})
|
||||
case colorNameCard:
|
||||
return pick(dark, color.NRGBA{R: 0x1D, G: 0x1D, B: 0x28, A: 0xFF}, color.NRGBA{R: 0xFF, G: 0xFF, B: 0xFF, A: 0xFF})
|
||||
return pick(dark, color.NRGBA{R: 0x1E, G: 0x16, B: 0x36, A: 0xFF}, color.NRGBA{R: 0xFF, G: 0xFF, B: 0xFF, A: 0xFF})
|
||||
case colorNameCardHover:
|
||||
return withAlpha(brandIndigo, pick[uint8](dark, 0x2E, 0x14))
|
||||
return withAlpha(brandAmber, pick[uint8](dark, 0x1F, 0x18))
|
||||
case theme.ColorNameInputBackground:
|
||||
return pick(dark, color.NRGBA{R: 0x1A, G: 0x1A, B: 0x24, A: 0xFF}, color.NRGBA{R: 0xFF, G: 0xFF, B: 0xFF, A: 0xFF})
|
||||
return pick(dark, color.NRGBA{R: 0x19, G: 0x11, B: 0x35, A: 0xFF}, color.NRGBA{R: 0xFF, G: 0xFF, B: 0xFF, A: 0xFF})
|
||||
case theme.ColorNameButton, theme.ColorNameMenuBackground:
|
||||
return pick(dark, color.NRGBA{R: 0x22, G: 0x22, B: 0x2E, A: 0xFF}, color.NRGBA{R: 0xEC, G: 0xEC, B: 0xF4, A: 0xFF})
|
||||
return pick(dark, color.NRGBA{R: 0x26, G: 0x1B, B: 0x45, A: 0xFF}, color.NRGBA{R: 0xED, G: 0xE3, B: 0xF5, A: 0xFF})
|
||||
case theme.ColorNameOverlayBackground:
|
||||
return pick(dark, color.NRGBA{R: 0x1B, G: 0x1B, B: 0x25, A: 0xFF}, color.NRGBA{R: 0xFF, G: 0xFF, B: 0xFF, A: 0xFF})
|
||||
return pick(dark, color.NRGBA{R: 0x1B, G: 0x13, B: 0x33, A: 0xFF}, color.NRGBA{R: 0xFF, G: 0xFF, B: 0xFF, A: 0xFF})
|
||||
case theme.ColorNameInputBorder, theme.ColorNameSeparator:
|
||||
return pick(dark, color.NRGBA{R: 0x32, G: 0x32, B: 0x44, A: 0xFF}, color.NRGBA{R: 0xDC, G: 0xDC, B: 0xE8, A: 0xFF})
|
||||
return pick(dark, color.NRGBA{R: 0x3A, G: 0x2A, B: 0x63, A: 0xFF}, color.NRGBA{R: 0xDC, G: 0xCF, B: 0xE9, A: 0xFF})
|
||||
case colorNameMuted:
|
||||
return pick(dark, color.NRGBA{R: 0x9C, G: 0x9C, B: 0xB4, A: 0xFF}, color.NRGBA{R: 0x6B, G: 0x6B, B: 0x80, A: 0xFF})
|
||||
return pick(dark, color.NRGBA{R: 0xA7, G: 0x9A, B: 0xC8, A: 0xFF}, color.NRGBA{R: 0x6E, G: 0x61, B: 0x83, A: 0xFF})
|
||||
case colorNameChipMenu:
|
||||
return withAlpha(brandIndigo, pick[uint8](dark, 0x44, 0x26))
|
||||
return withAlpha(brandPurple, pick[uint8](dark, 0x66, 0x2E))
|
||||
case colorNameChipDesk:
|
||||
return withAlpha(brandCyan, pick[uint8](dark, 0x3D, 0x2C))
|
||||
return withAlpha(brandMagenta, pick[uint8](dark, 0x4E, 0x30))
|
||||
case colorNameChipKind:
|
||||
return pick(dark, color.NRGBA{R: 0xFF, G: 0xFF, B: 0xFF, A: 0x1C}, color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x12})
|
||||
return withAlpha(color.NRGBA{R: 0xFF, G: 0xD1, B: 0x66, A: 0xFF}, pick[uint8](dark, 0x24, 0x30))
|
||||
case colorNameChipBroken:
|
||||
return withAlpha(color.NRGBA{R: 0xE0, G: 0x4F, B: 0x4F, A: 0xFF}, pick[uint8](dark, 0x4A, 0x2E))
|
||||
// merah senja: peringatan yang tetap terasa "seram" tapi terbaca
|
||||
return withAlpha(color.NRGBA{R: 0xD9, G: 0x46, B: 0x3C, A: 0xFF}, pick[uint8](dark, 0x50, 0x30))
|
||||
}
|
||||
return b.Theme.Color(name, variant)
|
||||
}
|
||||
|
||||