|
5 | 5 | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
6 | 6 | <title>Developer Tools Directory - TMHSDigital</title> |
7 | 7 | <meta name="description" content="Centralized directory of TMHSDigital developer tools, Cursor IDE plugins, and MCP servers." /> |
| 8 | + <link rel="canonical" href="https://tmhsdigital.github.io/Developer-Tools-Directory/" /> |
8 | 9 | <meta property="og:title" content="Developer Tools Directory - TMHSDigital" /> |
9 | 10 | <meta property="og:description" content="Centralized directory of TMHSDigital developer tools, Cursor IDE plugins, and MCP servers." /> |
10 | 11 | <meta property="og:type" content="website" /> |
| 12 | + <meta property="og:url" content="https://tmhsdigital.github.io/Developer-Tools-Directory/" /> |
11 | 13 | <meta property="og:image" content="assets/logo.png" /> |
| 14 | + <meta name="twitter:card" content="summary_large_image" /> |
| 15 | + <meta name="twitter:title" content="Developer Tools Directory - TMHSDigital" /> |
| 16 | + <meta name="twitter:description" content="Centralized directory of TMHSDigital developer tools, Cursor IDE plugins, and MCP servers." /> |
| 17 | + <meta name="twitter:image" content="assets/logo.png" /> |
12 | 18 | <link rel="icon" href="assets/logo.png" /> |
13 | 19 | <link rel="preload" as="font" type="font/woff2" crossorigin href="fonts/inter-regular.woff2" /> |
14 | 20 | <link rel="preload" as="font" type="font/woff2" crossorigin href="fonts/inter-bold.woff2" /> |
|
21 | 27 |
|
22 | 28 | *,*::before,*::after{box-sizing:border-box;margin:0;padding:0} |
23 | 29 |
|
| 30 | + /* Shared design tokens mirror site-template/tokens.css (the canonical |
| 31 | + source). tests/test_design_tokens.py enforces the mirror. The themeable |
| 32 | + --accent / --accent-light / --bg / --nav-bg are catalog-specific. */ |
24 | 33 | :root{ |
25 | 34 | --accent:#7c3aed;--accent-light:#a78bfa;--accent-glow:rgba(124,58,237,0.15); |
26 | 35 | --bg:#0d1117;--bg2:#161b22;--bg3:#1c2128;--bg-hover:#22272e; |
|
30 | 39 | --font-sans:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif; |
31 | 40 | --font-mono:'JetBrains Mono','Fira Code',Consolas,monospace; |
32 | 41 | --radius:8px;--radius-lg:12px; |
| 42 | + --hero-h1:2.5rem;--stat-size:1.75rem;--link-hover:#c4b5fd; |
33 | 43 | } |
34 | 44 |
|
35 | 45 | @media(prefers-color-scheme:light){ |
36 | 46 | html:not([data-theme="dark"]){ |
37 | 47 | --bg:#f6f8fa;--bg2:#ffffff;--bg3:#f0f2f5;--bg-hover:#e8ebef; |
38 | | - --border:#d0d7de;--text:#1f2328;--text-dim:#656d76;--text-muted:#8b949e; |
| 48 | + --border:#d0d7de;--text:#1f2328;--text-dim:#656d76;--text-muted:#5b6470; |
39 | 49 | --nav-bg:rgba(255,255,255,0.88);--accent-glow:rgba(124,58,237,0.08); |
40 | 50 | } |
41 | 51 | } |
42 | 52 | [data-theme="light"]{ |
43 | 53 | --bg:#f6f8fa;--bg2:#ffffff;--bg3:#f0f2f5;--bg-hover:#e8ebef; |
44 | | - --border:#d0d7de;--text:#1f2328;--text-dim:#656d76;--text-muted:#8b949e; |
| 54 | + --border:#d0d7de;--text:#1f2328;--text-dim:#656d76;--text-muted:#5b6470; |
45 | 55 | --nav-bg:rgba(255,255,255,0.88);--accent-glow:rgba(124,58,237,0.08); |
46 | 56 | } |
47 | 57 |
|
48 | 58 | html{scroll-behavior:smooth} |
49 | 59 | body{font-family:var(--font-sans);background:var(--bg);color:var(--text);line-height:1.6;min-height:100vh} |
50 | 60 | a{color:var(--accent-light);text-decoration:none;transition:color .2s} |
51 | | - a:hover{color:#c4b5fd} |
| 61 | + a:hover{color:var(--link-hover)} |
| 62 | + /* Light mode: hovered links use the darker accent for WCAG AA contrast. */ |
52 | 63 | [data-theme="light"] a{color:var(--accent)} |
53 | | - @media(prefers-color-scheme:light){html:not([data-theme="dark"]) a{color:var(--accent)}} |
| 64 | + [data-theme="light"] a:hover{color:var(--accent)} |
| 65 | + @media(prefers-color-scheme:light){html:not([data-theme="dark"]) a{color:var(--accent)}html:not([data-theme="dark"]) a:hover{color:var(--accent)}} |
54 | 66 |
|
55 | 67 | /* NAV */ |
56 | 68 | .nav{position:sticky;top:0;z-index:100;background:var(--nav-bg);backdrop-filter:blur(12px);border-bottom:1px solid var(--border);padding:0 1.5rem} |
|
70 | 82 | .hero{text-align:center;padding:4rem 1.5rem 3rem;background:linear-gradient(180deg,var(--bg) 0%,var(--bg2) 70%,var(--bg) 100%);position:relative} |
71 | 83 | .hero-inner{max-width:800px;margin:0 auto} |
72 | 84 | .hero-logo{width:80px;height:80px;border-radius:50%;object-fit:cover;margin-bottom:1.25rem;box-shadow:0 4px 24px rgba(0,0,0,.3);border:2px solid var(--border)} |
73 | | - .hero h1{font-size:2.5rem;font-weight:700;margin-bottom:1rem;background:linear-gradient(135deg,var(--text),var(--accent-light));-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text} |
| 85 | + .hero h1{font-size:var(--hero-h1);font-weight:700;margin-bottom:1rem;background:linear-gradient(135deg,var(--text),var(--accent-light));-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text} |
74 | 86 | .hero p{font-size:1.125rem;color:var(--text-dim);margin-bottom:2rem;max-width:600px;margin-left:auto;margin-right:auto} |
75 | 87 |
|
76 | 88 | .stats-bar{display:flex;justify-content:center;gap:2rem;flex-wrap:wrap;margin-bottom:1rem} |
77 | 89 | .stat-item{text-align:center} |
78 | | - .stat-value{font-size:1.75rem;font-weight:700;color:var(--accent-light);font-family:var(--font-mono)} |
| 90 | + .stat-value{font-size:var(--stat-size);font-weight:700;color:var(--accent-light);font-family:var(--font-mono)} |
79 | 91 | .stat-label{font-size:.75rem;color:var(--text-muted);text-transform:uppercase;letter-spacing:.05em} |
80 | 92 |
|
81 | 93 | .search-bar{max-width:480px;margin:0 auto 1.5rem;padding:0 1.5rem;position:relative} |
|
147 | 159 | details.cat-group>.cat-body{overflow:hidden} |
148 | 160 | .cat-body-anim{transition:max-height .25s ease,opacity .2s ease;overflow:hidden} |
149 | 161 | .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0} |
| 162 | + .skip-link{position:absolute;left:.5rem;top:-3rem;z-index:300;background:var(--accent);color:#fff;padding:.5rem 1rem;border-radius:6px;font-size:.875rem;font-weight:600;transition:top .15s} |
| 163 | + .skip-link:focus{top:.5rem;color:#fff} |
150 | 164 |
|
151 | 165 | /* TOAST */ |
152 | 166 | .toast{position:fixed;bottom:1.5rem;left:50%;transform:translateX(-50%) translateY(100%);background:var(--bg3);border:1px solid var(--border);color:var(--text);padding:.5rem 1.25rem;border-radius:8px;font-size:.8125rem;font-weight:500;opacity:0;transition:transform .3s,opacity .3s;z-index:200;pointer-events:none} |
|
198 | 212 | </head> |
199 | 213 | <body> |
200 | 214 |
|
| 215 | + <a href="#main" class="skip-link">Skip to content</a> |
| 216 | + |
201 | 217 | <nav class="nav"> |
202 | 218 | <div class="nav-inner"> |
203 | 219 | <a href="#" class="nav-brand"> |
|
221 | 237 | </div> |
222 | 238 | </nav> |
223 | 239 |
|
| 240 | + <main id="main"> |
| 241 | + |
224 | 242 | <section class="hero"> |
225 | 243 | <div class="hero-inner"> |
226 | 244 | <img class="hero-logo" src="assets/logo.png" alt="Developer Tools Directory logo" /> |
@@ -317,6 +335,8 @@ <h3>Scaffold Generator</h3> |
317 | 335 |
|
318 | 336 | </div> |
319 | 337 |
|
| 338 | + </main> |
| 339 | + |
320 | 340 | <footer> |
321 | 341 | <div class="footer-inner"> |
322 | 342 | <div class="footer-links"> |
@@ -388,6 +408,7 @@ <h3>Scaffold Generator</h3> |
388 | 408 | function updateIcon(s){ |
389 | 409 | setIconChildren(iconSvgs[s]||iconSvgs.auto); |
390 | 410 | btn.title='Theme: '+s; |
| 411 | + btn.setAttribute('aria-label','Theme: '+s+' (click to change)'); |
391 | 412 | } |
392 | 413 | btn.addEventListener('click',function(){var c=getState();apply(states[(states.indexOf(c)+1)%states.length])}); |
393 | 414 | updateIcon(getState()); |
|
0 commit comments