Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/blog/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export default async function BlogPost({ params }: { params: Promise<{ slug: str
<div className="flex items-center gap-3">
<Link
href="/blog/"
className="px-4 py-2 bg-bg-secondary border border-border rounded-lg hover:bg-accent hover:text-white hover:border-accent transition-colors text-sm font-semibold"
className="px-4 py-2 bg-bg-secondary border border-border rounded-lg hover:bg-accent hover:text-on-accent hover:border-accent transition-colors text-sm font-semibold"
>
← Back to Blog
</Link>
Expand Down
2 changes: 1 addition & 1 deletion app/contact/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default function Contact() {
<div className="glass-card shine-effect rounded-xl p-6">
<div className="flex items-center gap-4 mb-4">
<div className="w-12 h-12 bg-gradient-to-br from-accent to-accent-hover rounded-xl flex items-center justify-center icon-bounce shadow-lg">
<FaEnvelope className="w-6 h-6 text-white" />
<FaEnvelope className="w-6 h-6 text-on-accent" />
</div>
<h2 className="text-2xl font-semibold text-text-primary">Email</h2>
</div>
Expand Down
109 changes: 101 additions & 8 deletions app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,25 @@
--accent-hover: #0d5a88; /* Darker blue for hover */
--accent-orange: #fc7d0b; /* Bright Orange */
--accent-orange-hover: #c85200; /* Dark Orange/Brown for hover */
/* Text/icon color to use ON TOP OF an --accent or --accent-orange
background. --accent is dark enough here for white to read clearly;
dark and Xanga themes use a lighter --accent, so they need dark text
instead (see overrides below). --accent-orange is bright in every
theme, so dark text is always the right call for it. */
--on-accent: #ffffff;
--on-accent-orange: #1a1a1a;
/* Fixed (non-theme-dependent) blue used for the small number of buttons
that are deliberately "the blue button" as opposed to "the theme's
highlight color" (e.g. distinguishing two CTAs from each other on the
same page). Unlike --accent, this never changes with the theme -
Xanga's --accent is bright orange, so reusing --accent here would make
a "blue" button render orange and become indistinguishable from an
orange one. Deliberately not overridden in the dark/Xanga blocks below
so every theme gets the same value. Dark enough that white text always
has sufficient contrast on it. */
--accent-blue: #1170aa;
--accent-blue-hover: #0d5a88;
--on-accent-blue: #ffffff;
--border: #c8d0d9; /* Very Light Gray from palette */
--link: #1170aa; /* Dark Blue for links */
--link-hover: #fc7d0b; /* Bright Orange for link hover */
Expand All @@ -35,6 +54,10 @@
--accent-hover: #1170aa; /* Dark Blue */
--accent-orange: #fc7d0b; /* Bright Orange */
--accent-orange-hover: #ffbc79; /* Light Peach for hover */
/* --accent is a light medium-blue here, so white text on it fails
contrast - use dark text instead. */
--on-accent: #0b1220;
--on-accent-orange: #1a1a1a;
--border: #57606c; /* Dark Gray from palette */
--link: #5fa2ce; /* Medium Blue for links */
--link-hover: #fc7d0b; /* Bright Orange for link hover */
Expand All @@ -59,6 +82,10 @@
--accent-light: #ffbc79; /* Tableau Light Peach */
--accent-navy: #1170aa; /* Tableau Dark Blue */
--accent-navy-light: #5fa2ce; /* Tableau Medium Blue */
/* --accent is bright orange here (same as --accent-orange), so it
needs dark text too. */
--on-accent: #0a0a0a;
--on-accent-orange: #1a1a1a;
--border: #fc7d0b; /* Tableau Bright Orange */
--border-navy: #1170aa; /* Tableau Dark Blue */
--link: #5fa2ce; /* Tableau Medium Blue */
Expand Down Expand Up @@ -162,9 +189,13 @@ html[data-theme="xanga"] body .xanga-shell button:hover {
border-color: var(--accent-navy) !important;
}

/* Keep modern header stable: only restyle these inside Xanga shell */
html[data-theme="xanga"] body .xanga-shell .bg-bg-secondary,
html[data-theme="xanga"] body .xanga-shell [class*="bg-bg-secondary"] {
/* Keep modern header stable: only restyle these inside Xanga shell.
Excludes elements that switch their own background to --accent(-orange)
on hover/focus (e.g. the Share button, "Back to Blog" link) - otherwise
this pins their resting background !important, and hover:bg-accent can
never actually take effect. */
html[data-theme="xanga"] body .xanga-shell .bg-bg-secondary:not([class*="hover:bg-accent"]),
html[data-theme="xanga"] body .xanga-shell [class*="bg-bg-secondary"]:not([class*="hover:bg-accent"]) {
background-color: var(--bg-secondary) !important;
}

Expand Down Expand Up @@ -232,6 +263,42 @@ html[data-theme="xanga"] body header nav a:focus-visible * {
color: var(--accent-orange) !important;
}

/* Any link with its own bg-accent background (active mobile-nav items, the
404 page's "Go Home" button, etc.) needs matching --on-accent text - the
blanket link-color override above (and, in Xanga, --accent being the same
bright orange as --accent-orange) would otherwise put low-contrast text
on top of that background. This is deliberately not scoped to "header"
only: the mobile nav menu is a sibling of <nav> rather than nested inside
it, and the same bg-accent-on-a-link pattern shows up outside the header
too. */
html[data-theme="xanga"] body a[class*="bg-accent"],
html[data-theme="xanga"] body a[class*="bg-accent"]:hover,
html[data-theme="xanga"] body a[class*="bg-accent"]:focus-visible {
color: var(--on-accent) !important;
}
html[data-theme="xanga"] body a[class*="bg-accent"] *,
html[data-theme="xanga"] body a[class*="bg-accent"]:hover *,
html[data-theme="xanga"] body a[class*="bg-accent"]:focus-visible * {
color: var(--on-accent) !important;
}

/* Same problem outside the header: several buttons keep a permanent
text-accent/text-text-primary/text-text-secondary class for their resting
state, then switch their own background to --accent or --accent-orange on
hover/focus (e.g. Back to Top, the sidebar restore icon, the mobile nav's
inactive links, the Xanga sidebar nav applet). The blanket text-color
overrides above apply unconditionally, so without this they'd pin the
icon/text color even once the background behind it has also become
--accent, making it unreadable. */
html[data-theme="xanga"] body [class*="hover:bg-accent-orange"]:hover,
html[data-theme="xanga"] body [class*="hover:bg-accent-orange"]:focus-visible {
color: var(--on-accent-orange) !important;
}
html[data-theme="xanga"] body [class*="hover:bg-accent"]:not([class*="hover:bg-accent-orange"]):hover,
html[data-theme="xanga"] body [class*="hover:bg-accent"]:not([class*="hover:bg-accent-orange"]):focus-visible {
color: var(--on-accent) !important;
}

/* Light and dark: same nav hover (text color change, no box) */
html[data-theme="light"] body header nav a:hover,
html[data-theme="light"] body header nav a:focus-visible,
Expand All @@ -257,9 +324,14 @@ html[data-theme="xanga"] body footer {
border-top: 1px solid var(--border-navy) !important;
}

/* Card styling for Xanga mode */
html[data-theme="xanga"] body [class*="rounded-lg"],
html[data-theme="xanga"] body [class*="card"],
/* Card styling for Xanga mode. Excludes anything with a bg-accent(-orange)
class (buttons/links/CTAs that already carry their own background
intent, e.g. the Share button or "Back to Blog" link) - otherwise this
forces a card-style background/border/padding onto them and, worse,
!important-pins their background so hover:bg-accent can never actually
show. */
html[data-theme="xanga"] body [class*="rounded-lg"]:not([class*="bg-accent"]),
html[data-theme="xanga"] body [class*="card"]:not([class*="bg-accent"]),
html[data-theme="xanga"] body article,
html[data-theme="xanga"] body section {
background-color: var(--bg-secondary) !important;
Expand Down Expand Up @@ -625,7 +697,10 @@ html[data-theme="xanga"] body ::-webkit-scrollbar-thumb:hover {
border-radius: 12px;
border: none;
background: linear-gradient(135deg, var(--accent-orange) 0%, var(--accent-orange-hover) 100%);
color: white;
/* !important: in Xanga mode, the generic "body a" link-color rule has
higher selector specificity than this class alone and would otherwise
win even without !important on its side. */
color: var(--on-accent-orange) !important;
font-weight: 600;
cursor: pointer;
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
Expand All @@ -639,7 +714,11 @@ html[data-theme="xanga"] body ::-webkit-scrollbar-thumb:hover {
}

.gradient-btn-blue {
background: linear-gradient(135deg, var(--accent) 0%, var(--accent-hover) 100%);
/* Uses the fixed --accent-blue tokens (not --accent) so this button stays
visually blue - and distinct from the orange .gradient-btn - even in
Xanga mode, where --accent itself is the bright orange highlight color. */
background: linear-gradient(135deg, var(--accent-blue) 0%, var(--accent-blue-hover) 100%);
color: var(--on-accent-blue) !important;
box-shadow: 0 4px 20px rgba(17, 112, 170, 0.4);
}

Expand Down Expand Up @@ -752,6 +831,20 @@ html[data-theme="xanga"] body ::-webkit-scrollbar-thumb:hover {
color: #a8b4c4 !important;
}

/* Same escape hatch as Xanga above: elements that keep a permanent
text-text-secondary class but switch their own background to --accent or
--accent-orange on hover/focus (e.g. inactive mobile-nav links) need this
dark-mode contrast override to step aside once that happens, or the text
stays a light blue-gray on top of a bright orange hover background. */
[data-theme="dark"] [class*="hover:bg-accent-orange"]:hover,
[data-theme="dark"] [class*="hover:bg-accent-orange"]:focus-visible {
color: var(--on-accent-orange) !important;
}
[data-theme="dark"] [class*="hover:bg-accent"]:not([class*="hover:bg-accent-orange"]):hover,
[data-theme="dark"] [class*="hover:bg-accent"]:not([class*="hover:bg-accent-orange"]):focus-visible {
color: var(--on-accent) !important;
}

/* Subtle Section Background */
.section-highlight {
position: relative;
Expand Down
2 changes: 1 addition & 1 deletion app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export default function RootLayout({
<body className={`${openSans.className} ${openSans.variable}`} suppressHydrationWarning>
<a
href="#main-content"
className="sr-only focus:not-sr-only focus:absolute focus:top-2 focus:left-2 focus:z-[100] focus:rounded focus:bg-accent focus:px-4 focus:py-2 focus:text-white focus:shadow-lg"
className="sr-only focus:not-sr-only focus:absolute focus:top-2 focus:left-2 focus:z-[100] focus:rounded focus:bg-accent focus:px-4 focus:py-2 focus:text-on-accent focus:shadow-lg"
>
Skip to content
</a>
Expand Down
2 changes: 1 addition & 1 deletion app/not-found.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default function NotFound() {
</p>
<Link
href="/"
className="inline-block px-6 py-3 bg-accent text-white rounded-lg hover:bg-accent-hover transition-colors"
className="inline-block px-6 py-3 bg-accent text-on-accent rounded-lg hover:bg-accent-hover transition-colors"
>
Go Home
</Link>
Expand Down
2 changes: 1 addition & 1 deletion app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export default function Home() {
{/* Medium Card */}
<div className="glass-card shine-effect rounded-xl p-8">
<div className="flex items-center gap-4 mb-4">
<div className="w-14 h-14 bg-gradient-to-br from-accent-orange to-accent-orange-hover rounded-xl flex items-center justify-center text-white font-bold text-xl icon-bounce shadow-lg">
<div className="w-14 h-14 bg-gradient-to-br from-accent-orange to-accent-orange-hover rounded-xl flex items-center justify-center text-on-accent-orange font-bold text-xl icon-bounce shadow-lg">
M
</div>
<h3 className="text-3xl font-bold text-text-primary">Medium</h3>
Expand Down
2 changes: 1 addition & 1 deletion components/BackToTop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function BackToTop() {
onClick={scrollToTop}
aria-label="Back to top"
title="Back to top"
className={`fixed bottom-6 right-6 z-40 flex h-11 w-11 items-center justify-center rounded-full border border-border bg-bg-primary text-accent shadow-lg transition-all duration-300 hover:bg-accent hover:text-white hover:border-accent focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent ${
className={`fixed bottom-6 right-6 z-40 flex h-11 w-11 items-center justify-center rounded-full border border-border bg-bg-primary text-accent shadow-lg transition-all duration-300 hover:bg-accent hover:text-on-accent hover:border-accent focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent ${
visible
? 'opacity-100 translate-y-0 pointer-events-auto'
: 'opacity-0 translate-y-4 pointer-events-none'
Expand Down
28 changes: 14 additions & 14 deletions components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ function ThemeMenu({ theme, setTheme }: { theme: Theme; setTheme: (t: Theme) =>
aria-expanded={open}
aria-label={`Theme: ${themeLabel(theme)}. Open theme menu`}
title={`Theme: ${themeLabel(theme)}`}
className="relative w-9 h-9 flex items-center justify-center text-accent hover:bg-bg-secondary transition-colors"
className="relative w-9 h-9 flex items-center justify-center rounded text-accent hover:bg-bg-secondary transition-colors focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
>
<ThemeIcon theme={theme} />
<span className="sr-only">Theme: {themeLabel(theme)}. Open theme menu</span>
Expand All @@ -133,7 +133,7 @@ function ThemeMenu({ theme, setTheme }: { theme: Theme; setTheme: (t: Theme) =>
setOpen(false)
triggerRef.current?.focus()
}}
className={`flex w-full items-center gap-2.5 px-3 py-2 text-sm transition-colors ${
className={`flex w-full items-center gap-2.5 px-3 py-2 text-sm transition-colors focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-accent ${
isActive
? 'bg-bg-secondary text-accent font-semibold'
: 'text-text-primary hover:bg-bg-secondary'
Expand Down Expand Up @@ -201,7 +201,7 @@ function DesktopNavLink({
return (
<Link
href={href}
className={`group relative flex items-center gap-1.5 pb-1 transition-colors ${
className={`group relative flex items-center gap-1.5 pb-1 rounded transition-colors focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent ${
isActive ? 'text-accent font-semibold' : 'text-text-secondary hover:text-accent-orange'
}`}
title={vip ? 'VIP Content - Login Required' : undefined}
Expand Down Expand Up @@ -324,7 +324,7 @@ export function Header() {
{showCollapsedIcon && layout && (
<button
onClick={() => layout.restoreSidebar()}
className="relative group w-9 h-9 flex items-center justify-center rounded border border-accent/40 bg-accent/10 text-accent transition-colors hover:bg-accent hover:text-white"
className="relative group w-9 h-9 flex items-center justify-center rounded border border-accent/40 bg-accent/10 text-accent transition-colors hover:bg-accent hover:text-on-accent focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
aria-label={`Restore ${layout.lastVisibleSide} sidebar`}
title="Restore sidebar"
>
Expand All @@ -343,7 +343,7 @@ export function Header() {
aria-expanded={mobileMenuOpen}
aria-controls="mobile-nav"
aria-label={mobileMenuOpen ? 'Close menu' : 'Open menu'}
className="md:hidden relative w-9 h-9 flex items-center justify-center text-text-primary hover:bg-bg-secondary transition-colors"
className="md:hidden relative w-9 h-9 flex items-center justify-center rounded text-text-primary hover:bg-bg-secondary transition-colors focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
>
<HamburgerIcon open={mobileMenuOpen} />
</button>
Expand All @@ -368,10 +368,10 @@ export function Header() {
<Link
key={item.href}
href={item.href}
className={`px-4 py-1.5 rounded text-sm transition-colors flex-1 min-w-[70px] text-center ${
className={`px-4 py-1.5 rounded text-sm transition-colors flex-1 min-w-[70px] text-center focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent ${
isActive
? 'bg-accent text-white'
: 'bg-bg-secondary text-text-secondary hover:bg-accent-orange hover:text-white'
? 'bg-accent text-on-accent'
: 'bg-bg-secondary text-text-secondary hover:bg-accent-orange hover:text-on-accent-orange'
}`}
>
{item.label}
Expand All @@ -396,10 +396,10 @@ export function Header() {
<Link
key={item.href}
href={item.href}
className={`group relative px-3 py-1.5 rounded text-sm transition-colors flex items-center justify-center gap-1.5 flex-1 min-w-[70px] ${
className={`group relative px-3 py-1.5 rounded text-sm transition-colors flex items-center justify-center gap-1.5 flex-1 min-w-[70px] focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent ${
isActive
? 'bg-accent text-white'
: 'bg-bg-secondary text-text-secondary hover:bg-accent-orange hover:text-white'
? 'bg-accent text-on-accent'
: 'bg-bg-secondary text-text-secondary hover:bg-accent-orange hover:text-on-accent-orange'
}`}
title="VIP Content - Login Required"
>
Expand All @@ -419,10 +419,10 @@ export function Header() {
<Link
key={item.href}
href={item.href}
className={`group relative px-3 py-1.5 rounded text-sm transition-colors flex items-center justify-center gap-1.5 flex-1 min-w-[70px] ${
className={`group relative px-3 py-1.5 rounded text-sm transition-colors flex items-center justify-center gap-1.5 flex-1 min-w-[70px] focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent ${
isActive
? 'bg-accent text-white'
: 'bg-bg-secondary text-text-secondary hover:bg-accent-orange hover:text-white'
? 'bg-accent text-on-accent'
: 'bg-bg-secondary text-text-secondary hover:bg-accent-orange hover:text-on-accent-orange'
}`}
title="VIP Content - Login Required"
>
Expand Down
2 changes: 1 addition & 1 deletion components/blog/ShareButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export function ShareButton({ title }: { title: string }) {
<button
type="button"
onClick={handleShare}
className="inline-flex items-center gap-2 px-4 py-2 bg-bg-secondary border border-border rounded-lg hover:bg-accent hover:text-white hover:border-accent transition-colors text-sm font-semibold"
className="inline-flex items-center gap-2 px-4 py-2 bg-bg-secondary border border-border rounded-lg hover:bg-accent hover:text-on-accent hover:border-accent transition-colors text-sm font-semibold"
title="Share this post"
aria-label="Share this post"
>
Expand Down
Loading
Loading