design: apply silver gradient to section headers + nav links, add dev-only live accent switcher, slow border-beam to 11s
This commit is contained in:
237
vibn-frontend/app/(marketing)/AccentSwitcher.tsx
Normal file
237
vibn-frontend/app/(marketing)/AccentSwitcher.tsx
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dev-only accent color switcher for the marketing site.
|
||||||
|
*
|
||||||
|
* Flips the homepage accent live by overriding the `--accent-h` (hue) and
|
||||||
|
* `--accent-cm` (chroma) CSS variables on `.new-site-wrapper`. Choice persists
|
||||||
|
* in localStorage so it survives reloads while you experiment.
|
||||||
|
*
|
||||||
|
* Visibility: shows only in development, or in any environment when the URL has
|
||||||
|
* `?theme`. So it's hidden in production by default — nothing to do to hide it.
|
||||||
|
* To remove entirely later, delete this file and its <AccentSwitcher /> usage
|
||||||
|
* in app/(marketing)/page.tsx.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const PRESETS: { label: string; h: number; cm: number }[] = [
|
||||||
|
{ label: "Coral", h: 35, cm: 1 },
|
||||||
|
{ label: "Silver", h: 35, cm: 0 },
|
||||||
|
{ label: "Crimson", h: 25, cm: 1 },
|
||||||
|
{ label: "Amber", h: 75, cm: 1 },
|
||||||
|
{ label: "Emerald", h: 150, cm: 1 },
|
||||||
|
{ label: "Teal", h: 195, cm: 1 },
|
||||||
|
{ label: "Sky", h: 235, cm: 1 },
|
||||||
|
{ label: "Royal", h: 255, cm: 1 },
|
||||||
|
{ label: "Indigo", h: 270, cm: 1 },
|
||||||
|
{ label: "Violet", h: 300, cm: 1 },
|
||||||
|
{ label: "Pink", h: 350, cm: 1 },
|
||||||
|
];
|
||||||
|
|
||||||
|
const swatchColor = (h: number, cm: number) =>
|
||||||
|
`oklch(0.74 ${(0.175 * cm).toFixed(3)} ${h})`;
|
||||||
|
|
||||||
|
export default function AccentSwitcher() {
|
||||||
|
const [visible, setVisible] = useState(false);
|
||||||
|
const [open, setOpen] = useState(true);
|
||||||
|
const [h, setH] = useState(35);
|
||||||
|
const [cm, setCm] = useState(1);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const isDev = process.env.NODE_ENV !== "production";
|
||||||
|
const forced =
|
||||||
|
typeof window !== "undefined" &&
|
||||||
|
new URLSearchParams(window.location.search).has("theme");
|
||||||
|
setVisible(isDev || forced);
|
||||||
|
try {
|
||||||
|
const saved = JSON.parse(localStorage.getItem("vibn:accent") || "null");
|
||||||
|
if (saved && typeof saved.h === "number") {
|
||||||
|
setH(saved.h);
|
||||||
|
setCm(typeof saved.cm === "number" ? saved.cm : 1);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!visible) return;
|
||||||
|
const el = document.querySelector(".new-site-wrapper") as HTMLElement | null;
|
||||||
|
if (el) {
|
||||||
|
el.style.setProperty("--accent-h", String(h));
|
||||||
|
el.style.setProperty("--accent-cm", String(cm));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
localStorage.setItem("vibn:accent", JSON.stringify({ h, cm }));
|
||||||
|
} catch {
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
|
}, [visible, h, cm]);
|
||||||
|
|
||||||
|
if (!visible) return null;
|
||||||
|
|
||||||
|
const panel: React.CSSProperties = {
|
||||||
|
position: "fixed",
|
||||||
|
left: 16,
|
||||||
|
bottom: 16,
|
||||||
|
zIndex: 2147483647,
|
||||||
|
width: 232,
|
||||||
|
padding: 14,
|
||||||
|
borderRadius: 14,
|
||||||
|
background: "rgba(18,17,15,0.92)",
|
||||||
|
border: "1px solid rgba(255,255,255,0.12)",
|
||||||
|
backdropFilter: "blur(16px)",
|
||||||
|
boxShadow: "0 18px 50px rgba(0,0,0,0.5)",
|
||||||
|
color: "#f5f4f2",
|
||||||
|
fontFamily: "ui-monospace, 'SF Mono', Menlo, monospace",
|
||||||
|
fontSize: 11,
|
||||||
|
userSelect: "none",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!open) {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => setOpen(true)}
|
||||||
|
title="Theme"
|
||||||
|
style={{
|
||||||
|
position: "fixed",
|
||||||
|
left: 16,
|
||||||
|
bottom: 16,
|
||||||
|
zIndex: 2147483647,
|
||||||
|
width: 38,
|
||||||
|
height: 38,
|
||||||
|
borderRadius: "50%",
|
||||||
|
border: "1px solid rgba(255,255,255,0.18)",
|
||||||
|
background: swatchColor(h, cm),
|
||||||
|
boxShadow: "0 8px 24px rgba(0,0,0,0.45)",
|
||||||
|
cursor: "pointer",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={panel}>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
marginBottom: 10,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span style={{ letterSpacing: "0.1em", textTransform: "uppercase", opacity: 0.6 }}>
|
||||||
|
Accent · dev
|
||||||
|
</span>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => setOpen(false)}
|
||||||
|
title="Collapse"
|
||||||
|
style={{
|
||||||
|
border: "none",
|
||||||
|
background: "transparent",
|
||||||
|
color: "#f5f4f2",
|
||||||
|
cursor: "pointer",
|
||||||
|
fontSize: 14,
|
||||||
|
lineHeight: 1,
|
||||||
|
opacity: 0.7,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
▾
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "grid",
|
||||||
|
gridTemplateColumns: "repeat(6, 1fr)",
|
||||||
|
gap: 6,
|
||||||
|
marginBottom: 12,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{PRESETS.map((p) => {
|
||||||
|
const active = p.h === h && p.cm === cm;
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={p.label}
|
||||||
|
type="button"
|
||||||
|
title={p.label}
|
||||||
|
onClick={() => {
|
||||||
|
setH(p.h);
|
||||||
|
setCm(p.cm);
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
aspectRatio: "1 / 1",
|
||||||
|
borderRadius: 7,
|
||||||
|
border: active
|
||||||
|
? "2px solid #fff"
|
||||||
|
: "1px solid rgba(255,255,255,0.15)",
|
||||||
|
background: swatchColor(p.h, p.cm),
|
||||||
|
cursor: "pointer",
|
||||||
|
padding: 0,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label style={{ display: "block", marginBottom: 8 }}>
|
||||||
|
<span style={{ display: "flex", justifyContent: "space-between", opacity: 0.7 }}>
|
||||||
|
<span>Hue</span>
|
||||||
|
<span>{h}</span>
|
||||||
|
</span>
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
min={0}
|
||||||
|
max={360}
|
||||||
|
value={h}
|
||||||
|
onChange={(e) => setH(Number(e.target.value))}
|
||||||
|
style={{ width: "100%", accentColor: swatchColor(h, cm) }}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label style={{ display: "block", marginBottom: 10 }}>
|
||||||
|
<span style={{ display: "flex", justifyContent: "space-between", opacity: 0.7 }}>
|
||||||
|
<span>Vivid</span>
|
||||||
|
<span>{cm.toFixed(2)}</span>
|
||||||
|
</span>
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
min={0}
|
||||||
|
max={1}
|
||||||
|
step={0.05}
|
||||||
|
value={cm}
|
||||||
|
onChange={(e) => setCm(Number(e.target.value))}
|
||||||
|
style={{ width: "100%", accentColor: swatchColor(h, cm) }}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
|
||||||
|
<code style={{ opacity: 0.55, fontSize: 10 }}>
|
||||||
|
h:{h} cm:{cm}
|
||||||
|
</code>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => {
|
||||||
|
setH(35);
|
||||||
|
setCm(1);
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
border: "1px solid rgba(255,255,255,0.18)",
|
||||||
|
background: "transparent",
|
||||||
|
color: "#f5f4f2",
|
||||||
|
borderRadius: 6,
|
||||||
|
padding: "4px 8px",
|
||||||
|
cursor: "pointer",
|
||||||
|
fontSize: 10,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Reset
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -915,10 +915,23 @@ function Hero({ onStart, variant = "quote" }) {
|
|||||||
line-height: 0.98;
|
line-height: 0.98;
|
||||||
text-wrap: balance;
|
text-wrap: balance;
|
||||||
position: relative;
|
position: relative;
|
||||||
color: var(--fg);
|
/* Silver / brushed-metal heading: bright at the top, fading to a soft
|
||||||
|
pewter at the bottom, clipped to the text. */
|
||||||
|
background-image: linear-gradient(
|
||||||
|
180deg,
|
||||||
|
oklch(0.99 0.003 80) 0%,
|
||||||
|
oklch(0.86 0.004 80) 42%,
|
||||||
|
oklch(0.66 0.006 80) 100%
|
||||||
|
);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
background-clip: text;
|
||||||
|
color: transparent;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
}
|
}
|
||||||
.hero-quote .mark {
|
.hero-quote .mark {
|
||||||
|
/* keep the accent word in full color inside the silver heading */
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
|
-webkit-text-fill-color: var(--accent);
|
||||||
font-family: "Geist", serif;
|
font-family: "Geist", serif;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
line-height: 0;
|
line-height: 0;
|
||||||
@@ -963,13 +976,62 @@ function Hero({ onStart, variant = "quote" }) {
|
|||||||
border-radius: var(--r-xl);
|
border-radius: var(--r-xl);
|
||||||
padding: 1px;
|
padding: 1px;
|
||||||
background: linear-gradient(180deg,
|
background: linear-gradient(180deg,
|
||||||
oklch(0.50 0.06 35 / 0.6),
|
oklch(0.50 calc(0.06 * var(--accent-cm)) var(--accent-h) / 0.6),
|
||||||
oklch(0.30 0.012 60 / 0.4) 40%,
|
oklch(0.30 0.012 60 / 0.4) 40%,
|
||||||
oklch(0.25 0.012 60 / 0.4));
|
oklch(0.25 0.012 60 / 0.4));
|
||||||
box-shadow:
|
box-shadow:
|
||||||
0 30px 80px -20px oklch(0 0 0 / 0.6),
|
0 30px 80px -20px oklch(0 0 0 / 0.6),
|
||||||
0 0 80px -20px var(--accent-glow);
|
0 0 80px -20px var(--accent-glow);
|
||||||
}
|
}
|
||||||
|
/* Animated border beam (Magic UI style): a light comet that travels
|
||||||
|
the border, masked to a thin ring and themed to the accent. */
|
||||||
|
.prompt-beam {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
border-radius: inherit;
|
||||||
|
padding: 1.5px;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 2;
|
||||||
|
-webkit-mask:
|
||||||
|
linear-gradient(#000 0 0) content-box,
|
||||||
|
linear-gradient(#000 0 0);
|
||||||
|
mask:
|
||||||
|
linear-gradient(#000 0 0) content-box,
|
||||||
|
linear-gradient(#000 0 0);
|
||||||
|
-webkit-mask-composite: xor;
|
||||||
|
mask-composite: exclude;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.prompt-beam::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
width: 170px;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
offset-path: rect(0 auto auto 0 round var(--r-xl));
|
||||||
|
offset-distance: 0%;
|
||||||
|
offset-anchor: 50% 50%;
|
||||||
|
background: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
transparent,
|
||||||
|
var(--accent) 38%,
|
||||||
|
oklch(0.95 calc(0.05 * var(--accent-cm)) var(--accent-h)) 50%,
|
||||||
|
var(--accent) 62%,
|
||||||
|
transparent
|
||||||
|
);
|
||||||
|
filter: blur(3px);
|
||||||
|
animation: prompt-beam 11s linear infinite;
|
||||||
|
}
|
||||||
|
@keyframes prompt-beam {
|
||||||
|
to {
|
||||||
|
offset-distance: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.prompt-beam::before {
|
||||||
|
animation: none;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
.prompt-inner {
|
.prompt-inner {
|
||||||
background: linear-gradient(180deg, oklch(0.19 0.009 60 / 0.92), oklch(0.17 0.008 60 / 0.92));
|
background: linear-gradient(180deg, oklch(0.19 0.009 60 / 0.92), oklch(0.17 0.008 60 / 0.92));
|
||||||
border-radius: calc(var(--r-xl) - 1px);
|
border-radius: calc(var(--r-xl) - 1px);
|
||||||
@@ -1037,7 +1099,7 @@ function Hero({ onStart, variant = "quote" }) {
|
|||||||
background: var(--accent);
|
background: var(--accent);
|
||||||
color: var(--accent-fg);
|
color: var(--accent-fg);
|
||||||
font-weight: 500; font-size: 14px;
|
font-weight: 500; font-size: 14px;
|
||||||
box-shadow: 0 0 0 1px oklch(0.84 0.16 35 / 0.5) inset, 0 8px 28px -8px var(--accent-glow);
|
box-shadow: 0 0 0 1px oklch(0.84 calc(0.16 * var(--accent-cm)) var(--accent-h) / 0.5) inset, 0 8px 28px -8px var(--accent-glow);
|
||||||
transition: transform .12s;
|
transition: transform .12s;
|
||||||
}
|
}
|
||||||
.prompt-send:hover { transform: translateY(-1px); }
|
.prompt-send:hover { transform: translateY(-1px); }
|
||||||
@@ -1095,17 +1157,17 @@ function Hero({ onStart, variant = "quote" }) {
|
|||||||
|
|
||||||
{/* ambient glows behind hero */}
|
{/* ambient glows behind hero */}
|
||||||
<Glow
|
<Glow
|
||||||
color="oklch(0.74 0.175 35 / 0.30)"
|
color="oklch(0.74 calc(0.175 * var(--accent-cm)) var(--accent-h) / 0.30)"
|
||||||
size={900}
|
size={900}
|
||||||
style={{ top: "-200px", left: "50%", transform: "translateX(-50%)" }}
|
style={{ top: "-200px", left: "50%", transform: "translateX(-50%)" }}
|
||||||
/>
|
/>
|
||||||
<Glow
|
<Glow
|
||||||
color="oklch(0.45 0.10 35 / 0.30)"
|
color="oklch(0.45 calc(0.10 * var(--accent-cm)) var(--accent-h) / 0.30)"
|
||||||
size={600}
|
size={600}
|
||||||
style={{ top: "20%", left: "-200px" }}
|
style={{ top: "20%", left: "-200px" }}
|
||||||
/>
|
/>
|
||||||
<Glow
|
<Glow
|
||||||
color="oklch(0.45 0.10 35 / 0.20)"
|
color="oklch(0.45 calc(0.10 * var(--accent-cm)) var(--accent-h) / 0.20)"
|
||||||
size={500}
|
size={500}
|
||||||
style={{ top: "30%", right: "-150px" }}
|
style={{ top: "30%", right: "-150px" }}
|
||||||
/>
|
/>
|
||||||
@@ -1156,6 +1218,7 @@ function Hero({ onStart, variant = "quote" }) {
|
|||||||
{/* Prompt */}
|
{/* Prompt */}
|
||||||
<div className="prompt">
|
<div className="prompt">
|
||||||
<div className="prompt-frame">
|
<div className="prompt-frame">
|
||||||
|
<span className="prompt-beam" aria-hidden="true" />
|
||||||
<div className="prompt-inner">
|
<div className="prompt-inner">
|
||||||
<div style={{ position: "relative" }}>
|
<div style={{ position: "relative" }}>
|
||||||
<textarea
|
<textarea
|
||||||
@@ -1860,7 +1923,7 @@ function Journey() {
|
|||||||
background: var(--bg);
|
background: var(--bg);
|
||||||
padding: 6px 12px;
|
padding: 6px 12px;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
border: 1px solid oklch(0.74 0.175 35 / 0.5);
|
border: 1px solid oklch(0.74 calc(0.175 * var(--accent-cm)) var(--accent-h) / 0.5);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
box-shadow: 0 0 24px var(--accent-glow);
|
box-shadow: 0 0 24px var(--accent-glow);
|
||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
@@ -1878,7 +1941,7 @@ function Journey() {
|
|||||||
margin-top: 1px;
|
margin-top: 1px;
|
||||||
}
|
}
|
||||||
.demo-tag.you { color: oklch(0.85 0.06 250); background: oklch(0.28 0.04 250); }
|
.demo-tag.you { color: oklch(0.85 0.06 250); background: oklch(0.28 0.04 250); }
|
||||||
.demo-tag.ai { color: var(--accent); background: oklch(0.35 0.10 35 / 0.4); }
|
.demo-tag.ai { color: var(--accent); background: oklch(0.35 calc(0.10 * var(--accent-cm)) var(--accent-h) / 0.4); }
|
||||||
.demo-line { color: var(--fg-dim); }
|
.demo-line { color: var(--fg-dim); }
|
||||||
.demo-ok { color: var(--ok); }
|
.demo-ok { color: var(--ok); }
|
||||||
.demo-host {
|
.demo-host {
|
||||||
@@ -2200,8 +2263,8 @@ function Audience() {
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
padding: 3px 7px;
|
padding: 3px 7px;
|
||||||
background: oklch(0.74 0.175 35 / 0.12);
|
background: oklch(0.74 calc(0.175 * var(--accent-cm)) var(--accent-h) / 0.12);
|
||||||
border: 1px solid oklch(0.74 0.175 35 / 0.4);
|
border: 1px solid oklch(0.74 calc(0.175 * var(--accent-cm)) var(--accent-h) / 0.4);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
margin-top: 1px;
|
margin-top: 1px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
@@ -2306,7 +2369,7 @@ function Closing() {
|
|||||||
.closing-title .accent { color: var(--accent); }
|
.closing-title .accent { color: var(--accent); }
|
||||||
.closing-title em {
|
.closing-title em {
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
background: linear-gradient(180deg, var(--accent), oklch(0.62 0.18 18));
|
background: linear-gradient(180deg, var(--accent), oklch(0.62 calc(0.18 * var(--accent-cm)) calc(var(--accent-h) - 17)));
|
||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
background-clip: text;
|
background-clip: text;
|
||||||
color: transparent;
|
color: transparent;
|
||||||
@@ -2330,12 +2393,12 @@ function Closing() {
|
|||||||
`}</style>
|
`}</style>
|
||||||
|
|
||||||
<Glow
|
<Glow
|
||||||
color="oklch(0.74 0.175 35 / 0.35)"
|
color="oklch(0.74 calc(0.175 * var(--accent-cm)) var(--accent-h) / 0.35)"
|
||||||
size={1000}
|
size={1000}
|
||||||
style={{ top: "20%", left: "50%", transform: "translateX(-50%)" }}
|
style={{ top: "20%", left: "50%", transform: "translateX(-50%)" }}
|
||||||
/>
|
/>
|
||||||
<Glow
|
<Glow
|
||||||
color="oklch(0.45 0.10 35 / 0.20)"
|
color="oklch(0.45 calc(0.10 * var(--accent-cm)) var(--accent-h) / 0.20)"
|
||||||
size={600}
|
size={600}
|
||||||
style={{ bottom: "-200px", left: "50%", transform: "translateX(-50%)" }}
|
style={{ bottom: "-200px", left: "50%", transform: "translateX(-50%)" }}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
import NewSite from "./new-site";
|
import NewSite from "./new-site";
|
||||||
|
// Dev-only accent color switcher (auto-hidden in production). Remove these two
|
||||||
|
// lines to take it out entirely.
|
||||||
|
import AccentSwitcher from "./AccentSwitcher";
|
||||||
import "../styles/new-site.css";
|
import "../styles/new-site.css";
|
||||||
|
|
||||||
export const metadata = {
|
export const metadata = {
|
||||||
@@ -6,5 +9,10 @@ export const metadata = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return <NewSite />;
|
return (
|
||||||
|
<>
|
||||||
|
<NewSite />
|
||||||
|
<AccentSwitcher />
|
||||||
|
</>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,10 +9,23 @@
|
|||||||
--fg-mute: oklch(0.58 0.006 80);
|
--fg-mute: oklch(0.58 0.006 80);
|
||||||
--fg-faint: oklch(0.42 0.006 80);
|
--fg-faint: oklch(0.42 0.006 80);
|
||||||
|
|
||||||
--accent: oklch(0.74 0.175 35); /* warm coral, default */
|
/* ── Accent color — change these two to retheme the whole site ──────────
|
||||||
--accent-soft: oklch(0.74 0.175 35 / 0.18);
|
--accent-h : hue 0-360. coral 35 · red 25 · amber 75 · green 150
|
||||||
--accent-glow: oklch(0.74 0.175 35 / 0.35);
|
· teal 195 · blue 250 · indigo 270 · violet 300 · pink 350
|
||||||
--accent-fg: oklch(0.18 0.04 35);
|
--accent-cm : chroma multiplier. 1 = vivid · 0 = silver / neutral gray
|
||||||
|
Every accent color on the page derives from these, so the design stays
|
||||||
|
identical and only the hue/saturation moves. */
|
||||||
|
--accent-h: 35;
|
||||||
|
--accent-cm: 1;
|
||||||
|
|
||||||
|
--accent: oklch(0.74 calc(0.175 * var(--accent-cm)) var(--accent-h));
|
||||||
|
--accent-soft: oklch(
|
||||||
|
0.74 calc(0.175 * var(--accent-cm)) var(--accent-h) / 0.18
|
||||||
|
);
|
||||||
|
--accent-glow: oklch(
|
||||||
|
0.74 calc(0.175 * var(--accent-cm)) var(--accent-h) / 0.35
|
||||||
|
);
|
||||||
|
--accent-fg: oklch(0.18 calc(0.04 * var(--accent-cm)) var(--accent-h));
|
||||||
|
|
||||||
--ok: oklch(0.78 0.16 155);
|
--ok: oklch(0.78 0.16 155);
|
||||||
|
|
||||||
@@ -100,6 +113,34 @@ h4 {
|
|||||||
letter-spacing: -0.02em;
|
letter-spacing: -0.02em;
|
||||||
line-height: 1.05;
|
line-height: 1.05;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Shared Silver Metallic Gradient */
|
||||||
|
.silver-text,
|
||||||
|
.wall-title,
|
||||||
|
.crossed-title,
|
||||||
|
.journey-title,
|
||||||
|
.closing-title,
|
||||||
|
.mission-quote {
|
||||||
|
background-image: linear-gradient(
|
||||||
|
180deg,
|
||||||
|
oklch(0.99 0.003 80) 0%,
|
||||||
|
oklch(0.86 0.004 80) 42%,
|
||||||
|
oklch(0.66 0.006 80) 100%
|
||||||
|
);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
background-clip: text;
|
||||||
|
color: transparent;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
}
|
||||||
|
/* Ensure highlights/em elements stay full-color inside silver headers */
|
||||||
|
.wall-title em,
|
||||||
|
.crossed-title em,
|
||||||
|
.journey-title .accent,
|
||||||
|
.closing-title .accent,
|
||||||
|
.mission-quote .highlight {
|
||||||
|
color: var(--accent);
|
||||||
|
-webkit-text-fill-color: var(--accent);
|
||||||
|
}
|
||||||
p {
|
p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
@@ -172,7 +213,9 @@ button {
|
|||||||
background: var(--accent);
|
background: var(--accent);
|
||||||
color: var(--accent-fg);
|
color: var(--accent-fg);
|
||||||
box-shadow:
|
box-shadow:
|
||||||
0 0 0 1px oklch(0.84 0.16 35 / 0.5) inset,
|
0 0 0 1px
|
||||||
|
oklch(0.84 calc(0.16 * var(--accent-cm)) var(--accent-h) / 0.5)
|
||||||
|
inset,
|
||||||
0 10px 40px -10px var(--accent-glow),
|
0 10px 40px -10px var(--accent-glow),
|
||||||
0 0 50px -8px var(--accent-glow);
|
0 0 50px -8px var(--accent-glow);
|
||||||
}
|
}
|
||||||
@@ -269,7 +312,7 @@ button {
|
|||||||
background: linear-gradient(
|
background: linear-gradient(
|
||||||
135deg,
|
135deg,
|
||||||
var(--accent) 0%,
|
var(--accent) 0%,
|
||||||
oklch(0.65 0.2 18) 100%
|
oklch(0.65 calc(0.2 * var(--accent-cm)) calc(var(--accent-h) - 17)) 100%
|
||||||
);
|
);
|
||||||
box-shadow:
|
box-shadow:
|
||||||
0 0 22px var(--accent-glow),
|
0 0 22px var(--accent-glow),
|
||||||
@@ -293,11 +336,30 @@ button {
|
|||||||
.nav-links {
|
.nav-links {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 28px;
|
gap: 28px;
|
||||||
color: var(--fg-mute);
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
.nav-links a {
|
||||||
|
background-image: linear-gradient(
|
||||||
|
180deg,
|
||||||
|
oklch(0.92 0.003 80) 0%,
|
||||||
|
oklch(0.74 0.004 80) 100%
|
||||||
|
);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
background-clip: text;
|
||||||
|
color: transparent;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
.nav-links a:hover {
|
.nav-links a:hover {
|
||||||
color: var(--fg);
|
background-image: linear-gradient(
|
||||||
|
180deg,
|
||||||
|
oklch(0.99 0.003 80) 0%,
|
||||||
|
oklch(0.88 0.004 80) 100%
|
||||||
|
);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
background-clip: text;
|
||||||
|
color: transparent;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
}
|
}
|
||||||
.nav-cta {
|
.nav-cta {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
Reference in New Issue
Block a user