diff --git a/README.md b/README.md index 004207e..f4d3127 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,31 @@ # ProTop.Iop -@ + +A competitive gaming leaderboard and social platform. + +## Pages + +| File | Description | +|------|-------------| +| `profile.html` | User profile page layout | + +## Structure + +``` +ProTop.Iop/ +├── profile.html # User profile page +├── styles/ +│ └── profile.css # Profile page styles +└── scripts/ + └── profile.js # Profile page interactivity (tab switching) +``` + +## User Profile Page + +The profile page (`profile.html`) includes: + +- **Profile hero** – avatar with online status indicator, display name, handle, bio, location, and website +- **Stats bar** – follower count, following count, post count, and global rank +- **Tabbed content** – Posts, Achievements, and Activity tabs with smooth client-side switching +- **Responsive layout** – adapts cleanly to mobile viewports +- **Dark theme** – uses CSS custom properties for consistent theming + diff --git a/profile.html b/profile.html new file mode 100644 index 0000000..6f52fb8 --- /dev/null +++ b/profile.html @@ -0,0 +1,200 @@ + + + + + + User Profile – ProTop + + + + + +
+ +
+
+ Alex Morgan's avatar + +
+ +
+

Alex Morgan

+

@alexmorgan

+

+ Competitive gamer & speedrunner. Top 1% globally in three titles. + Coffee enthusiast ☕ and open-source contributor. +

+ +
+ 📍 San Francisco, CA + 🔗 alexmorgan.gg + 📅 Joined March 2022 +
+
+ +
+ + +
+
+ + +
+
+ 1,284 + Followers +
+
+ 342 + Following +
+
+ 87 + Posts +
+
+ #4 + Global Rank +
+
+ + +
+ + + +
+ + +
+
+
+
+ +
+ Alex Morgan + +
+
+

Just broke my personal record in SpeedBlast — 2:14.33! 🔥 Who's coming for me?

+ +
+ +
+
+ +
+ Alex Morgan + +
+
+

Tips for climbing the leaderboard: consistency > grinding. Play 2 hrs focused > 6 hrs distracted.

+ +
+ +
+
+ +
+ Alex Morgan + +
+
+

Reached top 5 globally for the first time. Long road, worth every hour. 🏆

+ +
+
+
+ + +
+ +
+ + +
+ +
+
+ + + + + + diff --git a/scripts/profile.js b/scripts/profile.js new file mode 100644 index 0000000..d9c136c --- /dev/null +++ b/scripts/profile.js @@ -0,0 +1,22 @@ +// Profile page – tab switching +(function () { + 'use strict'; + + var tabs = document.querySelectorAll('.tab'); + var panels = document.querySelectorAll('.tab-content'); + + function activateTab(targetId) { + tabs.forEach(function (tab) { + tab.classList.toggle('active', tab.dataset.tab === targetId); + }); + panels.forEach(function (panel) { + panel.classList.toggle('active', panel.id === 'tab-' + targetId); + }); + } + + tabs.forEach(function (tab) { + tab.addEventListener('click', function () { + activateTab(tab.dataset.tab); + }); + }); +}()); diff --git a/styles/profile.css b/styles/profile.css new file mode 100644 index 0000000..6715fac --- /dev/null +++ b/styles/profile.css @@ -0,0 +1,338 @@ +/* ===================================================== + ProTop – User Profile Page Styles + ===================================================== */ + +/* ── Reset & Base ── */ +*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } + +:root { + --color-bg: #0f0f13; + --color-surface: #1a1a24; + --color-border: #2e2e3e; + --color-primary: #6366f1; + --color-primary-h: #4f52d8; + --color-text: #e2e2ee; + --color-muted: #8888aa; + --color-success: #22c55e; + --radius: 12px; + --transition: 0.2s ease; +} + +html { font-size: 16px; } + +body { + background: var(--color-bg); + color: var(--color-text); + font-family: 'Segoe UI', system-ui, -apple-system, sans-serif; + line-height: 1.6; + min-height: 100vh; + display: flex; + flex-direction: column; +} + +a { color: var(--color-primary); text-decoration: none; } +a:hover { text-decoration: underline; } + +/* ── Layout ── */ +.container { + width: 100%; + max-width: 900px; + margin-inline: auto; + padding-inline: 1.25rem; +} + +/* ── Header ── */ +.site-header { + background: var(--color-surface); + border-bottom: 1px solid var(--color-border); + position: sticky; + top: 0; + z-index: 100; +} + +.site-header .container { + display: flex; + align-items: center; + justify-content: space-between; + height: 60px; +} + +.logo { + font-size: 1.25rem; + font-weight: 700; + color: var(--color-primary); + letter-spacing: -0.02em; +} + +.site-nav { display: flex; gap: 1.5rem; } + +.site-nav a { + color: var(--color-muted); + font-size: 0.9rem; + font-weight: 500; + transition: color var(--transition); +} + +.site-nav a:hover, +.site-nav a.active { color: var(--color-text); text-decoration: none; } + +/* ── Main ── */ +main.container { flex: 1; padding-top: 2rem; padding-bottom: 3rem; } + +/* ── Profile Hero ── */ +.profile-hero { + display: flex; + align-items: flex-start; + gap: 1.5rem; + background: var(--color-surface); + border: 1px solid var(--color-border); + border-radius: var(--radius); + padding: 2rem; + flex-wrap: wrap; +} + +.avatar-wrapper { position: relative; flex-shrink: 0; } + +.avatar { + width: 100px; + height: 100px; + border-radius: 50%; + border: 3px solid var(--color-primary); + display: block; +} + +.status-badge { + position: absolute; + bottom: 4px; + right: 4px; + width: 16px; + height: 16px; + border-radius: 50%; + border: 2px solid var(--color-surface); +} + +.status-badge.online { background: var(--color-success); } +.status-badge.offline { background: var(--color-muted); } + +.profile-info { flex: 1; min-width: 220px; } + +.profile-name { font-size: 1.5rem; font-weight: 700; line-height: 1.2; } +.profile-handle { color: var(--color-muted); font-size: 0.95rem; margin-top: 0.15rem; } + +.profile-bio { + margin-top: 0.65rem; + color: var(--color-text); + font-size: 0.95rem; + max-width: 480px; +} + +.profile-meta { + display: flex; + flex-wrap: wrap; + gap: 0.75rem 1.5rem; + margin-top: 0.85rem; + font-size: 0.85rem; + color: var(--color-muted); +} + +.profile-meta a { color: var(--color-primary); } + +.profile-actions { + display: flex; + gap: 0.75rem; + align-items: flex-start; + flex-shrink: 0; +} + +/* ── Buttons ── */ +.btn { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0.5rem 1.25rem; + border-radius: 8px; + font-size: 0.9rem; + font-weight: 600; + cursor: pointer; + border: none; + transition: background var(--transition), color var(--transition); + white-space: nowrap; +} + +.btn-primary { + background: var(--color-primary); + color: #fff; +} + +.btn-primary:hover { background: var(--color-primary-h); } + +.btn-secondary { + background: transparent; + color: var(--color-text); + border: 1px solid var(--color-border); +} + +.btn-secondary:hover { background: var(--color-border); } + +/* ── Stats Bar ── */ +.stats-bar { + display: flex; + justify-content: space-around; + background: var(--color-surface); + border: 1px solid var(--color-border); + border-radius: var(--radius); + padding: 1.25rem 1rem; + margin-top: 1.25rem; + flex-wrap: wrap; + gap: 1rem; +} + +.stat { text-align: center; flex: 1 1 80px; } + +.stat-value { + display: block; + font-size: 1.4rem; + font-weight: 700; + color: var(--color-text); +} + +.stat-label { + display: block; + font-size: 0.78rem; + color: var(--color-muted); + text-transform: uppercase; + letter-spacing: 0.05em; + margin-top: 0.2rem; +} + +/* ── Tabs ── */ +.tabs { + display: flex; + gap: 0; + margin-top: 1.5rem; + border-bottom: 1px solid var(--color-border); +} + +.tab { + background: transparent; + border: none; + border-bottom: 3px solid transparent; + color: var(--color-muted); + cursor: pointer; + font-size: 0.9rem; + font-weight: 600; + padding: 0.65rem 1.25rem; + transition: color var(--transition), border-color var(--transition); + margin-bottom: -1px; +} + +.tab:hover { color: var(--color-text); } + +.tab.active { + color: var(--color-primary); + border-bottom-color: var(--color-primary); +} + +/* ── Tab Content ── */ +.tab-content { display: none; padding-top: 1.5rem; } +.tab-content.active { display: block; } + +/* ── Post Grid ── */ +.post-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); + gap: 1rem; +} + +.post-card { + background: var(--color-surface); + border: 1px solid var(--color-border); + border-radius: var(--radius); + padding: 1.25rem; + transition: border-color var(--transition); +} + +.post-card:hover { border-color: var(--color-primary); } + +.post-header { + display: flex; + align-items: center; + gap: 0.75rem; + margin-bottom: 0.75rem; +} + +.post-avatar { width: 36px; height: 36px; border-radius: 50%; } + +.post-header strong { display: block; font-size: 0.9rem; } +.post-header time { font-size: 0.78rem; color: var(--color-muted); } + +.post-card p { font-size: 0.92rem; color: var(--color-text); } + +.post-footer { + display: flex; + gap: 1rem; + margin-top: 0.75rem; + font-size: 0.82rem; + color: var(--color-muted); +} + +/* ── Achievements ── */ +.achievement-list { list-style: none; display: flex; flex-direction: column; gap: 0.85rem; } + +.achievement-item { + display: flex; + align-items: flex-start; + gap: 1rem; + background: var(--color-surface); + border: 1px solid var(--color-border); + border-radius: var(--radius); + padding: 1rem 1.25rem; +} + +.achievement-icon { font-size: 1.6rem; flex-shrink: 0; } + +.achievement-item strong { display: block; font-size: 0.95rem; } +.achievement-item p { font-size: 0.85rem; color: var(--color-muted); margin-top: 0.15rem; } + +/* ── Activity Feed ── */ +.activity-feed { + list-style: none; + display: flex; + flex-direction: column; + gap: 0; +} + +.activity-feed li { + padding: 0.85rem 0; + border-bottom: 1px solid var(--color-border); + font-size: 0.9rem; + color: var(--color-text); +} + +.activity-feed li:last-child { border-bottom: none; } + +.activity-time { + font-size: 0.78rem; + color: var(--color-muted); + margin-right: 0.5rem; +} + +/* ── Footer ── */ +.site-footer { + background: var(--color-surface); + border-top: 1px solid var(--color-border); + padding: 1rem 0; + text-align: center; + font-size: 0.82rem; + color: var(--color-muted); +} + +.site-footer a { color: var(--color-muted); } +.site-footer a:hover { color: var(--color-text); text-decoration: none; } + +/* ── Responsive ── */ +@media (max-width: 600px) { + .profile-hero { flex-direction: column; } + .profile-actions { width: 100%; } + .btn { flex: 1; } +}