HTML
<section class="sn-rai" aria-label="Vertical rail menu demo">
<input type="checkbox" id="sn-rai-x" class="toggle" aria-label="Toggle rail">
<nav class="rail" aria-label="Player navigation">
<div class="mark" aria-hidden="true">◊</div>
<a class="pill active" href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z"/></svg><span class="lbl">Home</span><span class="tip">Home</span></a>
<a class="pill" href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.3-4.3"/></svg><span class="lbl">Discover</span><span class="tip">Discover</span></a>
<a class="pill" href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><path d="M9 18V5l12-2v13"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="16" r="3"/></svg><span class="lbl">Your Library</span><span class="tip">Library</span></a>
<a class="pill" href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><path d="M19 21l-7-5-7 5V5a2 2 0 012-2h10a2 2 0 012 2z"/></svg><span class="lbl">Saved</span><span class="tip">Saved</span></a>
<a class="pill" href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><path d="M4 11a9 9 0 019 9M4 4a16 16 0 0116 16"/><circle cx="5" cy="19" r="1"/></svg><span class="lbl">Radio</span><span class="tip">Radio</span></a>
<div class="spacer"></div>
<a class="pill" href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 01-2.83 2.83l-.06-.06a1.65 1.65 0 00-2.82 1.17V21a2 2 0 01-4 0v-.09A1.65 1.65 0 007 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 11-2.83-2.83l.06-.06A1.65 1.65 0 004.6 14H4.5a2 2 0 010-4h.09A1.65 1.65 0 006 8.6"/></svg><span class="lbl">Settings</span><span class="tip">Settings</span></a>
<label for="sn-rai-x" class="ctrl" title="Expand rail" aria-label="Expand rail">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><path d="M9 18l6-6-6-6" stroke-width="2" stroke-linecap="round"/></svg>
</label>
</nav>
<main class="stage">
<div class="nowplaying">
<div class="cover" aria-hidden="true"></div>
<div>
<h1>Flexible Rail Menu</h1>
<p>An expanding icon rail — bouncy, springy, collapsible.</p>
<div class="bars" aria-hidden="true"><i></i><i></i><i></i><i></i><i></i></div>
</div>
</div>
</main>
</section> CSS
/* ─── 03 Vertical Rail Menu — neon music player ───────────── */
@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;700&family=Syne:wght@600;800&display=swap');
.sn-rai {
--sn-rai-bg: #08070d;
--sn-rai-rail: #0f0d18;
--sn-rai-rail-2: #17142a;
--sn-rai-txt: #e8e6f0;
--sn-rai-muted: #7b7790;
--sn-rai-neon: #c4f82a;
--sn-rai-pink: #ff4d8c;
--sn-rai-cyan: #39e0ff;
position: relative;
width: 100%;
height: 600px;
font-family: 'Outfit', sans-serif;
background:
radial-gradient(700px 700px at 100% 100%, rgba(255,77,140,.12), transparent 60%),
radial-gradient(700px 700px at 0% 0%, rgba(57,224,255,.1), transparent 55%),
var(--sn-rai-bg);
color: var(--sn-rai-txt);
display: flex;
overflow: hidden;
box-sizing: border-box;
}
.sn-rai *, .sn-rai *::before, .sn-rai *::after { box-sizing: border-box; margin: 0; padding: 0; }
.sn-rai .toggle { display: none; }
.sn-rai .rail {
width: 84px;
background: linear-gradient(180deg, var(--sn-rai-rail), var(--sn-rai-rail-2));
border-right: 1px solid rgba(255,255,255,.06);
height: 100%;
display: flex; flex-direction: column; align-items: center;
padding: 1.3rem 0; gap: .5rem;
transition: width .35s cubic-bezier(.34,1.56,.64,1);
overflow: hidden;
flex-shrink: 0;
}
.sn-rai .mark {
width: 44px; height: 44px; border-radius: 14px; flex-shrink: 0;
background: linear-gradient(135deg, var(--sn-rai-neon), var(--sn-rai-cyan));
display: grid; place-items: center; color: #08070d;
font-family: 'Syne'; font-weight: 800; font-size: 1.3rem; margin-bottom: 1rem;
box-shadow: 0 0 24px rgba(196,248,42,.4);
}
.sn-rai .pill {
width: 90%; display: flex; align-items: center; gap: 1rem;
padding: .75rem; border-radius: 14px; text-decoration: none; color: var(--sn-rai-muted);
position: relative; transition: .25s; white-space: nowrap;
}
.sn-rai .pill svg { width: 24px; height: 24px; min-width: 24px; stroke-width: 1.8; }
.sn-rai .pill .lbl { font-size: .95rem; font-weight: 500; opacity: 0; transition: opacity .25s; }
.sn-rai .pill:hover { color: var(--sn-rai-txt); background: rgba(255,255,255,.04); }
.sn-rai .pill.active { color: var(--sn-rai-neon); background: rgba(196,248,42,.1); }
.sn-rai .pill.active::after {
content: ""; position: absolute; right: -.65rem; top: 50%; transform: translateY(-50%);
width: 4px; height: 60%; border-radius: 4px; background: var(--sn-rai-neon);
box-shadow: 0 0 12px var(--sn-rai-neon);
}
.sn-rai .tip {
position: absolute; left: 72px; top: 50%; transform: translateY(-50%) scale(.8);
background: #fff; color: #08070d; font-size: .78rem; font-weight: 600;
padding: .35rem .7rem; border-radius: 8px; opacity: 0; pointer-events: none;
transition: .2s; white-space: nowrap; z-index: 5;
}
.sn-rai .pill:hover .tip { opacity: 1; transform: translateY(-50%) scale(1); }
.sn-rai .spacer { flex: 1; }
.sn-rai .ctrl {
margin-top: .8rem; width: 44px; height: 44px; border-radius: 12px; flex-shrink: 0;
background: rgba(255,255,255,.05); border: none; cursor: pointer; color: var(--sn-rai-muted);
display: grid; place-items: center; transition: .25s;
}
.sn-rai .ctrl:hover { color: var(--sn-rai-neon); background: rgba(196,248,42,.1); }
.sn-rai .ctrl svg { width: 22px; height: 22px; transition: transform .35s; }
/* expanded */
.sn-rai .toggle:checked ~ .rail { width: 248px; align-items: stretch; padding-left: 1rem; padding-right: 1rem; }
.sn-rai .toggle:checked ~ .rail .pill .lbl { opacity: 1; }
.sn-rai .toggle:checked ~ .rail .pill:hover .tip { display: none; }
.sn-rai .toggle:checked ~ .rail .ctrl svg { transform: rotate(180deg); }
.sn-rai .toggle:checked ~ .rail .mark { margin-left: .4rem; }
.sn-rai .stage { flex: 1; padding: 3rem; display: flex; flex-direction: column; justify-content: flex-end; min-width: 0; overflow: hidden; }
.sn-rai .nowplaying { display: flex; align-items: center; gap: 1.4rem; }
.sn-rai .cover { width: 120px; height: 120px; border-radius: 20px; flex-shrink: 0;
background: conic-gradient(from 45deg, var(--sn-rai-pink), var(--sn-rai-cyan), var(--sn-rai-neon), var(--sn-rai-pink));
box-shadow: 0 18px 50px rgba(255,77,140,.25); }
.sn-rai .stage h1 { font-family: 'Syne'; font-weight: 800; font-size: 2.4rem; letter-spacing: -.02em; }
.sn-rai .stage p { color: var(--sn-rai-muted); margin-top: .3rem; }
.sn-rai .bars { display: flex; gap: 4px; margin-top: 1.4rem; align-items: flex-end; height: 38px; }
.sn-rai .bars i { width: 5px; background: var(--sn-rai-neon); border-radius: 3px; animation: sn-rai-b 1s ease-in-out infinite; }
.sn-rai .bars i:nth-child(2) { animation-delay: .2s; background: var(--sn-rai-cyan); }
.sn-rai .bars i:nth-child(3) { animation-delay: .4s; background: var(--sn-rai-pink); }
.sn-rai .bars i:nth-child(4) { animation-delay: .1s; }
.sn-rai .bars i:nth-child(5) { animation-delay: .5s; background: var(--sn-rai-cyan); }
@keyframes sn-rai-b { 0%, 100% { height: 10px; } 50% { height: 38px; } }
@media (prefers-reduced-motion: reduce) {
.sn-rai .rail, .sn-rai .pill, .sn-rai .tip { transition: none; }
.sn-rai .bars i { animation: none; height: 24px; }
}