Persona 5-Inspired Geometric Wobble Hover

Not an exact recreation but a similar effect.

STATUS
<style>
.lab {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.menu {
    display: flex;
    flex-direction: column;
    gap: 30px;
}

.menu-item {
    position: relative;
    font-family: 'Arial Black', sans-serif;
    font-size: 3rem;
    letter-spacing: 0.25em;
    color: #fff;
    cursor: pointer;
    padding: 0.25em 0.5em;
    z-index: 1;
}

.menu-item::before,
.menu-item::after {
    content: '';
    position: absolute;
    inset: -12px;
    z-index: 0;
    transform: skewX(-14deg);
    opacity: 0;
}

.menu-item::before {
    background: #ff1b1b;
}

.menu-item::after {
    background: #fff;
    inset: -6px;
}

.menu-item.active::before {
    opacity: 1;
    animation:
        liquidRed 2.6s ease-in-out infinite,
        jitterRed 0.25s steps(1,end);
}

.menu-item.active::after {
    opacity: 1;
    animation:
        liquidWhite 3s ease-in-out infinite,
        jitterWhite 0.25s steps(1,end);
}

.menu-item.active {
    animation: textPop 0.18s steps(1,end);
}
</style>
</head>

<body>

<div class="lab">
    <div class="menu">
        <div class="menu-item" onclick="select(this)">STATUS</div>
        <div class="menu-item" onclick="select(this)">EQUIPMENT</div>
        <div class="menu-item" onclick="select(this)">SKILLS</div>
        <div class="menu-item" onclick="select(this)">MAP</div>
    </div>
</div>

<script>
function select(el) {
    document.querySelectorAll('.menu-item')
        .forEach(i => i.classList.remove('active'));
    el.classList.add('active');
}
</script>

Subtitle Hover Reveal

Secondary text appears beneath main text on hover.

ARCHIVE
Data Log
<div class="subtitle-demo">
    <div class="subtitle-main">ARCHIVE</div>
    <div class="subtitle-sub">Data Log</div>
</div>

</style>
.subtitle-demo {
    text-align: center;
}

.subtitle-main {
    font-size: 2.5rem;
    cursor: pointer;
}

.subtitle-sub {
    font-family: 'ArsenalBold';
    font-size: 0.9rem;
    letter-spacing: 0.15em;
    margin-top: 6px;
    background: #000;
    padding: 0.3em 0.6em;
    display: inline-block;

    opacity: 0;
    transform: translateY(-6px) scale(0.8);
    transition: 0.25s cubic-bezier(0.34,1.56,0.64,1);
}

.subtitle-demo:hover .subtitle-sub {
    opacity: 1;
    transform: translateY(0) scale(1);
}
</style>

Shooting Stars Title

Make a wish or something I don't know.

SHOOTING STARS
<style>
.star-title-wrap {
    position: relative;
    padding: 80px 120px;
    overflow: hidden;
}

.star-title {
    font-size: 4.5rem;
    letter-spacing: 0.25em;
    text-transform: uppercase;
    color: #f5f7ff;
    position: relative;
    z-index: 5;
    text-shadow:
        0 0 10px rgba(180,200,255,0.4),
        0 0 30px rgba(120,160,255,0.25);
}

.star-field {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 1;
}

.shooting-star {
    position: absolute;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #fff;
    box-shadow:
        0 0 10px rgba(255,255,255,1),
        0 0 24px rgba(200,220,255,0.9),
        0 0 48px rgba(160,190,255,0.8);
    opacity: 0;
    transform: rotate(-45deg);
}

.shooting-star::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 8px;
    height: 4px;
    width: 0;
    transform: translateY(-50%);
    border-radius: 999px;
    background: linear-gradient(
        90deg,
        rgba(255,255,255,0),
        rgba(200,220,255,0.8),
        rgba(160,190,255,0.5),
        rgba(120,160,255,0)
    );
    filter: blur(1.5px);
    animation: tailGrow 1.5s ease-out infinite;
}

@keyframes tailGrow {
    0%   { width: 0; opacity: 0; }
    20%  { width: 140px; opacity: 1; }
    45%  { width: 260px; opacity: 1; }
    75%  { width: 160px; opacity: 0.8; }
    100% { width: 40px; opacity: 0; }
}

@keyframes starShoot {
    0% {
        transform: translate(420px, -80px) rotate(-45deg);
        opacity: 0;
    }
    10% { opacity: 1; }
    100% {
        transform: translate(-160px, 360px) rotate(-45deg);
        opacity: 0;
    }
}
</style>

<script>
const field = document.getElementById('starField');

function spawnShootingStar() {
    const star = document.createElement('div');
    star.className = 'shooting-star';

    star.style.top = Math.random() * 60 - 10 + '%';
    star.style.left = Math.random() * 100 - 10 + '%';

    star.style.animation =
        'starShoot 1.05s cubic-bezier(0.25, 0.8, 0.3, 1) forwards';

    if (Math.random() > 0.85) {
        star.style.filter = 'brightness(1.4)';
    }

    field.appendChild(star);
    setTimeout(() => star.remove(), 1700);
}

setInterval(spawnShootingStar, 1600);
</script>