feat(admin): add volumen icon and use it in sidebar and login
This commit is contained in:
@@ -109,6 +109,10 @@ module Volumen
|
||||
send_file(File.expand_path("web/public/volumen-logo.svg", __dir__))
|
||||
end
|
||||
|
||||
app.get "/admin/icon.svg" do
|
||||
send_file(File.expand_path("web/public/volumen-icon.svg", __dir__))
|
||||
end
|
||||
|
||||
app.get "/admin/settings" do
|
||||
require_login!
|
||||
@crumbs = [["Settings", nil]]
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" role="img" aria-label="volumen">
|
||||
<title>volumen</title>
|
||||
|
||||
<defs>
|
||||
<!-- Background gradient: deep night sky -->
|
||||
<radialGradient id="bg" cx="50%" cy="35%" r="80%">
|
||||
<stop offset="0%" stop-color="#4a5bd8"/>
|
||||
<stop offset="55%" stop-color="#2a2d6e"/>
|
||||
<stop offset="100%" stop-color="#15163a"/>
|
||||
</radialGradient>
|
||||
|
||||
<!-- Subtle inner ring gradient -->
|
||||
<linearGradient id="ring" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#8aa0ff" stop-opacity="0.9"/>
|
||||
<stop offset="100%" stop-color="#3b3f8a" stop-opacity="0.6"/>
|
||||
</linearGradient>
|
||||
|
||||
<!-- Glossy highlight at the top -->
|
||||
<radialGradient id="gloss" cx="50%" cy="15%" r="55%">
|
||||
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.35"/>
|
||||
<stop offset="60%" stop-color="#ffffff" stop-opacity="0.05"/>
|
||||
<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
|
||||
<!-- Wave stroke gradient -->
|
||||
<linearGradient id="wave" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stop-color="#7afcff" stop-opacity="0.15"/>
|
||||
<stop offset="50%" stop-color="#7afcff" stop-opacity="0.95"/>
|
||||
<stop offset="100%" stop-color="#7afcff" stop-opacity="0.15"/>
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient id="waveDim" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stop-color="#ffffff" stop-opacity="0.05"/>
|
||||
<stop offset="50%" stop-color="#ffffff" stop-opacity="0.35"/>
|
||||
<stop offset="100%" stop-color="#ffffff" stop-opacity="0.05"/>
|
||||
</linearGradient>
|
||||
|
||||
<!-- Central V fill gradient -->
|
||||
<linearGradient id="vFill" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#fdfdff"/>
|
||||
<stop offset="100%" stop-color="#b8c4ff"/>
|
||||
</linearGradient>
|
||||
|
||||
<!-- Soft drop shadow -->
|
||||
<filter id="softShadow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feGaussianBlur in="SourceAlpha" stdDeviation="2"/>
|
||||
<feOffset dx="0" dy="2" result="off"/>
|
||||
<feComponentTransfer>
|
||||
<feFuncA type="linear" slope="0.5"/>
|
||||
</feComponentTransfer>
|
||||
<feMerge>
|
||||
<feMergeNode/>
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
|
||||
<!-- Outer glow for the disc -->
|
||||
<filter id="outerGlow" x="-30%" y="-30%" width="160%" height="160%">
|
||||
<feGaussianBlur stdDeviation="4"/>
|
||||
</filter>
|
||||
|
||||
<!-- Reusable wave path (sinusoidal, centered around y=128) -->
|
||||
<path id="wavePath"
|
||||
d="M 36 128
|
||||
C 56 96, 76 96, 96 128
|
||||
S 136 160, 156 128
|
||||
S 196 96, 216 128"
|
||||
fill="none"/>
|
||||
</defs>
|
||||
|
||||
<!-- ===== Outer glow halo ===== -->
|
||||
<circle cx="128" cy="128" r="116" fill="url(#bg)" opacity="0.55" filter="url(#outerGlow)"/>
|
||||
|
||||
<!-- ===== Main disc ===== -->
|
||||
<circle cx="128" cy="128" r="112" fill="url(#bg)"/>
|
||||
|
||||
<!-- Inner decorative ring -->
|
||||
<circle cx="128" cy="128" r="104" fill="none" stroke="url(#ring)" stroke-width="1.2" opacity="0.7"/>
|
||||
|
||||
<!-- Dotted ring (tick marks) -->
|
||||
<g fill="#8aa0ff" opacity="0.55">
|
||||
<circle cx="128" cy="22" r="1.4"/>
|
||||
<circle cx="180" cy="32" r="1.2"/>
|
||||
<circle cx="220" cy="62" r="1.4"/>
|
||||
<circle cx="234" cy="110" r="1.2"/>
|
||||
<circle cx="234" cy="146" r="1.4"/>
|
||||
<circle cx="220" cy="194" r="1.2"/>
|
||||
<circle cx="180" cy="224" r="1.4"/>
|
||||
<circle cx="128" cy="234" r="1.2"/>
|
||||
<circle cx="76" cy="224" r="1.4"/>
|
||||
<circle cx="36" cy="194" r="1.2"/>
|
||||
<circle cx="22" cy="146" r="1.4"/>
|
||||
<circle cx="22" cy="110" r="1.2"/>
|
||||
<circle cx="36" cy="62" r="1.4"/>
|
||||
<circle cx="76" cy="32" r="1.2"/>
|
||||
</g>
|
||||
|
||||
<!-- ===== Waves (background layer) ===== -->
|
||||
<g stroke-linecap="round" fill="none">
|
||||
<use href="#wavePath" stroke="url(#waveDim)" stroke-width="1.2"
|
||||
transform="translate(0,-46)" opacity="0.6"/>
|
||||
<use href="#wavePath" stroke="url(#waveDim)" stroke-width="1.2"
|
||||
transform="translate(0,46)" opacity="0.6"/>
|
||||
</g>
|
||||
|
||||
<!-- ===== Central stylized "V" ===== -->
|
||||
<g filter="url(#softShadow)">
|
||||
<!-- Main V shape, geometric, with a small notch at the bottom for a leaf/quill hint -->
|
||||
<path d="
|
||||
M 78 70
|
||||
L 110 70
|
||||
L 128 142
|
||||
L 146 70
|
||||
L 178 70
|
||||
L 138 186
|
||||
L 118 186
|
||||
Z"
|
||||
fill="url(#vFill)"/>
|
||||
|
||||
<!-- Inner accent line on the V -->
|
||||
<path d="M 118 186 L 128 142 L 138 186"
|
||||
fill="none" stroke="#2a2d6e" stroke-width="1.2" stroke-linejoin="round" opacity="0.35"/>
|
||||
|
||||
<!-- Subtle highlight stripe on the left arm of V -->
|
||||
<path d="M 82 74 L 108 74 L 100 100 Z"
|
||||
fill="#ffffff" opacity="0.25"/>
|
||||
</g>
|
||||
|
||||
<!-- ===== Foreground waves crossing the V ===== -->
|
||||
<g stroke-linecap="round" fill="none">
|
||||
<use href="#wavePath" stroke="url(#wave)" stroke-width="3.2" opacity="0.9"/>
|
||||
<use href="#wavePath" stroke="url(#wave)" stroke-width="1.6"
|
||||
transform="translate(0,18)" opacity="0.7"/>
|
||||
<use href="#wavePath" stroke="url(#wave)" stroke-width="1.6"
|
||||
transform="translate(0,-18)" opacity="0.7"/>
|
||||
</g>
|
||||
|
||||
<!-- ===== Sparkles / dots ===== -->
|
||||
<g fill="#ffffff">
|
||||
<circle cx="60" cy="92" r="1.8" opacity="0.95"/>
|
||||
<circle cx="196" cy="92" r="1.6" opacity="0.85"/>
|
||||
<circle cx="200" cy="168" r="1.4" opacity="0.8"/>
|
||||
<circle cx="58" cy="172" r="1.4" opacity="0.8"/>
|
||||
<circle cx="156" cy="58" r="1.2" opacity="0.7"/>
|
||||
<circle cx="100" cy="206" r="1.2" opacity="0.7"/>
|
||||
</g>
|
||||
|
||||
<!-- Four-point sparkle (north star) -->
|
||||
<g transform="translate(70,70)" fill="#ffffff" opacity="0.9">
|
||||
<path d="M 0 -7 L 1.4 -1.4 L 7 0 L 1.4 1.4 L 0 7 L -1.4 1.4 L -7 0 L -1.4 -1.4 Z"/>
|
||||
</g>
|
||||
<g transform="translate(190,190) scale(0.7)" fill="#ffffff" opacity="0.8">
|
||||
<path d="M 0 -7 L 1.4 -1.4 L 7 0 L 1.4 1.4 L 0 7 L -1.4 1.4 L -7 0 L -1.4 -1.4 Z"/>
|
||||
</g>
|
||||
|
||||
<!-- ===== Glossy top highlight ===== -->
|
||||
<circle cx="128" cy="128" r="112" fill="url(#gloss)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.8 KiB |
@@ -63,10 +63,7 @@
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.sidebar-head .logo {
|
||||
width: 28px; height: 28px; display: grid; place-items: center;
|
||||
background: var(--accent); color: var(--on-accent);
|
||||
border-radius: 8px; font-weight: 700; font-size: 0.85rem;
|
||||
letter-spacing: -0.02em;
|
||||
width: 28px; height: 28px; display: block; flex-shrink: 0;
|
||||
}
|
||||
.sidebar-head .name {
|
||||
font-size: 0.95rem; font-weight: 600; letter-spacing: -0.01em;
|
||||
@@ -496,9 +493,7 @@
|
||||
display: flex; align-items: center; gap: 0.6rem; font-size: 1rem; font-weight: 600; letter-spacing: -0.01em;
|
||||
}
|
||||
.login-side .brand-mark .logo {
|
||||
width: 32px; height: 32px; display: grid; place-items: center;
|
||||
background: rgba(255,255,255,0.2); border-radius: 8px; backdrop-filter: blur(8px);
|
||||
font-weight: 700;
|
||||
width: 32px; height: 32px; display: block;
|
||||
}
|
||||
.login-side .pitch { max-width: 480px; }
|
||||
.login-side .pitch h1 { font-size: 2.5rem; font-weight: 700; letter-spacing: -0.03em; line-height: 1.1; margin: 0 0 1rem; }
|
||||
@@ -559,7 +554,7 @@
|
||||
<div class="login-page">
|
||||
<aside class="login-side">
|
||||
<div class="brand-mark">
|
||||
<span class="logo">V</span>
|
||||
<img class="logo" src="<%= to('/admin/icon.svg') %>" alt="volumen">
|
||||
<span>volumen</span>
|
||||
</div>
|
||||
<div class="pitch">
|
||||
@@ -591,7 +586,7 @@
|
||||
<div class="shell">
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-head">
|
||||
<div class="logo">V</div>
|
||||
<img class="logo" src="<%= to('/admin/icon.svg') %>" alt="volumen">
|
||||
<div class="name">volumen</div>
|
||||
</div>
|
||||
<% if authenticated? %>
|
||||
|
||||
Reference in New Issue
Block a user