// motion.jsx — Motion PController sub-page

function Motion() {
  return (
    <Page>
      <section className="detail" data-screen-label="Motion PController · Detail">
        <a className="back reveal" href="#/" onClick={(e) => { e.preventDefault(); navigate('/'); }}>
          <span className="arr">←</span> Back to index
        </a>

        <p className="detail-kicker reveal">
          <span className="dot" />
          <span>Project 02</span>
          <span style={{ color: 'var(--rule)' }}>/</span>
          <span>iOS · PC server · Motion input</span>
          <span style={{ color: 'var(--rule)' }}>/</span>
          <span>2025 —</span>
        </p>

        <h1 className="detail-title reveal">
          Motion <em>P</em>Controller<em>.</em>
        </h1>
        <p className="detail-tag reveal">
          Your phone, tilted and twisted like a real bike throttle, piped straight into a desktop game. Built around <em>MotoGP&nbsp;Ride</em> — because a keyboard is a terrible way to corner.
        </p>

        <dl className="detail-facts reveal">
          <div className="fact"><dt>Game</dt><dd>MotoGP Ride</dd></div>
          <div className="fact"><dt>Sensors</dt><dd>Accel. + gyroscope</dd></div>
          <div className="fact"><dt>Link</dt><dd>PC server over Wi-Fi</dd></div>
          <div className="fact"><dt>Latency</dt><dd>~9&nbsp;ms end-to-end</dd></div>
        </dl>

        <div className="detail-body reveal">
          <h3>Concept</h3>
          <div className="body-copy">
            <p>
              A motorcycle game deserves a motorcycle input. Motion PController runs a lightweight server on the desktop; the phone, held like a grip in your right hand, streams its IMU — accelerometer for throttle roll, gyroscope for lean. The server translates that into keystrokes, gamepad axes, or vJoy events, whichever the game likes.
            </p>
            <p>
              The first target was <em>MotoGP Ride</em>, and the mapping is deliberately physical: twist to accelerate, tilt to lean, short forward jerk to brake. It feels more like riding than any controller I own, which is probably the highest praise a firmware engineer can hand out.
            </p>
          </div>
        </div>

        <div className="shot-wrap reveal">
          <div className="shot" style={{ gridColumn: 'span 6' }}>
            <span className="shot-label">01 · Phone grip</span>
            <div className="shot-inner">
              [ screenshot ]<br/>
              iOS throttle HUD<br/>
              lean angle · RPM bar
            </div>
            <div className="shot-caption">Held right-handed, twisted like a throttle.</div>
          </div>
          <div className="shot" style={{ gridColumn: 'span 6' }}>
            <span className="shot-label">02 · Desktop server</span>
            <div className="shot-inner">
              [ screenshot ]<br/>
              PC console:<br/>
              pairing code · latency · axis map
            </div>
            <div className="shot-caption">Runs on Windows / macOS, 3 MB binary.</div>
          </div>
        </div>

        <div className="detail-body reveal">
          <h3>Signal path</h3>
          <div className="body-copy">
            <p>
              Phone samples CoreMotion at 100&nbsp;Hz → a tiny Kalman filter smooths the high-frequency noise → axes are packed into 8-byte UDP frames → desktop server unpacks, rescales, and emits vJoy / XInput events. The whole path, door-to-door, clocks in at about 9&nbsp;ms over local Wi-Fi.
            </p>
            <p>
              Mapping is user-defined: you can trade yaw for throttle if you prefer a steering-wheel grip, or reserve a magnetic gesture (slap the phone down) as an emergency &ldquo;close throttle&rdquo;. The defaults mimic a real bike grip because that&rsquo;s the point.
            </p>
          </div>
        </div>

        <ul className="feature-list reveal" style={{ listStyle: 'none', margin: 0, padding: 0 }}>
          <li className="feature">
            <span className="idx">01</span>
            <div>
              <h4>Twist-to-throttle</h4>
              <p>Gyroscope roll around the long axis of the phone drives the throttle axis, 0–100%.</p>
            </div>
          </li>
          <li className="feature">
            <span className="idx">02</span>
            <div>
              <h4>Lean-to-steer</h4>
              <p>Phone pitch maps to the bike&rsquo;s lean. A small dead-zone keeps hand tremors from wobbling you.</p>
            </div>
          </li>
          <li className="feature">
            <span className="idx">03</span>
            <div>
              <h4>Gesture brake</h4>
              <p>A short forward jerk — detected via linear accel spike — triggers front brake. Surprisingly natural.</p>
            </div>
          </li>
          <li className="feature">
            <span className="idx">04</span>
            <div>
              <h4>Bring-your-own-mapping</h4>
              <p>Remap axes to vJoy, XInput, or keyboard. Profiles are saved per-game.</p>
            </div>
          </li>
        </ul>

        <div className="detail-body reveal">
          <h3>Status</h3>
          <div className="body-copy">
            <p>
              Private v0.3 — I&rsquo;m riding it most evenings. Next up: haptic feedback driven by the game&rsquo;s telemetry (it reads rumble events and plays them back on the phone&rsquo;s motor), and an Android port once the CoreMotion-side is fully cleaned up.
            </p>
          </div>
        </div>

        <nav className="pager reveal">
          <a href="#/zic-hat" onClick={(e) => { e.preventDefault(); navigate('/zic-hat'); }}>
            <small>Previous project</small>
            ← Zic Hat
          </a>
          <a href="#/" onClick={(e) => { e.preventDefault(); navigate('/'); }}>
            <small>Back</small>
            Index <em style={{ fontStyle: 'italic', color: 'var(--muted)' }}>↺</em>
          </a>
        </nav>
      </section>
    </Page>
  );
}

window.Motion = Motion;
