@@ -27,58 +27,87 @@ export default function ReadmeBadge({ username }: Props) {
2727 }
2828
2929 return (
30- < div style = { { width : '100%' , marginBottom : '22px' , display : 'flex' , justifyContent : 'center' } } >
31- < div
32- className = "record-card"
33- style = { {
34- width : 'min(520px, 100%)' ,
35- border : '2px solid #1a1a1a' ,
36- borderRadius : '0px' ,
37- boxShadow : '0 1px 4px rgba(0,0,0,0.05)' ,
38- padding : '14px 16px' ,
39- } }
40- >
41- { /* Badge preview — aspect-ratio wrapper prevents layout shift while loading */ }
42- < div style = { { width : '100%' , aspectRatio : '440 / 96' } } >
43- { /* eslint-disable-next-line @next/next/no-img-element */ }
44- < img
45- src = { `/api/badge?username=${ username } &v=${ BADGE_VERSION } ` }
46- alt = { altText }
47- loading = "lazy"
48- decoding = "async"
30+ < div className = "readme-badge-block" style = { { width : '100%' , marginBottom : '22px' } } >
31+ { /* Badge preview — the SVG already has its own border; keep the wrapper borderless */ }
32+ < div className = "readme-badge-preview" style = { { width : '100%' , aspectRatio : '440 / 96' , display : 'flex' , alignItems : 'center' , justifyContent : 'center' } } >
33+ { svg ? (
34+ < div
35+ aria-label = { altText }
36+ role = "img"
4937 style = { { width : '100%' , height : '100%' , display : 'block' } }
38+ // SVG is generated by our own API route.
39+ dangerouslySetInnerHTML = { { __html : svg } }
5040 />
51- </ div >
52-
53- { /* Copy row */ }
54- < div style = { { display : 'flex' , alignItems : 'center' , justifyContent : 'space-between' , gap : '12px' , marginTop : '10px' } } >
55- < p className = "readme-badge-caption" style = { { fontFamily : MONO , margin : 0 , textAlign : 'left' } } >
56- ↻ paste once — updates automatically
57- </ p >
58- < button
59- onClick = { handleCopy }
60- className = "readme-copy-btn"
41+ ) : (
42+ < div
43+ aria-label = { altText }
44+ role = "img"
6145 style = { {
62- fontFamily : MONO ,
63- fontSize : '10px' ,
64- fontWeight : 700 ,
65- letterSpacing : '0.06em' ,
66- padding : '8px 14px' ,
67- minHeight : '36px' ,
68- background : copied ? '#2d7a3c' : 'transparent' ,
69- color : copied ? '#fff' : '#4a4440' ,
70- border : `2px solid ${ copied ? '#2d7a3c' : '#cec6bb' } ` ,
71- cursor : 'pointer' ,
72- transition : 'all 0.15s' ,
73- whiteSpace : 'nowrap' ,
74- flexShrink : 0 ,
46+ width : '100%' ,
47+ height : '100%' ,
48+ border : '2px solid #1a1a1a' ,
49+ background : 'var(--c-bg)' ,
50+ display : 'flex' ,
51+ alignItems : 'center' ,
52+ justifyContent : 'center' ,
53+ padding : '10px' ,
54+ textAlign : 'center' ,
7555 } }
76- onMouseEnter = { e => { if ( ! copied ) { e . currentTarget . style . borderColor = '#1a1a1a' ; e . currentTarget . style . color = '#1a1a1a' } } }
77- onMouseLeave = { e => { if ( ! copied ) { e . currentTarget . style . borderColor = '#cec6bb' ; e . currentTarget . style . color = '#4a4440' } } }
7856 >
79- { copied ? '✓ copied!' : '⎘ copy to readme' }
80- </ button >
81- </ div >
57+ < span
58+ style = { {
59+ fontFamily : MONO ,
60+ fontSize : '11px' ,
61+ fontWeight : 700 ,
62+ letterSpacing : '0.12em' ,
63+ textTransform : 'uppercase' ,
64+ color : svgError ? '#8B0000' : 'var(--c-muted)' ,
65+ } }
66+ >
67+ { svgError ? 'could not load graveyard badge' : 'loading graveyard badge…' }
68+ </ span >
69+ </ div >
70+ ) }
71+ </ div >
72+
73+ { /* Copy row */ }
74+ < div className = "readme-badge-row" style = { { marginTop : '10px' , flexWrap : 'wrap' , justifyContent : 'space-between' } } >
75+ < p className = "readme-badge-caption" style = { { fontFamily : MONO , margin : 0 , textAlign : 'left' } } >
76+ ↻ paste once — updates automatically
77+ </ p >
78+ < button
79+ onClick = { handleCopy }
80+ className = "readme-copy-btn"
81+ style = { {
82+ fontFamily : MONO ,
83+ fontSize : '10px' ,
84+ fontWeight : 700 ,
85+ letterSpacing : '0.06em' ,
86+ padding : '8px 14px' ,
87+ minHeight : '36px' ,
88+ background : copied ? '#2d7a3c' : 'transparent' ,
89+ color : copied ? '#fff' : '#4a4440' ,
90+ border : `2px solid ${ copied ? '#2d7a3c' : '#cec6bb' } ` ,
91+ cursor : 'pointer' ,
92+ transition : 'all 0.15s' ,
93+ whiteSpace : 'nowrap' ,
94+ flexShrink : 0 ,
95+ } }
96+ onMouseEnter = { e => {
97+ if ( ! copied ) {
98+ e . currentTarget . style . borderColor = '#1a1a1a'
99+ e . currentTarget . style . color = '#1a1a1a'
100+ }
101+ } }
102+ onMouseLeave = { e => {
103+ if ( ! copied ) {
104+ e . currentTarget . style . borderColor = '#cec6bb'
105+ e . currentTarget . style . color = '#4a4440'
106+ }
107+ } }
108+ >
109+ { copied ? '✓ copied!' : '⎘ copy to readme' }
110+ </ button >
82111 </ div >
83112 </ div >
84113 )
0 commit comments