changed hero styling, added animations
This commit is contained in:
@@ -11,7 +11,7 @@ This site demonstrates my personality, skills, and presents the tone I provide t
|
||||
|
||||
**STACK**
|
||||
|
||||
- SPA with React (functonal components, hooks)
|
||||
- SPA with React (functional components, hooks)
|
||||
- TailwindCSS (custom tokens and theme system)
|
||||
- Theme Engine (5 themes with automated color adaption per user preference )
|
||||
- IntersectionObserver (based scroll nav)
|
||||
@@ -37,7 +37,7 @@ src/
|
||||
## Theme System
|
||||
|
||||
### within index:
|
||||
#### 5 unique themes are layed out by:
|
||||
#### 5 unique themes are laid out by:
|
||||
- color-bg
|
||||
- color-primary
|
||||
- color-text
|
||||
@@ -50,7 +50,7 @@ These themes are applied via html[data-theme="x"] and are used across the site f
|
||||
## DEV NOTES as of 10/29/2025
|
||||
|
||||
- All social links are dummy values as of now.
|
||||
- Section layout is controlleted via <Section id="...."></Section> wrappers.
|
||||
- Section layout is controlled via <Section id="...."></Section> wrappers.
|
||||
- Images are outdated and will be replaced.
|
||||
- UI is mobile-oriented, but device friendly.
|
||||
|
||||
@@ -58,7 +58,7 @@ These themes are applied via html[data-theme="x"] and are used across the site f
|
||||
## TODO
|
||||
|
||||
- Add links to projects within cards
|
||||
- Change out experiance tab for resume/skills
|
||||
- Change out experience tab for resume/skills
|
||||
- Add animations
|
||||
- more ways to contact
|
||||
- Deploy site via personal service
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 375 KiB |
@@ -19,14 +19,24 @@ export function Footer({
|
||||
<footer className="border-t border-secondary bg-bg px-4 py-10">
|
||||
<div className="mx-auto flex max-w-7xl flex-col items-center justify-between gap-6 md:flex-row">
|
||||
<div className="text-center md:text-left">
|
||||
<div className="text-xl font-extrabold tracking-wide text-text">Jody Holt</div>
|
||||
<p className="text-sm text-text/70">Passion Pioneer</p>
|
||||
<div className="text-xl md:text-2xl font-extrabold font-name tracking-wide text-text">
|
||||
Jody Holt
|
||||
</div>
|
||||
<div className="text-[11px] md:text-sm text-text/70">
|
||||
Passion Pioneer
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav className="flex items-center gap-5">
|
||||
<a className="text-text hover:text-primary" href="#projects">Projects</a>
|
||||
<a className="text-text hover:text-primary" href="#experience">Experience</a>
|
||||
<a className="text-text hover:text-primary" href="#home">Background</a>
|
||||
<a className="text-text hover:text-primary" href="#projects">
|
||||
Projects
|
||||
</a>
|
||||
<a className="text-text hover:text-primary" href="#experience">
|
||||
Experience
|
||||
</a>
|
||||
<a className="text-text hover:text-primary" href="#home">
|
||||
Background
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<div className="flex items-center gap-4 text-text">
|
||||
@@ -38,14 +48,18 @@ export function Footer({
|
||||
className="inline-flex h-10 w-10 items-center justify-center rounded-lg border border-secondary hover:border-primary hover:text-primary"
|
||||
title={s.label}
|
||||
>
|
||||
{s.icon ?? <span className="h-2.5 w-2.5 rounded-full bg-current" />}
|
||||
{s.icon ?? (
|
||||
<span className="h-2.5 w-2.5 rounded-full bg-current" />
|
||||
)}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mx-auto mt-6 flex max-w-7xl items-center justify-center gap-4">
|
||||
<div className="text-center text-xs text-text/60">© {year} Jody Holt • All rights reserved</div>
|
||||
<div className="text-center text-xs text-text/60">
|
||||
© {year} Jody Holt • All rights reserved
|
||||
</div>
|
||||
{showBackToTop && (
|
||||
<button
|
||||
onClick={() => window.scrollTo({ top: 0, behavior: "smooth" })}
|
||||
@@ -57,4 +71,4 @@ export function Footer({
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,47 +1,45 @@
|
||||
import React from "react";
|
||||
import profileImage from "../assets/jody.png";
|
||||
import jodyMobile from "../assets/Jody-mobile.png";
|
||||
|
||||
import { useTheme } from "../hooks/useTheme";
|
||||
export function Hero() {
|
||||
const { theme } = useTheme(); // "a" | "b" | "c" | "d" | "e"
|
||||
return (
|
||||
<section className="relative w-full bg-hero">
|
||||
<section key={theme} className="relative w-full bg-hero anim-fade-in">
|
||||
<div className="md:hidden flex flex-col items-center text-center gap-2 min-h-[calc(100vh-64px)] py-6">
|
||||
<h1
|
||||
className="font-extrabold font-title tracking-wide leading-tight text-text
|
||||
text-2xl underline md:decoration-secondary decoration-primary"
|
||||
text-2xl underline md:decoration-secondary decoration-primary anim-pop-in"
|
||||
>
|
||||
Design. Develop. Deliver.
|
||||
</h1>
|
||||
|
||||
<p className=" font-main text-sm text-text/80">
|
||||
<p className=" font-main text-sm text-text/80 anim-fade-in">
|
||||
Driven by a genuine passion for creation through code.
|
||||
</p>
|
||||
|
||||
<div className="relative h-68 w-68 rounded-full overflow-hidden mb-2">
|
||||
<div className="relative h-48 w-48 rounded-full overflow-hidden mb-2 anim-pop-in float-idle">
|
||||
<div className="absolute inset-0 rounded-full img-glow" />
|
||||
|
||||
<div className="absolute inset-0 rounded-full img-glow" />
|
||||
<img
|
||||
src={jodyMobile}
|
||||
alt="Jody Holt"
|
||||
className="relative z-[1] h-full w-full object-cover select-none pointer-events-none will-change-transform"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
<img
|
||||
src={jodyMobile}
|
||||
alt="Jody Holt"
|
||||
className="relative z-[1] h-full w-full object-cover select-none pointer-events-none"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<h2 className="mt- font-extrabold font-title text-text leading-tight tracking-wide text-3xl">
|
||||
<h2 className="mt- font-extrabold font-title text-text leading-tight tracking-wide text-3xl anim-fade-in">
|
||||
Hello, I’m Jody Holt
|
||||
</h2>
|
||||
|
||||
<p className=" font-main mt-5 text-lg text-base text-text/85">
|
||||
<p className=" font-main mt-2 text-[22px] text-base text-text/85 anim-fade-in">
|
||||
Turning concepts into clean, functional code.
|
||||
</p>
|
||||
|
||||
<p className=" font-main text-2xl font-semibold text-text mt-4">It’s What I Do.</p>
|
||||
|
||||
|
||||
|
||||
<p className="mt-8 text-2xl text-text font-main ">I would love to connect!</p>
|
||||
|
||||
<div className="mt-2 mb-4 flex items-center justify-center gap-4">
|
||||
<div className="mt-5 mb-4 flex items-center justify-center gap-4">
|
||||
{[
|
||||
{ label: "GitHub", href: "#" },
|
||||
{ label: "LinkedIn", href: "#" },
|
||||
@@ -51,7 +49,10 @@ export function Hero() {
|
||||
key={a.label}
|
||||
href={a.href}
|
||||
aria-label={a.label}
|
||||
className="inline-flex h-12 w-12 items-center justify-center rounded-lg border border-secondary/70 bg-secondary/20 text-text hover:border-primary hover:text-primary transition"
|
||||
className="inline-flex h-12 w-12 items-center justify-center rounded-lg
|
||||
border border-secondary/70 bg-secondary/20 text-text anim-base icon-hover
|
||||
hover:border-primary hover:text-primary focus:outline-none focus-visible:ring-2
|
||||
focus-visible:ring-primary/60"
|
||||
>
|
||||
<span className="h-3 w-3 rounded-full bg-current" />
|
||||
</a>
|
||||
@@ -59,79 +60,58 @@ export function Hero() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/*DESKTOP*/}
|
||||
{/*____________________________________________________________________________________________________*/}
|
||||
<div
|
||||
className=" md:flex md:flex-col items-center hidden md: md:mx-auto px-4 w-full sm:h-[calc(100vh-80px)]
|
||||
overflow-hidden"
|
||||
>
|
||||
<h1
|
||||
className="text-text font-extrabold tracking-wide leading-tight
|
||||
text-3xl sm:text-4xl md:text-3xl lg:text-5xl xl:text-6xl
|
||||
underline md:decoration-secondary decoration-primary font-title
|
||||
text-center lg:pt-2 xl:pt-7 anim-pop-in "
|
||||
>
|
||||
Design. Develop. Deliver.
|
||||
</h1>
|
||||
<p
|
||||
className="text-text/80 text-sm sm:text-base md:text-lg lg:text-xl xl:text-2xl
|
||||
font-main text-center anim-fade-in"
|
||||
>
|
||||
Driven by a genuine passion for creation through code.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{/*DESKTOP*/}
|
||||
{/*____________________________________________________________________________________________________*/}
|
||||
<div className="hidden md:block md:mx-auto max-w-7xl px-4">
|
||||
<div
|
||||
className="
|
||||
min-h-[calc(100vh-64px)]
|
||||
md:min-h-[calc(100vh-80px)]
|
||||
flex flex-col md:flex-row items-start gap-10 lg:gap-10
|
||||
py-8 md:py-1
|
||||
"
|
||||
flex items-center justify-evenly
|
||||
w-full max-h-[calc(auto-400px) lg:px-5 xl:px-20"
|
||||
>
|
||||
<div className="shrink-0 self-start lg:pl-20">
|
||||
<img
|
||||
src={profileImage}
|
||||
alt="Jody Holt"
|
||||
className="w-[240px] sm:h-[280px] md:h-[700px] lg:h-[780px] xl:g-[800px] h-auto object-contain select-none pointer-events-none"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 self-start md:pt-10 items-center text-center">
|
||||
<h1
|
||||
className="text-text font-extrabold tracking-wide leading-tight
|
||||
text-3xl sm:text-4xl md:text-3xl lg:text-5xl xl:text-6xl underline md:decoration-secondary decoration-primary font-title"
|
||||
<div className="self-end flex flex-col items-start lg:gap-1 mb-8 lg: items-center
|
||||
lg:pb-22 2xl:pb-30 ">
|
||||
<h5
|
||||
className="font-semi-bold text-text
|
||||
text-2xl sm:text-3xl md:text-2xl lg:text-2xl xl:text-4xl
|
||||
font-title text-left"
|
||||
>
|
||||
Design. Develop. Deliver.
|
||||
</h1>
|
||||
|
||||
<p
|
||||
className="mb-10 text-text/80
|
||||
text-sm sm:text-base md:text-lg lg:text-xl xl:text-2 font-main"
|
||||
>
|
||||
Driven by a genuine passion for creation through code.
|
||||
</p>
|
||||
|
||||
Hello,
|
||||
</h5>
|
||||
<h2
|
||||
className="font-extrabold text-text leading-tight tracking-wide mb-5
|
||||
text-2xl sm:text-3xl md:text-4xl lg:text-5xl xl:text-6xl font-title"
|
||||
className="font-extrabold text-text leading-tight tracking-wide
|
||||
text-2xl sm:text-3xl md:text-3xl lg:text-5xl xl:text-8xl
|
||||
font-title text-left"
|
||||
>
|
||||
Hello, I’m Jody Holt
|
||||
I’m Jody Holt
|
||||
</h2>
|
||||
|
||||
<p
|
||||
className="mb-3 text-text/85 md:mt-10 md:mb-5
|
||||
text-base md:text-xl lg:text-2xl xl:text-3xl font-main"
|
||||
className="mb-3 text-text/85 md:mt-2
|
||||
text-base md:text-xl lg:text-2xl xl:text-4xl font-main"
|
||||
>
|
||||
Turning concepts into clean, functional code.
|
||||
</p>
|
||||
|
||||
<p
|
||||
className="mb-30 text-text/85
|
||||
text-base md:text-3xl lg:text-4xl xl:text-5xl
|
||||
font-semibold font-main"
|
||||
>
|
||||
It’s What I Do.
|
||||
</p>
|
||||
|
||||
<p
|
||||
className="mb-8 text-text
|
||||
text-lg md:text-4xl lg:text-5xl font-main"
|
||||
>
|
||||
I would love to connect!
|
||||
</p>
|
||||
|
||||
<div className="flex items-center justify-center gap-4 md:gap-6">
|
||||
|
||||
<div className="flex self-start items-center justify-start gap-4 md:gap-6 mt-5">
|
||||
{[
|
||||
{ label: "GitHub", href: "#" },
|
||||
{ label: "LinkedIn", href: "#" },
|
||||
@@ -140,9 +120,11 @@ export function Hero() {
|
||||
<a
|
||||
key={a.label}
|
||||
href={a.href}
|
||||
className="inline-flex items-center justify-center rounded-xl border border-secondary/70 bg-secondary/20 text-text transition
|
||||
h-10 w-10 sm:h-12 sm:w-12 md:h-14 md:w-14 lg:h-16 lg:w-16
|
||||
hover:border-primary hover:text-primary"
|
||||
className="inline-flex items-center justify-center rounded-xl border
|
||||
border-secondary/70 bg-secondary/20 text-text transition h-10 w-10
|
||||
sm:h-12 sm:w-12 md:h-14 md:w-14 lg:h-16 lg:w-16 hover:border-primary
|
||||
hover:text-primary anim-base icon-hover focus:outline-none
|
||||
focus-visible:ring-2 focus-visible:ring-primary/60"
|
||||
aria-label={a.label}
|
||||
title={a.label}
|
||||
>
|
||||
@@ -151,6 +133,14 @@ export function Hero() {
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className=" justify-start ">
|
||||
<img
|
||||
src={profileImage}
|
||||
alt="Jody Holt"
|
||||
className="lg:max-h-[78vh] sm:max-h-[50vh] h-auto object-contain select-none
|
||||
pointer-events-none anim-pop-in will-change-transform"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -15,12 +15,14 @@ export function Navbar({ onNav }: { onNav: (id: string) => void }) {
|
||||
};
|
||||
|
||||
return (
|
||||
<header className="sticky top-0 z-50 border-b border-secondary bg-bg/90 backdrop-blur h-16 md:h-20 font-main">
|
||||
<div className="mx-auto flex h-full max-w-7xl items-center justify-between px-4">
|
||||
|
||||
<div className="flex items-center gap-3">
|
||||
<header className="sticky top-0 z-50 border-b border-secondary bg-bg/90
|
||||
backdrop-blur h-16 md:h-20 font-main w-full anim-fade-in">
|
||||
<div className="flex h-full w-full items-center justify-between px-4 sm:px-6
|
||||
md:px-10 lg:px-16">
|
||||
<div className="flex items-center gap-3 hover-pop anim-base select-none">
|
||||
<div className="leading-tight">
|
||||
<div className="text-xl md:text-2xl font-extrabold font-name tracking-wide text-text">
|
||||
<div className="text-xl md:text-2xl font-extrabold font-name tracking-wide
|
||||
text-text">
|
||||
Jody Holt
|
||||
</div>
|
||||
<div className="text-[11px] md:text-sm text-text/70">
|
||||
@@ -29,12 +31,11 @@ export function Navbar({ onNav }: { onNav: (id: string) => void }) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<nav className="hidden items-center gap-6 md:flex">
|
||||
{links.map((l) => (
|
||||
<button
|
||||
key={l.id}
|
||||
className="text-text hover:text-primary"
|
||||
className="text-text/90 hover:text-primary anim-base hover:-translate-y-[1px] focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/60 rounded"
|
||||
onClick={() => handleNav(l.id)}
|
||||
>
|
||||
{l.label}
|
||||
@@ -43,7 +44,6 @@ export function Navbar({ onNav }: { onNav: (id: string) => void }) {
|
||||
<ThemeToggle />
|
||||
</nav>
|
||||
|
||||
|
||||
<div className="md:hidden">
|
||||
<button
|
||||
aria-expanded={open}
|
||||
@@ -63,7 +63,6 @@ export function Navbar({ onNav }: { onNav: (id: string) => void }) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div
|
||||
className={`md:hidden transition-[max-height] duration-300 ${
|
||||
open ? "max-h-96 overflow-visible" : "max-h-0 overflow-hidden"
|
||||
@@ -80,7 +79,6 @@ export function Navbar({ onNav }: { onNav: (id: string) => void }) {
|
||||
</button>
|
||||
))}
|
||||
<div className="pt-2">
|
||||
<ThemeToggle compact />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// ThemeToggle.tsx
|
||||
import React from "react";
|
||||
import { useTheme } from "../hooks/useTheme";
|
||||
|
||||
@@ -5,35 +6,56 @@ export function ThemeToggle({ compact = false }: { compact?: boolean }) {
|
||||
const { theme, setTheme } = useTheme();
|
||||
const themes = ["a", "b", "c", "d", "e"] as const;
|
||||
|
||||
const crossfadeTo = (next: typeof themes[number]) => {
|
||||
// 1) capture current hero computed background (all layers resolved)
|
||||
const hero = document.querySelector<HTMLElement>(".bg-hero");
|
||||
const prevBg = hero ? getComputedStyle(hero).backgroundImage : "";
|
||||
|
||||
// 2) stash it in a CSS var & flag crossfade
|
||||
const root = document.documentElement;
|
||||
root.style.setProperty("--hero-bg-prev", prevBg);
|
||||
root.classList.add("hero-xfade");
|
||||
|
||||
// 3) switch theme (your existing logic)
|
||||
setTheme(next as any);
|
||||
|
||||
// 4) remove crossfade flag after the animation
|
||||
window.setTimeout(() => {
|
||||
root.classList.remove("hero-xfade");
|
||||
root.style.removeProperty("--hero-bg-prev");
|
||||
}, 600); // a bit > .55s animation
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="relative inline-block text-text">
|
||||
<details className="group">
|
||||
<summary className="cursor-pointer select-none list-none inline-flex items-center gap-2 rounded px-3 py-1.5 bg-secondary/70 hover:bg-secondary focus:outline-none">
|
||||
<span className="font-medium">
|
||||
{compact ? "Theme" : "Toggle Theme"}
|
||||
</span>
|
||||
<summary className="cursor-pointer select-none list-none inline-flex items-center gap-2 rounded px-3 py-1.5 bg-secondary/70 hover:bg-secondary focus:outline-none anim-base hover-pop">
|
||||
<span className="font-medium">{compact ? "Theme" : "Toggle Theme"}</span>
|
||||
<span aria-hidden>▾</span>
|
||||
</summary>
|
||||
|
||||
<div
|
||||
className="
|
||||
absolute top-full mt-2
|
||||
left-0 right-0 w-[calc(100vw-10rem)]
|
||||
md:left-auto md:right- md:mx-0 md:w-44
|
||||
rounded-lg border border-secondary bg-bg/95 p-2 shadow-xl backdrop-blur z-[70]
|
||||
"
|
||||
absolute top-full mt-2 z-[70] rounded-lg border border-secondary bg-bg/95 p-2 shadow-xl backdrop-blur
|
||||
left-4 right-4 mx-auto w-[calc(100vw-2rem)] max-w-[18rem]
|
||||
md:left-auto md:right-0 md:mx-0 md:w-44 md:max-w-none
|
||||
origin-top scale-y-95 opacity-0 translate-y-[-4px]
|
||||
pointer-events-none transition-all duration-300 ease-out
|
||||
group-open:opacity-100 group-open:scale-y-100 group-open:translate-y-0 group-open:pointer-events-auto
|
||||
"
|
||||
>
|
||||
<ul className="space-y-1">
|
||||
{themes.map((t) => (
|
||||
<li key={t}>
|
||||
<button
|
||||
onClick={() => setTheme(t as any)}
|
||||
className={`w-full rounded px-3 py-2 text-left hover:bg-secondary/60 ${
|
||||
onClick={() => crossfadeTo(t)}
|
||||
className={`w-full rounded px-3 py-2 text-left hover:bg-secondary/60 anim-base ${
|
||||
theme === t ? "outline outline-1 outline-primary" : ""
|
||||
}`}
|
||||
>
|
||||
<span
|
||||
className="mr-2 inline-block h-3 w-3 rounded-full align-middle"
|
||||
style={{ background: `var(--color-accent-${t})` }}
|
||||
style={{ background: `var(--color-accent-${t}, var(--color-primary))` }}
|
||||
/>
|
||||
Theme {t.toUpperCase()}
|
||||
</button>
|
||||
|
||||
122
src/index.css
122
src/index.css
@@ -48,7 +48,7 @@ html[data-theme="d"] {
|
||||
--color-bg: #0f1014;
|
||||
--color-secondary: #1d1f24;
|
||||
--color-text: #eaecef;
|
||||
--color-primary: #6c78ff;
|
||||
--color-primary: #7743d8;
|
||||
--color-tertiary: #a97bff;
|
||||
--color-contrast: #9ca3af;
|
||||
}
|
||||
@@ -69,7 +69,7 @@ html[data-theme="e"] {
|
||||
|
||||
@layer utilities {
|
||||
/* Mobile / default */
|
||||
.bg-hero {
|
||||
.bg-hero {
|
||||
background:
|
||||
/* Top-right radial accent, similar to desktop */ radial-gradient(
|
||||
120% 100% at 80% 10%,
|
||||
@@ -78,10 +78,10 @@ html[data-theme="e"] {
|
||||
),
|
||||
/* Slight linear sweep from top to bottom */
|
||||
linear-gradient(
|
||||
180deg,
|
||||
120deg,
|
||||
#0a0d13 0%,
|
||||
var(--color-bg) 40%,
|
||||
color-mix(in oklab, var(--color-primary) 10%, var(--color-bg) 90%)
|
||||
var(--color-bg) 20%,
|
||||
color-mix(in oklab, var(--color-primary) 15%, var(--color-bg) 90%)
|
||||
100%
|
||||
);
|
||||
}
|
||||
@@ -92,7 +92,7 @@ html[data-theme="e"] {
|
||||
background:
|
||||
/* small, softer highlight lower than the portrait rim */ radial-gradient(
|
||||
95% 70% at 50% 28%,
|
||||
color-mix(in oklab, var(--hero-core) 18%, transparent 82%) 0%,
|
||||
color-mix(in oklab, var(--hero-core) 24%, transparent 82%) 0%,
|
||||
transparent 56%
|
||||
),
|
||||
/* gentle bottom vignette for depth */
|
||||
@@ -116,12 +116,12 @@ html[data-theme="e"] {
|
||||
html[data-theme="a"] .bg-hero {
|
||||
background: radial-gradient(
|
||||
135% 120% at 80% 48%,
|
||||
color-mix(in oklab, var(--color-primary) 65%, black 35%) 0%,
|
||||
color-mix(in oklab, var(--color-primary) 45%, black 55%) 38%,
|
||||
transparent 74%
|
||||
color-mix(in oklab, var(--color-primary) 50%, black 35%) 0%,
|
||||
color-mix(in oklab, var(--color-primary) 70%, black 55%) 38%,
|
||||
transparent 90%
|
||||
),
|
||||
linear-gradient(
|
||||
165deg,
|
||||
230deg,
|
||||
#080b10 0%,
|
||||
color-mix(in oklab, var(--color-bg) 70%, black 30%) 46%,
|
||||
#0a1324 100%
|
||||
@@ -131,27 +131,27 @@ html[data-theme="e"] {
|
||||
html[data-theme="b"] .bg-hero {
|
||||
background: radial-gradient(
|
||||
140% 110% at 76% 46%,
|
||||
color-mix(in oklab, var(--color-primary) 60%, black 40%) 0%,
|
||||
color-mix(in oklab, var(--color-primary) 40%, black 60%) 36%,
|
||||
transparent 70%
|
||||
color-mix(in oklab, var(--color-primary) 50%, black 40%) 0%,
|
||||
color-mix(in oklab, var(--color-primary) 70%, black 60%) 36%,
|
||||
transparent 82%
|
||||
),
|
||||
linear-gradient(
|
||||
185deg,
|
||||
230deg,
|
||||
#140c0b 0%,
|
||||
var(--color-bg) 40%,
|
||||
color-mix(in oklab, var(--color-tertiary) 6%, var(--color-bg) 94%) 100%
|
||||
var(--color-bg) 20%,
|
||||
color-mix(in oklab, var(--color-secondary) 6%, var(--color-bg) 94%) 100%
|
||||
);
|
||||
}
|
||||
/* Theme C – teal/cyan */
|
||||
html[data-theme="c"] .bg-hero {
|
||||
background: radial-gradient(
|
||||
140% 120% at 76% 48%,
|
||||
color-mix(in oklab, var(--color-primary) 58%, black 42%) 0%,
|
||||
color-mix(in oklab, var(--color-primary) 40%, black 60%) 36%,
|
||||
transparent 72%
|
||||
color-mix(in oklab, var(--color-primary) 50%, black 42%) 0%,
|
||||
color-mix(in oklab, var(--color-primary) 70%, black 60%) 36%,
|
||||
transparent 82%
|
||||
),
|
||||
linear-gradient(
|
||||
165deg,
|
||||
230deg,
|
||||
#081016 0%,
|
||||
color-mix(in oklab, var(--color-bg) 62%, black 38%) 44%,
|
||||
#0a1822 100%
|
||||
@@ -162,12 +162,12 @@ html[data-theme="e"] {
|
||||
html[data-theme="d"] .bg-hero {
|
||||
background: radial-gradient(
|
||||
135% 120% at 80% 48%,
|
||||
color-mix(in oklab, var(--color-primary) 60%, black 40%) 0%,
|
||||
color-mix(in oklab, var(--color-primary) 38%, black 62%) 36%,
|
||||
transparent 72%
|
||||
color-mix(in oklab, var(--color-primary) 50%, black 40%) 0%,
|
||||
color-mix(in oklab, var(--color-primary) 70%, black 62%) 36%,
|
||||
transparent 82%
|
||||
),
|
||||
linear-gradient(
|
||||
165deg,
|
||||
230deg,
|
||||
#090a10 0%,
|
||||
color-mix(in oklab, var(--color-bg) 68%, black 32%) 46%,
|
||||
#111328 100%
|
||||
@@ -178,12 +178,12 @@ html[data-theme="e"] {
|
||||
html[data-theme="e"] .bg-hero {
|
||||
background: radial-gradient(
|
||||
140% 120% at 78% 48%,
|
||||
color-mix(in oklab, var(--color-primary) 58%, black 42%) 0%,
|
||||
color-mix(in oklab, var(--color-primary) 38%, black 62%) 34%,
|
||||
transparent 70%
|
||||
color-mix(in oklab, var(--color-primary) 50%, black 42%) 0%,
|
||||
color-mix(in oklab, var(--color-primary) 70%, black 62%) 34%,
|
||||
transparent 82%
|
||||
),
|
||||
linear-gradient(
|
||||
165deg,
|
||||
230deg,
|
||||
#07100e 0%,
|
||||
color-mix(in oklab, var(--color-bg) 64%, black 36%) 44%,
|
||||
#0a1c1a 100%
|
||||
@@ -198,12 +198,19 @@ html[data-theme="e"] {
|
||||
pointer-events: none;
|
||||
/* left-to-right fade of darkness */
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
270deg,
|
||||
rgba(0, 0, 0, 0.5) 0%,
|
||||
rgba(0, 0, 0, 0.34) 30%,
|
||||
rgba(0, 0, 0, 0.18) 42%,
|
||||
rgba(0, 0, 0, 0.34) 16%,
|
||||
rgba(0, 0, 0, 0.18) 35%,
|
||||
rgba(0, 0, 0, 0) 50%
|
||||
);
|
||||
),
|
||||
linear-gradient(
|
||||
270deg,
|
||||
rgba(0,0,0,0.6) 0%,
|
||||
rgba(0,0,0,0.48) 25%,
|
||||
rgba(0,0,0,0.1) 60%
|
||||
);
|
||||
;
|
||||
z-index: 0;
|
||||
}
|
||||
/* keep content above the overlay */
|
||||
@@ -231,4 +238,53 @@ html[data-theme="e"] {
|
||||
);
|
||||
box-shadow: inset 0 0 24px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Keyframes ─────────────────────────────────────────── */
|
||||
/* ── Keyframes (unchanged) ───────────────────────────── */
|
||||
@keyframes ui-fade-in { from{opacity:0;transform:translateY(6px)} to{opacity:1;transform:translateY(0)} }
|
||||
@keyframes ui-pop-in { from{opacity:0;transform:scale(.96);filter:blur(2px)} to{opacity:1;transform:scale(1);filter:blur(0)} }
|
||||
@keyframes ui-fade { from{opacity:0} to{opacity:1} }
|
||||
/* Old→new gradient crossfade */
|
||||
@keyframes hero-xfade-out { from { opacity: 1 } to { opacity: 0 } }
|
||||
|
||||
/* When html has .hero-xfade, paint the OLD gradient on ::after and fade it out */
|
||||
html.hero-xfade .bg-hero {
|
||||
position: relative; /* anchor overlay */
|
||||
}
|
||||
html.hero-xfade .bg-hero::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 2; /* above everything but below menus if needed */
|
||||
pointer-events: none;
|
||||
background-image: var(--hero-bg-prev, none);
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
animation: hero-xfade-out .55s ease-out forwards; /* match your new durations */
|
||||
}
|
||||
|
||||
/* Ensure the base gradient is behind content as usual */
|
||||
.bg-hero > * { position: relative; z-index: 3; }
|
||||
|
||||
|
||||
/* Respect reduced motion (unchanged) */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
* { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; }
|
||||
}
|
||||
|
||||
/* ── Helpers (longer durations) ──────────────────────── */
|
||||
.anim-base { transition: transform .24s ease, opacity .24s ease, filter .24s ease, color .24s ease, background-color .24s ease, border-color .24s ease; }
|
||||
.anim-fade-in{ animation: ui-fade-in .55s cubic-bezier(.22,.61,.36,1) both; } /* 550ms */
|
||||
.anim-pop-in { animation: ui-pop-in .48s cubic-bezier(.22,.61,.36,1) both; } /* 480ms */
|
||||
.anim-fade { animation: ui-fade .45s ease-out both; } /* 450ms */
|
||||
|
||||
/* Optional: slightly gentler hover/tap */
|
||||
.hover-pop:hover { transform: translateY(-2px) scale(1.03); transition-duration: .24s; }
|
||||
.hover-pop:active { transform: translateY(0) scale(.98); transition-duration: .14s; }
|
||||
|
||||
/* ── Theme fade-on-switch (keeps it simple) ──────────── */
|
||||
/* When the theme changes (html[data-theme] switches), the hero softly fades in */
|
||||
html[data-theme] .bg-hero { animation: ui-fade .5s ease-out both; } /* 500ms */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user