Skip to content
This repository was archived by the owner on Apr 24, 2026. It is now read-only.

Commit c48ba09

Browse files
authored
Merge pull request #59 from renderghost/feature/unified-link-and-focus-styles
Feature #38: Unified link and focus styles + dashboard improvements
2 parents 61b4b78 + cec18f8 commit c48ba09

16 files changed

Lines changed: 96 additions & 67 deletions

File tree

‎src/app/auth/page.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export default function AuthPage() {
3333
href="https://bsky.app"
3434
target="_blank"
3535
rel="noopener noreferrer"
36-
className="text-primary underline-offset-4 hover:underline"
36+
className="leading-normal"
3737
>
3838
Create one here
3939
</Link>
@@ -44,7 +44,7 @@ export default function AuthPage() {
4444
href="https://bsky.app/settings/app-passwords"
4545
target="_blank"
4646
rel="noopener noreferrer"
47-
className="text-primary underline-offset-4 hover:underline"
47+
className="leading-normal"
4848
>
4949
Generate one in settings
5050
</Link>

‎src/app/dashboard/about/affiliations/page.tsx‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ export default async function AffiliationsPage() {
100100
<div className="flex items-center gap-2">
101101
<Link
102102
href={`/dashboard/about/affiliations/edit?rkey=${encodeURIComponent(affiliation.uri.split('/').pop() || '')}`}
103-
className="hover:underline"
104103
>
105104
<CardTitle className="text-base leading-tight">
106105
{affiliation.organizationName}

‎src/app/dashboard/about/qualifications/page.tsx‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ export default async function QualificationsPage() {
100100
<div className="flex items-center gap-2">
101101
<Link
102102
href={`/dashboard/about/qualifications/edit?rkey=${encodeURIComponent(qualification.uri.split('/').pop() || '')}`}
103-
className="hover:underline"
104103
>
105104
<CardTitle className="text-base leading-tight">
106105
{qualification.title}

‎src/app/dashboard/about/skills/page.tsx‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ export default async function SkillsPage() {
100100
<div className="flex items-center gap-2">
101101
<Link
102102
href={`/dashboard/about/skills/edit?rkey=${encodeURIComponent(skill.uri.split('/').pop() || '')}`}
103-
className="hover:underline"
104103
>
105104
<CardTitle className="text-base leading-tight">
106105
{skill.name}

‎src/app/dashboard/events/page.tsx‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ export default async function EventsPage() {
106106
<div className="flex items-center gap-2">
107107
<Link
108108
href={`/dashboard/events/edit?rkey=${encodeURIComponent(event.rkey)}`}
109-
className="hover:underline"
110109
>
111110
<CardTitle className="text-base leading-tight">
112111
{event.name}
@@ -152,7 +151,7 @@ export default async function EventsPage() {
152151
href={event.url}
153152
target="_blank"
154153
rel="noopener noreferrer"
155-
className="inline-flex items-center gap-1 text-sm text-foreground hover:underline mt-2"
154+
className="inline-flex items-center gap-1 text-sm mt-2 leading-normal"
156155
>
157156
<ExternalLink className="h-3 w-3 shrink-0" />
158157
{formatDisplayURL(event.url)}

‎src/app/dashboard/links/page.tsx‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ export default async function LinksPage() {
100100
<div className="space-y-1 flex-1 min-w-0">
101101
<Link
102102
href={`/dashboard/links/edit?rkey=${encodeURIComponent(link.rkey)}`}
103-
className="hover:underline"
104103
>
105104
<CardTitle className="text-base leading-tight">
106105
{link.title || 'Web Link'}
@@ -110,7 +109,7 @@ export default async function LinksPage() {
110109
href={link.url}
111110
target="_blank"
112111
rel="noopener noreferrer"
113-
className="inline-flex items-center gap-1 text-sm text-foreground hover:underline break-all"
112+
className="inline-flex items-center gap-1 text-sm break-all leading-normal"
114113
>
115114
<ExternalLink className="h-3 w-3 shrink-0" />
116115
{formatDisplayURL(link.url)}

‎src/app/dashboard/page.tsx‎

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,7 @@ export default async function DashboardPage() {
7777
</div>
7878
</header>
7979

80-
<div className="flex flex-1 flex-col gap-4 p-4">
81-
<div className="mx-auto w-full max-w-2xl">
82-
<h1 className="text-xl font-semibold">Profile</h1>
83-
<p className="text-sm text-muted-foreground">
84-
Update your profile information
85-
</p>
86-
</div>
80+
<div className="flex flex-1 flex-col p-4">
8781
<div className="mx-auto w-full max-w-2xl">
8882
<ProfileForm profile={profile} />
8983
</div>

‎src/app/dashboard/research/page.tsx‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ export default async function ResearchPage() {
101101
<div className="space-y-1 flex-1 min-w-0">
102102
<Link
103103
href={`/dashboard/research/edit?rkey=${encodeURIComponent(work.rkey)}`}
104-
className="hover:underline"
105104
>
106105
<CardTitle className="text-base leading-tight">
107106
{work.title || work.doi}
@@ -142,7 +141,7 @@ export default async function ResearchPage() {
142141
href={`https://doi.org/${normalizeDOI(work.doi)}`}
143142
target="_blank"
144143
rel="noopener noreferrer"
145-
className="inline-flex items-center gap-1 text-sm text-foreground hover:underline"
144+
className="inline-flex items-center gap-1 text-sm leading-normal"
146145
>
147146
<ExternalLink className="h-3 w-3" />
148147
doi.org/{normalizeDOI(work.doi)}

‎src/app/dashboard/socials/page.tsx‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ export default async function SocialsPage() {
115115
<div className="space-y-1 flex-1 min-w-0">
116116
<Link
117117
href={`/dashboard/socials/edit?rkey=${encodeURIComponent(social.rkey)}`}
118-
className="hover:underline"
119118
>
120119
<CardTitle className="text-base leading-tight">
121120
{platform.label}
@@ -125,7 +124,7 @@ export default async function SocialsPage() {
125124
href={social.url}
126125
target="_blank"
127126
rel="noopener noreferrer"
128-
className="inline-flex items-center gap-1 text-sm text-foreground hover:underline break-all"
127+
className="inline-flex items-center gap-1 text-sm break-all leading-normal"
129128
>
130129
<ExternalLink className="h-3 w-3 shrink-0" />
131130
{formatDisplayURL(social.url)}

‎src/app/globals.css‎

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -59,35 +59,37 @@
5959
--background: var(--color-purple-muted-50);
6060
--foreground: var(--color-purple-muted-950);
6161
--card: var(--color-mono-white);
62-
--card-foreground: var(--color-purple-muted-1000);
62+
--card-foreground: var(--color-purple-muted-900);
6363
--popover: var(--color-mono-white);
64-
--popover-foreground: var(--color-purple-muted-1000);
64+
--popover-foreground: var(--color-purple-muted-900);
6565
--primary: var(--color-purple-vivid-800);
6666
--primary-foreground: var(--color-mono-white);
67-
--secondary: var(--color-purple-muted-300);
67+
--secondary: var(--color-purple-muted-200);
6868
--secondary-foreground: var(--color-purple-muted-900);
69-
--muted: var(--color-purple-muted-400);
69+
--muted: var(--color-purple-muted-200);
7070
--muted-foreground: var(--color-purple-muted-950);
7171
--accent: var(--color-purple-vivid-50);
7272
--accent-foreground: var(--color-purple-muted-900);
7373
--destructive: var(--color-red-400);
74-
--destructive-foreground: var(--color-purple-muted-1000);
74+
--destructive-foreground: var(--color-purple-muted-900);
7575
--border: var(--color-purple-muted-700);
7676
--input: var(--color-purple-muted-400);
77-
--ring: var(--color-purple-vivid-800);
77+
--ring: var(--color-purple-vivid-500);
7878
--chart-1: var(--color-purple-vivid-500);
7979
--chart-2: var(--color-purple-vivid-600);
8080
--chart-3: var(--color-purple-vivid-700);
8181
--chart-4: var(--color-purple-vivid-900);
8282
--chart-5: var(--color-purple-vivid-950);
83-
--sidebar: var(--color-purple-muted-200);
84-
--sidebar-foreground: var(--color-purple-muted-1000);
83+
--sidebar: var(--color-purple-muted-50);
84+
--sidebar-foreground: var(--color-purple-muted-900);
8585
--sidebar-primary: var(--color-purple-vivid-800);
8686
--sidebar-primary-foreground: var(--color-mono-white);
8787
--sidebar-accent: var(--color-purple-muted-100);
88-
--sidebar-accent-foreground: var(--color-purple-muted-1000);
88+
--sidebar-accent-foreground: var(--color-purple-muted-900);
8989
--sidebar-border: var(--color-purple-muted-700);
90-
--sidebar-ring: var(--color-purple-vivid-800);
90+
--sidebar-ring: var(--color-purple-vivid-500);
91+
--link-hover: var(--color-purple-vivid-500);
92+
--focus-ring: var(--color-purple-vivid-500);
9193
--font-sans: 'DM Sans', ui-sans-serif, sans-serif, system-ui;
9294
--font-serif: 'DM Serif Text', ui-serif, serif;
9395
--font-mono: 'DM Mono', ui-monospace, monospace;
@@ -135,7 +137,7 @@
135137
--destructive-foreground: var(--color-purple-muted-900);
136138
--border: var(--color-purple-muted-800);
137139
--input: var(--color-purple-muted-700);
138-
--ring: var(--color-yellow-500);
140+
--ring: var(--color-yellow-vivid-500);
139141
--chart-1: var(--color-purple-vivid-400);
140142
--chart-2: var(--color-purple-vivid-500);
141143
--chart-3: var(--color-purple-vivid-600);
@@ -144,11 +146,13 @@
144146
--sidebar: var(--color-purple-vivid-950);
145147
--sidebar-foreground: var(--color-purple-muted-100);
146148
--sidebar-primary: var(--color-purple-vivid-500);
147-
--sidebar-primary-foreground: var(--color-purple-muted-1000);
149+
--sidebar-primary-foreground: var(--color-purple-muted-900);
148150
--sidebar-accent: var(--color-purple-muted-900);
149-
--sidebar-accent-foreground: var(--color-purple-muted-500);
151+
--sidebar-accent-foreground: var(--color-yellow-vivid-500);
150152
--sidebar-border: var(--color-purple-muted-800);
151-
--sidebar-ring: var(--color-yellow-500);
153+
--sidebar-ring: var(--color-yellow-vivid-500);
154+
--link-hover: var(--color-yellow-vivid-500);
155+
--focus-ring: var(--color-yellow-vivid-500);
152156
--font-sans: 'DM Sans', ui-sans-serif, sans-serif, system-ui;
153157
--font-serif: 'DM Serif Text', ui-serif, serif;
154158
--font-mono: 'DM Mono', ui-monospace, monospace;
@@ -203,6 +207,8 @@
203207
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
204208
--color-sidebar-border: var(--sidebar-border);
205209
--color-sidebar-ring: var(--sidebar-ring);
210+
--color-link-hover: var(--link-hover);
211+
--color-focus-ring: var(--focus-ring);
206212

207213
--font-sans: var(--font-sans);
208214
--font-mono: var(--font-mono);
@@ -241,4 +247,36 @@
241247
-webkit-font-smoothing: antialiased;
242248
-moz-osx-font-smoothing: grayscale;
243249
}
250+
251+
/* Unified focus state for all focusable elements */
252+
*:focus-visible {
253+
outline: 2px solid var(--color-focus-ring);
254+
outline-offset: 2px;
255+
border-radius: var(--radius);
256+
}
257+
258+
/* Unified link styling */
259+
a:not([data-slot="button"]):not([data-sidebar]) {
260+
color: var(--foreground);
261+
text-decoration: underline;
262+
text-decoration-thickness: 1px;
263+
text-underline-offset: 2px;
264+
}
265+
266+
a:not([data-slot="button"]):not([data-sidebar]):hover,
267+
a:not([data-slot="button"]):not([data-sidebar]):focus {
268+
color: var(--link-hover);
269+
}
270+
271+
/* Sidebar link styling */
272+
a[data-sidebar]:hover,
273+
a[data-sidebar]:focus {
274+
color: var(--color-purple-vivid-500);
275+
}
276+
277+
/* Placeholder text styling */
278+
::placeholder {
279+
color: var(--color-purple-muted-500);
280+
opacity: 1;
281+
}
244282
}

0 commit comments

Comments
 (0)