Files
sharper.ly/apps/web/app/components/ui/Navigation/Navigation.css
T

82 lines
2.8 KiB
CSS

/* ============================================================================
NAVIGATION - the dropdown's opening motion
----------------------------------------------------------------------------
The redesign opens each group's menu with a short fade and an 8px settle
("menuIn" in the draft). It lives here rather than in the page kit because
the navigation is a design-system component and must not depend on a route
module's stylesheet.
`:not([hidden])` is what replays it: the panel is hidden with the `hidden`
attribute, so the animation runs each time the group opens instead of once
per mount. app.css collapses it to 0.01ms under prefers-reduced-motion.
========================================================================= */
@layer theme, base, components, utilities;
@layer components {
.sh-nav-menu:not([hidden]) {
animation: sh-nav-menu-in var(--motion-duration-base)
var(--motion-ease-entrance) both;
}
/* The "-ER" after "SHARP" in the brand, sliding out from behind the P and
fading in once the page has settled. The same reveal the home hero used to
run on its wordmark, now owned by the navigation. The suffix sits in its
own box whose inline-start edge is the P's right edge, and that box clips;
the mark starts a full box-width back - entirely beside "SHARP", so
nothing overlaps it - and travels forward to rest, with the opacity
reaching 1 before the travel ends, so the glyphs read as solid for the
last, slowest part of the decelerating slide. The translate is physical
(translateX) on purpose: the lockup row is pinned to dir="ltr" because a
Latin wordmark never mirrors, so the P is always left of the suffix, in
Arabic too. Pure CSS, so it runs from the server-rendered HTML without
waiting for hydration, and the `both` fill keeps the suffix hidden through
the delay instead of flashing in first. It replays whenever the navigation
mounts again, e.g. on a client-side navigation back to a page. Under
prefers-reduced-motion the animation is removed outright - app.css only
collapses the duration and would leave the delay holding the suffix
hidden - so the full name is simply there from the start. */
.sh-brand-suffix {
overflow: hidden;
}
.sh-brand-suffix__mark {
animation: sh-brand-suffix-in var(--motion-duration-reveal)
var(--motion-ease-entrance) var(--motion-delay-reveal) both;
}
@media (prefers-reduced-motion: reduce) {
.sh-brand-suffix__mark {
animation: none;
}
}
}
@keyframes sh-brand-suffix-in {
from {
opacity: 0;
transform: translateX(-100%);
}
60% {
opacity: 1;
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes sh-nav-menu-in {
from {
opacity: 0;
transform: translateY(-8px);
}
to {
opacity: 1;
transform: none;
}
}