Files
PinPoint/website/index.html
T
harineandClaude Sonnet 5 d7abc9fb4b Add project website (Goal 3: required deliverable)
Static one-page site covering the problem statement, features, scope,
team roster, and infra links, drawn from docs/proposal.md and
docs/design/product-design.md. Deployed via nginx on the team19 VM
at http://51.79.242.163:5002.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-17 18:42:00 +08:00

248 lines
11 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>PinPoint — Bowling Form Coaching</title>
<meta name="description" content="PinPoint (BowlEye) is an Android app that uses on-device pose detection to help bowlers correct their approach and delivery form.">
<style>
:root {
--bg: #f7f5f2;
--surface: #ffffff;
--ink: #1c1b1f;
--ink-soft: #55524f;
--accent: #c4392b;
--accent-ink: #ffffff;
--line: #e6e2db;
--pin-cream: #fbfaf7;
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--bg: #16151a;
--surface: #1f1e24;
--ink: #f3f1ee;
--ink-soft: #b8b4ad;
--accent: #e0574a;
--accent-ink: #16151a;
--line: #302e35;
--pin-cream: #232228;
}
}
:root[data-theme="dark"] {
--bg: #16151a;
--surface: #1f1e24;
--ink: #f3f1ee;
--ink-soft: #b8b4ad;
--accent: #e0574a;
--accent-ink: #16151a;
--line: #302e35;
--pin-cream: #232228;
}
* { box-sizing: border-box; }
body {
margin: 0;
background: var(--bg);
color: var(--ink);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
line-height: 1.55;
}
.wrap { max-width: 1040px; margin: 0 auto; padding-inline: 20px; }
header.site {
border-bottom: 1px solid var(--line);
padding-block: 18px;
}
header.site .wrap { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.brand { display: flex; align-items: center; gap: 10px; font-weight: 700; font-size: 1.15rem; letter-spacing: -0.01em; }
.brand .dot { width: 11px; height: 11px; border-radius: 50%; background: var(--accent); flex: none; }
nav.site a { color: var(--ink-soft); text-decoration: none; margin-left: 22px; font-size: 0.95rem; }
nav.site a:hover { color: var(--ink); }
.hero { padding-block: 72px 56px; }
.hero .kicker { color: var(--accent); font-weight: 700; font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 14px; }
.hero h1 { font-size: clamp(2.1rem, 5vw, 3.2rem); line-height: 1.08; margin: 0 0 18px; letter-spacing: -0.02em; }
.hero p.lead { color: var(--ink-soft); font-size: 1.15rem; max-width: 640px; margin: 0 0 28px; }
.cta-row { display: flex; gap: 12px; flex-wrap: wrap; }
.btn { display: inline-block; padding: 12px 22px; border-radius: 8px; font-weight: 600; font-size: 0.95rem; text-decoration: none; border: 1px solid transparent; }
.btn.primary { background: var(--accent); color: var(--accent-ink); }
.btn.ghost { border-color: var(--line); color: var(--ink); }
section { padding-block: 56px; border-top: 1px solid var(--line); }
section h2 { font-size: 1.7rem; margin: 0 0 8px; letter-spacing: -0.01em; }
section p.section-lead { color: var(--ink-soft); margin: 0 0 32px; max-width: 620px; }
.scope-grid { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 28px; margin-bottom: 8px; }
@media (max-width: 640px) { .scope-grid { grid-template-columns: 1fr; } }
.scope-grid h3 { font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-soft); margin: 0 0 12px; }
.scope-grid ul { margin: 0; padding-left: 1.1em; }
.scope-grid li { margin-bottom: 6px; }
.feature-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 20px; }
.feature-card { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 22px; }
.feature-card .icon { width: 34px; height: 34px; border-radius: 8px; background: var(--pin-cream); border: 1px solid var(--line); display: flex; align-items: center; justify-content: center; margin-bottom: 14px; font-size: 1.1rem; }
.feature-card h3 { font-size: 1.02rem; margin: 0 0 8px; }
.feature-card p { color: var(--ink-soft); font-size: 0.93rem; margin: 0; }
.team-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 16px; }
.member { background: var(--surface); border: 1px solid var(--line); border-radius: 10px; padding: 16px 18px; }
.member .name { font-weight: 600; margin-bottom: 2px; }
.member .role { color: var(--accent); font-size: 0.85rem; font-weight: 600; }
.status-row { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 20px; }
.status-pill { display: flex; align-items: center; gap: 8px; background: var(--surface); border: 1px solid var(--line); border-radius: 999px; padding: 8px 16px; font-size: 0.88rem; text-decoration: none; color: var(--ink); }
.status-pill .led { width: 8px; height: 8px; border-radius: 50%; background: #3aa65a; flex: none; }
footer.site { border-top: 1px solid var(--line); padding-block: 28px; color: var(--ink-soft); font-size: 0.85rem; }
footer.site .wrap { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 10px; }
footer.site a { color: var(--ink-soft); }
code.inline { background: var(--pin-cream); border: 1px solid var(--line); border-radius: 5px; padding: 1px 6px; font-size: 0.85em; }
</style>
</head>
<body>
<header class="site">
<div class="wrap">
<div class="brand"><span class="dot"></span> PinPoint</div>
<nav class="site">
<a href="#features">Features</a>
<a href="#scope">Scope</a>
<a href="#team">Team</a>
<a href="#status">Status</a>
</nav>
</div>
</header>
<section class="hero">
<div class="wrap">
<div class="kicker">DigiPen FullStack · Team 19</div>
<h1>Fix your bowling form before your next frame.</h1>
<p class="lead">
PinPoint (working codename <code class="inline">BowlEye</code>) is an Android app that watches your
approach through your phone's camera, tracks your body in real time with on-device pose detection,
and shows you exactly where your steps, timing, and joint angles go wrong — no coach required.
</p>
<div class="cta-row">
<a class="btn primary" href="#features">See what it does</a>
<a class="btn ghost" href="http://51.79.242.163:5000/unplayable01/PinPoint" target="_blank" rel="noopener">View source</a>
</div>
</div>
</section>
<section id="problem">
<div class="wrap">
<h2>The problem</h2>
<p class="section-lead">
Most bowlers improve by trial and error, or by paying for a coach's eye. PinPoint gives anyone who can
bowl a way to see their own mistakes — where their feet land, how their hips and ankles move at release,
and how that compares to correct form — using nothing but a phone propped up at the lane.
</p>
</div>
</section>
<section id="features">
<div class="wrap">
<h2>What it does</h2>
<p class="section-lead">Built around live pose tracking during a real approach, not a recorded lesson.</p>
<div class="feature-grid">
<div class="feature-card">
<div class="icon">📹</div>
<h3>Live camera capture</h3>
<p>Front or back camera, portrait or landscape, switchable mid-session via CameraX.</p>
</div>
<div class="feature-card">
<div class="icon">🦴</div>
<h3>Real-time pose overlay</h3>
<p>A skeleton drawn live over the camera preview from on-device ML Kit landmark detection.</p>
</div>
<div class="feature-card">
<div class="icon">👣</div>
<h3>Step &amp; phase detection</h3>
<p>Counts steps through the approach and segments it into stance, approach, and release phases.</p>
</div>
<div class="feature-card">
<div class="icon">📐</div>
<h3>Joint angle analysis</h3>
<p>Computes ankle and hip angles at the key moments that matter for a clean release.</p>
</div>
<div class="feature-card">
<div class="icon">🎯</div>
<h3>Mistake &amp; correction feedback</h3>
<p>Surfaces what went wrong and how to fix it — with the ideal form shown for comparison.</p>
</div>
<div class="feature-card">
<div class="icon">🔊</div>
<h3>Spoken instructions</h3>
<p>Hear correction cues, not just read them, so you can keep your eyes on the lane.</p>
</div>
</div>
</div>
</section>
<section id="scope">
<div class="wrap">
<h2>Who it's for, and today's scope</h2>
<p class="section-lead">
Anyone who can bowl. This version focuses on getting the core coaching loop right before broadening it.
</p>
<div class="scope-grid">
<div>
<h3>In scope</h3>
<ul>
<li>Five-step bowling approaches</li>
<li>Right-handed bowlers</li>
<li>Starting position and finishing position correction</li>
</ul>
</div>
<div>
<h3>Not yet</h3>
<ul>
<li>Left-handed / non-five-step approaches</li>
<li>Cloud sync across devices</li>
<li>Automated scoring against a reference model</li>
<li>iOS support</li>
</ul>
</div>
</div>
</div>
</section>
<section id="team">
<div class="wrap">
<h2>Team</h2>
<p class="section-lead">DigiPen Institute of Technology — FullStack, Team 19.</p>
<div class="team-grid">
<div class="member"><div class="name">Lu Yong Wei</div><div class="role">Product Owner</div></div>
<div class="member"><div class="name">Gabriel Low</div><div class="role">Programmer / Version Control</div></div>
<div class="member"><div class="name">Harine S/O Sumen</div><div class="role">Tech Lead</div></div>
<div class="member"><div class="name">Liu Jingwen</div><div class="role">Programmer / Serialization</div></div>
<div class="member"><div class="name">Auvik Kumar Biswas</div><div class="role">Programmer / Feedback</div></div>
<div class="member"><div class="name">Chan Qi Ying</div><div class="role">Programmer / UI Lead</div></div>
<div class="member"><div class="name">Low Yu Sheng Javier</div><div class="role">Product Manager</div></div>
<div class="member"><div class="name">Khalil Belabadia</div><div class="role">Programmer / Audio Lead</div></div>
</div>
</div>
</section>
<section id="status">
<div class="wrap">
<h2>Project infrastructure</h2>
<p class="section-lead">Self-hosted on the team's own VM, per the course's FullStack infrastructure track.</p>
<div class="status-row">
<a class="status-pill" href="http://51.79.242.163:5000/unplayable01/PinPoint" target="_blank" rel="noopener"><span class="led"></span> Gitea repository</a>
<a class="status-pill" href="http://51.79.242.163:5001/job/PinPoint-CI/" target="_blank" rel="noopener"><span class="led"></span> Jenkins CI</a>
<a class="status-pill" href="https://github.com/DefiantWanderer/PinPoint" target="_blank" rel="noopener"><span class="led"></span> GitHub mirror</a>
</div>
</div>
</section>
<footer class="site">
<div class="wrap">
<div>PinPoint / BowlEye — DigiPen FullStack, Team 19.</div>
<div><a href="http://51.79.242.163:5000/unplayable01/PinPoint" target="_blank" rel="noopener">Source</a></div>
</div>
</footer>
</body>
</html>