<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Gamepad to Keyboard — Free Controller-to-Keyboard Mapper for Windows</title>
<meta name="description" content="Free Windows app to map any game controller button to keyboard keys or mouse clicks. Remap your gamepad to keyboard, play keyboard-only games with a controller — a lightweight free reWASD alternative.">
<link rel="canonical" href="https://gamepadtokeyboard.com/">
<meta name="theme-color" content="#0B1019">
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='8' fill='%230E1420'/%3E%3Crect x='4' y='9' width='24' height='15' rx='6.5' fill='none' stroke='%238A8FFF' stroke-width='2'/%3E%3Cpath d='M11 13v5M8.5 15.5h5' stroke='%238A8FFF' stroke-width='2' stroke-linecap='round'/%3E%3Ccircle cx='21' cy='14.5' r='1.6' fill='%2334D399'/%3E%3Ccircle cx='24' cy='18' r='1.6' fill='%238A8FFF'/%3E%3C/svg%3E">
<link rel="preload" as="image" href="/assets/poster.jpg">
<link rel="preload" as="font" type="font/woff2" href="/fonts/syne-800.woff2" crossorigin>
<meta property="og:type" content="website">
<meta property="og:site_name" content="Gamepad to Keyboard">
<meta property="og:url" content="https://gamepadtokeyboard.com/">
<meta property="og:title" content="Gamepad to Keyboard — Free Controller-to-Keyboard Mapper">
<meta property="og:description" content="Free Windows app to map any game controller button to keyboard keys or mouse clicks. Remap your gamepad to keyboard, play keyboard-only games with a controller — a lightweight free reWASD alternative.">
<meta property="og:image" content="https://gamepadtokeyboard.com/og.jpg">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Gamepad to Keyboard — Free Controller-to-Keyboard Mapper">
<meta name="twitter:description" content="Free Windows app to map any game controller button to keyboard keys or mouse clicks. Remap your gamepad to keyboard, play keyboard-only games with a controller — a lightweight free reWASD alternative.">
<meta name="twitter:image" content="https://gamepadtokeyboard.com/og.jpg">
<style>html,body{margin:0;background:#0B1019}</style>
</head>
<body>
<style>
  /* fonts (external, font-display:swap) */
@font-face{font-family:'Syne';font-style:normal;font-weight:700;font-display:swap;src:url(/fonts/syne-700.woff2) format('woff2')}
@font-face{font-family:'Syne';font-style:normal;font-weight:800;font-display:swap;src:url(/fonts/syne-800.woff2) format('woff2')}
@font-face{font-family:'Sora';font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/sora-400.woff2) format('woff2')}
@font-face{font-family:'Sora';font-style:normal;font-weight:600;font-display:swap;src:url(/fonts/sora-600.woff2) format('woff2')}
  /* embedded display+body fonts (Syne / Sora) */

  :root{
    --bg:#0B1019;
    --bg-2:#0E1420;
    --panel:#131A28;
    --panel-2:#161E30;
    --line:rgba(124,131,255,.14);
    --line-strong:rgba(124,131,255,.28);
    --ink:#E9EDF7;
    --body:#A6B0C6;
    --muted:#6B7488;
    --indigo:#7C83FF;
    --indigo-2:#8A8FFF;
    --emerald:#34D399;
    --emerald-dim:#1f8f6b;
    --display:"Syne","SF Pro Display","Segoe UI",system-ui,-apple-system,sans-serif;
    --text:"Sora",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
    --mono:"SF Mono","JetBrains Mono","Cascadia Code",ui-monospace,Menlo,Consolas,monospace;
    --maxw:1120px;
    --r:16px;
    --r-lg:22px;
  }

  *{box-sizing:border-box}
  html{scroll-behavior:smooth}
  @media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

  body,.gk-root{margin:0}
  .gk-root{
    background:
      radial-gradient(1200px 700px at 78% -8%, rgba(124,131,255,.16), transparent 60%),
      radial-gradient(900px 620px at 8% 6%, rgba(52,211,153,.08), transparent 58%),
      linear-gradient(180deg,var(--bg-2),var(--bg) 32%,var(--bg));
    color:var(--body);
    font-family:var(--text);
    font-size:17.5px;
    line-height:1.62;
    -webkit-font-smoothing:antialiased;
    text-rendering:optimizeLegibility;
    overflow-x:hidden;
    position:relative;
  }
  .gk-root::before{
    content:"";position:fixed;inset:0;pointer-events:none;z-index:0;
    background-image:
      linear-gradient(rgba(124,131,255,.035) 1px,transparent 1px),
      linear-gradient(90deg,rgba(124,131,255,.035) 1px,transparent 1px);
    background-size:64px 64px;
    -webkit-mask-image:radial-gradient(1100px 700px at 50% 0%,#000 0%,transparent 72%);
            mask-image:radial-gradient(1100px 700px at 50% 0%,#000 0%,transparent 72%);
  }
  .gk-root > *{position:relative;z-index:1}

  .wrap{width:100%;max-width:var(--maxw);margin:0 auto;padding:0 24px}

  a{color:inherit;text-decoration:none}
  img{max-width:100%;display:block}
  ::selection{background:rgba(124,131,255,.32);color:#fff}

  :focus-visible{outline:2px solid var(--indigo-2);outline-offset:3px;border-radius:6px}

  h1,h2,h3{font-family:var(--display);color:var(--ink);margin:0;font-weight:800;letter-spacing:-.02em;text-wrap:balance}
  .tnum{font-variant-numeric:tabular-nums}

  /* ---------- NAV ---------- */
  .nav{
    position:sticky;top:0;z-index:40;
    backdrop-filter:blur(14px) saturate(140%);
    -webkit-backdrop-filter:blur(14px) saturate(140%);
    background:linear-gradient(180deg,rgba(11,16,25,.82),rgba(11,16,25,.5));
    border-bottom:1px solid var(--line);
  }
  .nav-in{display:flex;align-items:center;justify-content:space-between;height:66px}
  .brand{display:flex;align-items:center;gap:11px;font-family:var(--display);font-weight:800;color:var(--ink);letter-spacing:-.02em;font-size:16px}
  .brand .mark{width:30px;height:30px;border-radius:9px;flex:0 0 auto;
    background:linear-gradient(145deg,#232c46,#0f1626);
    border:1px solid var(--line-strong);
    display:grid;place-items:center;box-shadow:0 0 0 1px rgba(0,0,0,.4) inset,0 6px 18px rgba(124,131,255,.22)}
  .nav-links{display:flex;align-items:center;gap:28px}
  .nav-links a.navlink{color:var(--body);font-size:14.5px;font-weight:500}
  .nav-links a.navlink:hover{color:var(--ink)}
  .nav-cta{display:inline-flex;align-items:center;gap:8px;font-weight:650;font-size:14px;color:#0b1019;
    background:linear-gradient(180deg,var(--indigo-2),var(--indigo));
    padding:9px 16px;border-radius:11px;box-shadow:0 6px 20px rgba(124,131,255,.32)}
  .nav-cta:hover{filter:brightness(1.06)}
  @media (max-width:760px){.nav-links .navlink{display:none}}

  /* ---------- BUTTONS ---------- */
  .btn{display:inline-flex;align-items:center;gap:12px;font-family:var(--display);font-weight:700;letter-spacing:-.01em;
    border-radius:15px;padding:18px 30px;font-size:18px;cursor:pointer;border:1px solid transparent;transition:transform .15s ease,filter .15s ease,box-shadow .15s ease}
  .btn:active{transform:translateY(1px)}
  .btn-primary{color:#0a0e18;background:linear-gradient(180deg,var(--indigo-2),var(--indigo));
    box-shadow:0 10px 34px -6px rgba(124,131,255,.55),0 0 0 1px rgba(146,152,255,.4) inset}
  .btn-primary:hover{filter:brightness(1.07);box-shadow:0 16px 46px -8px rgba(124,131,255,.7),0 0 0 1px rgba(146,152,255,.5) inset}
  /* attention "download me" pulse on the primary CTA */
  @keyframes dlpulse{
    0%,100%{box-shadow:0 12px 36px -6px rgba(124,131,255,.55),0 0 0 1px rgba(146,152,255,.45) inset,0 0 0 0 rgba(124,131,255,.5)}
    50%{box-shadow:0 18px 54px -6px rgba(124,131,255,.92),0 0 0 1px rgba(146,152,255,.6) inset,0 0 0 13px rgba(124,131,255,0)}
  }
  .btn-primary{animation:dlpulse 1.8s ease-in-out infinite}
  .btn-primary:hover{animation-play-state:paused}
  /* make Download noticeably bigger than the secondary button */
  .hero-actions .btn-primary,.band .btn-primary{padding:24px 46px;font-size:22px;font-weight:800}
  .hero-actions .btn-primary svg,.band .btn-primary svg{width:26px;height:26px}
  .btn-ghost{color:var(--ink);background:rgba(148,160,190,.05);border-color:var(--line-strong)}
  .btn-ghost:hover{border-color:var(--indigo);background:rgba(124,131,255,.09)}
  .btn svg{width:22px;height:22px}
  /* extra-large hero + band call-to-action buttons */
  .hero-actions .btn{padding:21px 38px;font-size:20px;border-radius:16px}
  .hero-actions .btn svg{width:24px;height:24px}
  /* GitHub + SourceForge ghost buttons: identical size, centered */
  .hero-actions .btn-ghost{min-width:262px;justify-content:center}
  @media (max-width:520px){.hero-actions{gap:12px}.hero-actions .btn{width:100%;min-width:0;justify-content:center;padding:19px 26px;font-size:18px}}

  /* ---------- HERO ---------- */
  .hero{position:relative;min-height:100svh;display:flex;align-items:center;padding:118px 0 80px;overflow:hidden}
  .hero-canvas{position:absolute;inset:0;width:100%;height:100%;z-index:0;display:block;opacity:.4}
  /* generated Grok video — FIXED full-page background, seamless loop, stays behind everything always */
  .bg-video{position:fixed;inset:0;width:100%;height:100%;object-fit:cover;z-index:0;opacity:.72;pointer-events:none}
  .bg-veil{position:fixed;inset:0;z-index:0;pointer-events:none;
    background:linear-gradient(180deg,rgba(11,16,25,.44),rgba(11,16,25,.5) 55%,rgba(11,16,25,.62))}
  .hero-veil{position:absolute;inset:0;z-index:1;pointer-events:none;
    background:linear-gradient(90deg,rgba(11,16,25,.5),rgba(11,16,25,.18) 55%,transparent),
      linear-gradient(180deg,rgba(11,16,25,.28),transparent 42%,rgba(11,16,25,.55))}
  .aurora{position:absolute;z-index:0;border-radius:50%;filter:blur(70px);opacity:.6;will-change:transform;pointer-events:none}
  .aurora.a1{width:620px;height:620px;top:-180px;right:-120px;background:radial-gradient(circle at 40% 40%,rgba(124,131,255,.55),transparent 62%)}
  .aurora.a2{width:520px;height:520px;bottom:-220px;left:-140px;background:radial-gradient(circle at 50% 50%,rgba(52,211,153,.28),transparent 62%)}
  .aurora.a3{width:400px;height:400px;top:24%;left:44%;background:radial-gradient(circle at 50% 50%,rgba(138,143,255,.3),transparent 60%);opacity:.4}
  .hero-fade{position:absolute;left:0;right:0;bottom:0;height:180px;z-index:1;background:linear-gradient(180deg,transparent,var(--bg));pointer-events:none}

  .hero-in{position:relative;z-index:2;width:100%}
  .eyebrow{display:inline-flex;align-items:center;gap:9px;font-family:var(--mono);font-size:12.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--indigo-2);
    background:rgba(124,131,255,.09);border:1px solid var(--line-strong);padding:7px 13px;border-radius:100px}
  .eyebrow .dot{width:7px;height:7px;border-radius:50%;background:var(--emerald);box-shadow:0 0 10px var(--emerald)}
  .hero h1{font-size:clamp(3.2rem,8vw,6.4rem);line-height:.94;font-weight:850;letter-spacing:-.038em;margin:28px 0 0;max-width:15ch}
  .hero h1 .grad{background:linear-gradient(105deg,var(--indigo-2) 6%,#c9cdff 40%,var(--emerald) 108%);-webkit-background-clip:text;background-clip:text;color:transparent}
  .hero .sub{margin:22px 0 0;font-size:clamp(1.05rem,1.8vw,1.28rem);color:var(--body);max-width:60ch;line-height:1.55}
  .hero-actions{display:flex;flex-wrap:wrap;gap:14px;margin-top:34px}
  .hero-meta{display:flex;flex-wrap:wrap;gap:22px;margin-top:30px;color:var(--muted);font-size:14px}
  .hero-meta b{color:var(--ink);font-weight:700}
  .hero-meta .mi{display:flex;align-items:center;gap:9px}
  .hero-meta svg{width:17px;height:17px;color:var(--emerald)}

  /* onload reveal */
  .rise{opacity:0;transform:translateY(22px)}
  .loaded .rise{animation:rise .9s cubic-bezier(.16,.84,.34,1) forwards}
  .loaded .rise.d1{animation-delay:.06s}
  .loaded .rise.d2{animation-delay:.16s}
  .loaded .rise.d3{animation-delay:.28s}
  .loaded .rise.d4{animation-delay:.4s}
  .loaded .rise.d5{animation-delay:.52s}
  @keyframes rise{to{opacity:1;transform:none}}

  /* scroll reveal */
  .reveal{opacity:0;transform:translateY(26px);transition:opacity .7s ease,transform .7s cubic-bezier(.16,.84,.34,1)}
  .reveal.in{opacity:1;transform:none}

  /* ---------- SECTION SHELL ---------- */
  .section{padding:96px 0}
  .kicker{font-family:var(--mono);font-size:12.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--emerald);margin:0 0 14px}
  .section h2{font-size:clamp(1.9rem,3.6vw,2.9rem);line-height:1.04;letter-spacing:-.03em;max-width:20ch}
  .lead{margin:16px 0 0;font-size:1.08rem;max-width:62ch;color:var(--body)}

  /* ---------- SCREENSHOT ---------- */
  .shot-wrap{margin-top:8px;position:relative;display:flex;justify-content:center}
  .shot-halo{position:absolute;inset:-6% 4% 8%;z-index:0;border-radius:40px;
    background:radial-gradient(60% 60% at 50% 42%,rgba(124,131,255,.4),transparent 70%);
    filter:blur(60px)}
  .frame{position:relative;z-index:1;width:100%;max-width:960px;border-radius:var(--r-lg);
    background:linear-gradient(180deg,#1a2237,#121a2a);
    border:1px solid var(--line-strong);
    box-shadow:0 40px 120px -30px rgba(3,6,14,.9),0 0 0 1px rgba(255,255,255,.02) inset,0 0 60px -12px rgba(124,131,255,.4);
    overflow:hidden}
  .frame:hover{box-shadow:0 46px 130px -28px rgba(3,6,14,.95),0 0 80px -8px rgba(124,131,255,.5)}
  .titlebar{display:flex;align-items:center;gap:14px;height:44px;padding:0 16px;border-bottom:1px solid var(--line);
    background:linear-gradient(180deg,rgba(255,255,255,.03),transparent)}
  .tdots{display:flex;gap:8px}
  .tdots i{width:11px;height:11px;border-radius:50%;display:block}
  .tdots i:nth-child(1){background:#ff5f57}
  .tdots i:nth-child(2){background:#febc2e}
  .tdots i:nth-child(3){background:#28c840}
  .tbtitle{font-family:var(--mono);font-size:12.5px;color:var(--muted);letter-spacing:.02em}
  .tbtitle b{color:var(--body);font-weight:600}
  .frame img{width:100%;height:auto;display:block;background:#0c111c}
  .shot-tags{display:flex;flex-wrap:wrap;gap:10px;justify-content:center;margin-top:26px}
  .tag{font-size:13px;color:var(--body);border:1px solid var(--line);background:rgba(148,160,190,.04);padding:7px 13px;border-radius:100px}
  .tag b{color:var(--emerald);font-weight:650}

  /* ---------- FEATURES ---------- */
  .feat-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;margin-top:52px}
  @media (max-width:900px){.feat-grid{grid-template-columns:repeat(2,1fr)}}
  @media (max-width:600px){.feat-grid{grid-template-columns:1fr}}
  .card{background:linear-gradient(180deg,var(--panel-2),var(--panel));border:1px solid var(--line);border-radius:var(--r);padding:24px;position:relative;overflow:hidden;transition:border-color .25s ease,transform .25s ease}
  .card:hover{border-color:var(--line-strong);transform:translateY(-3px)}
  .card::after{content:"";position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,rgba(124,131,255,.5),transparent);opacity:0;transition:opacity .25s}
  .card:hover::after{opacity:1}
  .ic{width:44px;height:44px;border-radius:12px;display:grid;place-items:center;margin-bottom:16px;
    background:radial-gradient(120% 120% at 30% 20%,rgba(124,131,255,.22),rgba(124,131,255,.05));
    border:1px solid var(--line-strong)}
  .ic svg{width:23px;height:23px;color:var(--indigo-2)}
  .card.em .ic{background:radial-gradient(120% 120% at 30% 20%,rgba(52,211,153,.22),rgba(52,211,153,.05));border-color:rgba(52,211,153,.3)}
  .card.em .ic svg{color:var(--emerald)}
  .card h3{font-size:1.1rem;letter-spacing:-.01em;margin-bottom:8px;font-weight:700}
  .card p{margin:0;font-size:.97rem;color:var(--body);line-height:1.55}

  /* ---------- CONTROLLERS ---------- */
  .pads-scroll{margin-top:46px;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:thin;scrollbar-color:var(--line-strong) transparent;padding-bottom:6px}
  .pads{display:grid;grid-template-columns:repeat(4,minmax(210px,1fr));gap:16px;min-width:min(100%,900px)}
  .pad{background:linear-gradient(180deg,var(--panel-2),var(--panel));border:1px solid var(--line);border-radius:var(--r);padding:26px 22px;text-align:left}
  .pad .padic{width:52px;height:52px;color:var(--indigo-2);margin-bottom:18px}
  .pad h3{font-size:1.06rem;margin-bottom:6px}
  .pad p{margin:0;font-size:.92rem;color:var(--muted)}
  .pad .ok{margin-top:16px;display:inline-flex;align-items:center;gap:7px;font-size:12.5px;color:var(--emerald);font-family:var(--mono);letter-spacing:.04em}
  .pad .ok svg{width:14px;height:14px}
  .pads-note{margin-top:18px;font-size:.93rem;color:var(--muted)}

  /* ---------- HOW ---------- */
  .steps{display:grid;grid-template-columns:repeat(4,1fr);gap:18px;margin-top:52px;counter-reset:st}
  @media (max-width:900px){.steps{grid-template-columns:repeat(2,1fr)}}
  @media (max-width:520px){.steps{grid-template-columns:1fr}}
  .step{position:relative;padding:26px 22px 24px;border:1px solid var(--line);border-radius:var(--r);background:linear-gradient(180deg,var(--panel-2),var(--panel))}
  .step .n{font-family:var(--display);font-weight:850;font-size:2.4rem;letter-spacing:-.04em;line-height:1;
    background:linear-gradient(160deg,var(--indigo-2),rgba(124,131,255,.25));-webkit-background-clip:text;background-clip:text;color:transparent}
  .step h3{font-size:1.08rem;margin:14px 0 8px;font-weight:700}
  .step p{margin:0;font-size:.96rem;color:var(--body)}
  .step .key{display:inline-block;font-family:var(--mono);font-size:12px;color:var(--emerald);border:1px solid rgba(52,211,153,.3);
    background:rgba(52,211,153,.07);border-radius:7px;padding:2px 8px;margin-top:2px}

  /* ---------- REVIEWS ---------- */
  .rev-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;margin-top:52px}
  @media (max-width:940px){.rev-grid{grid-template-columns:repeat(2,1fr)}}
  @media (max-width:600px){.rev-grid{grid-template-columns:1fr}}
  .rev{background:linear-gradient(180deg,var(--panel-2),var(--panel));border:1px solid var(--line);border-radius:var(--r);padding:24px;display:flex;flex-direction:column;gap:14px}
  .stars{display:flex;gap:3px;color:var(--emerald)}
  .stars svg{width:16px;height:16px}
  .rev p{margin:0;color:var(--ink);font-size:1rem;line-height:1.55;flex:1}
  .rev .who{display:flex;align-items:center;gap:12px}
  .av{width:38px;height:38px;border-radius:10px;flex:0 0 auto;display:grid;place-items:center;font-family:var(--display);font-weight:800;color:#0b1019;font-size:15px}
  .rev .nm{font-weight:650;color:var(--ink);font-size:.95rem;line-height:1.2}
  .rev .hd{font-size:.82rem;color:var(--muted);font-family:var(--mono)}
  .rating-strip{display:flex;flex-wrap:wrap;align-items:center;gap:22px;margin-top:12px;color:var(--muted);font-size:14px}
  .rating-strip .big{font-family:var(--display);font-weight:850;font-size:1.7rem;color:var(--ink);letter-spacing:-.02em}

  /* ---------- DOWNLOAD BAND ---------- */
  .band{position:relative;overflow:hidden;border:1px solid var(--line-strong);border-radius:var(--r-lg);
    background:radial-gradient(120% 160% at 82% 0%,rgba(124,131,255,.28),transparent 55%),linear-gradient(180deg,var(--panel-2),#0f1626);
    padding:56px 44px;text-align:center}
  .band::before{content:"";position:absolute;inset:0;z-index:0;
    background:radial-gradient(50% 80% at 12% 100%,rgba(52,211,153,.16),transparent 60%)}
  .band > *{position:relative;z-index:1}
  .band h2{font-size:clamp(1.8rem,3.6vw,2.7rem);letter-spacing:-.03em;margin:0 auto;max-width:20ch}
  .band p{margin:16px auto 0;max-width:52ch;color:var(--body)}
  .band .hero-actions{justify-content:center}
  .band .reassure{margin-top:20px;font-size:13.5px;color:var(--muted);font-family:var(--mono);letter-spacing:.03em}

  /* ---------- FAQ ---------- */
  .faq{margin-top:48px;border-top:1px solid var(--line)}
  details.q{border-bottom:1px solid var(--line)}
  details.q summary{list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:20px;
    padding:24px 4px;font-family:var(--display);font-weight:650;color:var(--ink);font-size:1.12rem;letter-spacing:-.01em}
  details.q summary::-webkit-details-marker{display:none}
  details.q .pm{width:26px;height:26px;flex:0 0 auto;border:1px solid var(--line-strong);border-radius:8px;position:relative;transition:background .2s,border-color .2s}
  details.q .pm::before,details.q .pm::after{content:"";position:absolute;background:var(--indigo-2);border-radius:2px;top:50%;left:50%;transform:translate(-50%,-50%);transition:transform .25s ease,opacity .25s}
  details.q .pm::before{width:11px;height:2px}
  details.q .pm::after{width:2px;height:11px}
  details.q[open] .pm{background:rgba(124,131,255,.12);border-color:var(--indigo)}
  details.q[open] .pm::after{transform:translate(-50%,-50%) rotate(90deg);opacity:0}
  details.q .ans{padding:0 4px 26px;color:var(--body);font-size:1rem;line-height:1.62;max-width:74ch}
  details.q .ans a{color:var(--indigo-2);text-decoration:underline;text-underline-offset:3px}

  /* ---------- FOOTER ---------- */
  .foot{border-top:1px solid var(--line);padding:56px 0 46px;margin-top:20px}
  .foot-top{display:flex;flex-wrap:wrap;justify-content:space-between;gap:26px;align-items:flex-start}
  .foot .brand{font-size:17px}
  .foot .tagline{margin-top:14px;color:var(--muted);font-size:.95rem;max-width:52ch;line-height:1.55}
  .foot-links{display:flex;gap:26px;flex-wrap:wrap}
  .foot-links a{color:var(--body);font-size:14.5px}
  .foot-links a:hover{color:var(--ink)}
  .foot-bottom{display:flex;flex-wrap:wrap;justify-content:space-between;gap:14px;align-items:center;margin-top:40px;padding-top:24px;border-top:1px solid var(--line);color:var(--muted);font-size:13.5px}
  .foot-bottom .lic{font-family:var(--mono);letter-spacing:.03em;color:var(--body)}

  @media (prefers-reduced-motion:reduce){
    .rise,.reveal{opacity:1 !important;transform:none !important;animation:none !important;transition:none !important}
    .aurora{animation:none !important}
    .btn-primary{animation:none !important}
    .bg-video{display:none}
    .card:hover,.frame:hover{transform:none}
  }
</style>

<div class="gk-root">

  <video class="bg-video" autoplay muted loop playsinline preload="auto" aria-hidden="true" poster="/assets/poster.jpg"><source src="/assets/bg.mp4" type="video/mp4"></video>
  <div class="bg-veil" aria-hidden="true"></div>

  <!-- ================= NAV ================= -->
  <nav class="nav">
    <div class="wrap nav-in">
      <a class="brand" href="#top" aria-label="Gamepad to Keyboard home">
        <span class="mark" aria-hidden="true">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none"><path d="M8 9v6M5 12h6" stroke="#8A8FFF" stroke-width="1.8" stroke-linecap="round"/><circle cx="16" cy="10.5" r="1.4" fill="#34D399"/><circle cx="18.5" cy="13.5" r="1.4" fill="#8A8FFF"/><rect x="2.4" y="6.2" width="19.2" height="11.6" rx="5" stroke="#8A8FFF" stroke-width="1.6"/></svg>
        </span>
        Gamepad&nbsp;to&nbsp;Keyboard
      </a>
      <div class="nav-links">
        <a class="navlink" href="#features">Features</a>
        <a class="navlink" href="#controllers">Controllers</a>
        <a class="navlink" href="#how">How it works</a>
        <a class="navlink" href="#faq">FAQ</a>
        <a class="navlink" href="https://github.com/heeklb6/gamepad-to-keyboard" rel="noopener">GitHub</a>
        <a class="nav-cta" href="https://sourceforge.net/projects/gamepad-to-keyboard/files/latest/download" rel="noopener">
          <svg width="15" height="15" viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M12 3v12m0 0l4-4m-4 4l-4-4M5 20h14" stroke="#0b1019" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
          Download
        </a>
      </div>
    </div>
  </nav>

  <!-- ================= HERO ================= -->
  <header class="hero" id="top">
    <canvas class="hero-canvas" id="fx" aria-hidden="true"></canvas>
    <div class="aurora a1" id="au1" aria-hidden="true"></div>
    <div class="aurora a2" id="au2" aria-hidden="true"></div>
    <div class="aurora a3" id="au3" aria-hidden="true"></div>
    <div class="hero-veil" aria-hidden="true"></div>
    <div class="hero-fade" aria-hidden="true"></div>

    <div class="wrap hero-in">
      <span class="eyebrow rise d1"><span class="dot" aria-hidden="true"></span>Open source · MIT · Windows 10 &amp; 11</span>
      <h1 class="rise d2">Turn any controller into a <span class="grad">keyboard.</span></h1>
      <p class="sub rise d3">
        Gamepad to Keyboard is a free tool that maps every button, trigger and stick on your
        controller to real keystrokes and mouse clicks — so you can play keyboard-only games with a
        controller: emulators, browser games, retro classics and any PC title that never expected a gamepad.
      </p>
      <div class="hero-actions rise d4">
        <a class="btn btn-primary" href="https://sourceforge.net/projects/gamepad-to-keyboard/files/latest/download" rel="noopener">
          <svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M12 3v12m0 0l4.2-4.2M12 15l-4.2-4.2M5 20h14" stroke="#0a0e18" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
          Download for Windows
        </a>
        <a class="btn btn-ghost" href="https://github.com/heeklb6/gamepad-to-keyboard" rel="noopener">
          <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2C6.48 2 2 6.58 2 12.25c0 4.53 2.87 8.37 6.84 9.73.5.1.68-.22.68-.49 0-.24-.01-.87-.01-1.72-2.78.62-3.37-1.37-3.37-1.37-.45-1.18-1.11-1.5-1.11-1.5-.91-.63.07-.62.07-.62 1 .07 1.53 1.06 1.53 1.06.89 1.56 2.34 1.11 2.91.85.09-.66.35-1.11.63-1.36-2.22-.26-4.55-1.14-4.55-5.06 0-1.12.39-2.03 1.03-2.75-.1-.26-.45-1.3.1-2.71 0 0 .84-.28 2.75 1.05a9.35 9.35 0 015 0c1.91-1.33 2.75-1.05 2.75-1.05.55 1.41.2 2.45.1 2.71.64.72 1.03 1.63 1.03 2.75 0 3.93-2.34 4.8-4.57 5.05.36.32.68.94.68 1.9 0 1.37-.01 2.48-.01 2.82 0 .27.18.6.69.49A10.02 10.02 0 0022 12.25C22 6.58 17.52 2 12 2z"/></svg>
          View on GitHub
        </a>
        <a class="btn btn-ghost" href="https://sourceforge.net/projects/gamepad-to-keyboard/" rel="noopener">
          <svg viewBox="0 0 117 102.6" fill="#FF6600" aria-hidden="true" style="width:27px;height:24px"><path d="M66.9,54.5c0-19.1-6.8-27.8-10.4-31.1c-0.7-0.6-1.8-0.1-1.7,0.9c0.7,10.8-12.9,13.5-12.9,30.4h0 c0,0,0,0.1,0,0.1c0,10.3,7.8,18.7,17.4,18.7c9.6,0,17.4-8.4,17.4-18.7c0,0,0-0.1,0-0.1h0c0-4.8-1.8-9.4-3.6-12.8 c-0.4-0.7-1.4-0.4-1.3,0.2C75.1,56.7,66.9,65.7,66.9,54.5z"/><path d="M46.2,94.8c-0.4,0-0.9-0.2-1.2-0.5L0.5,49.8c-0.6-0.6-0.6-1.7,0-2.4l47-47C47.8,0.2,48.2,0,48.6,0h13.5 c0.8,0,1.3,0.5,1.5,1c0.2,0.5,0.2,1.2-0.4,1.8L19.1,47c-0.9,0.9-0.9,2.3,0,3.2L54,85.2c0.6,0.6,0.6,1.7,0,2.4l-6.7,6.8 C47,94.6,46.6,94.8,46.2,94.8z"/><path d="M55.1,102.6c-0.8,0-1.3-0.5-1.5-1c-0.2-0.5-0.2-1.2,0.4-1.8l44.2-44.2c0.4-0.4,0.7-1,0.7-1.6 c0-0.6-0.2-1.2-0.7-1.6L63.2,17.4c-0.6-0.6-0.6-1.7,0-2.4l6.8-6.8c0.3-0.3,0.7-0.5,1.2-0.5S72,8,72.3,8.3l44.4,44.5 c0.3,0.3,0.5,0.7,0.5,1.2s-0.2,0.9-0.5,1.2l-47,47c-0.3,0.3-0.7,0.5-1.2,0.5H55.1z"/></svg>
          SourceForge
        </a>
      </div>
      <div class="hero-meta rise d5">
        <span class="mi"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M5 12l4 4L19 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> No drivers, no virtual controller</span>
        <span class="mi"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M5 12l4 4L19 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Single portable <b>.exe</b></span>
        <span class="mi"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M5 12l4 4L19 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> <b class="tnum">100%</b> free · no ads</span>
      </div>
    </div>
  </header>

  <!-- ================= SCREENSHOT ================= -->
  <section class="section" style="padding-top:24px" aria-label="App preview">
    <div class="wrap reveal">
      <div class="shot-wrap">
        <div class="shot-halo" aria-hidden="true"></div>
        <figure class="frame" style="margin:0">
          <div class="titlebar">
            <span class="tdots" aria-hidden="true"><i></i><i></i><i></i></span>
            <span class="tbtitle"><b>Gamepad to Keyboard</b> — Profile: WASD Shooter</span>
          </div>
          <img src="/assets/shot.png" loading="lazy" decoding="async" alt="Gamepad to Keyboard — mapping a controller to keyboard keys">
        </figure>
      </div>
      <div class="shot-tags">
        <span class="tag"><b>Live</b> on-screen controller view</span>
        <span class="tag">Lights up <b>green</b> as you press</span>
        <span class="tag">Every button &rarr; any key or mouse click</span>
        <span class="tag"><b>F8</b> toggle in-game</span>
      </div>
    </div>
  </section>

  <!-- ================= FEATURES ================= -->
  <section class="section" id="features">
    <div class="wrap">
      <div class="reveal">
        <p class="kicker">Everything you need</p>
        <h2>Remap controller buttons to any key — nothing left out.</h2>
        <p class="lead">From face buttons to the tiniest stick-click, every input on the pad is yours to reassign. Bind it to a keyboard key or a mouse button, then save it as a profile you can switch to in a click.</p>
      </div>

      <div class="feat-grid">
        <article class="card reveal">
          <div class="ic" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none"><rect x="3" y="7" width="18" height="10" rx="4" stroke="currentColor" stroke-width="1.7"/><path d="M8 10v4M6 12h4" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><circle cx="15.5" cy="11" r="1.1" fill="currentColor"/><circle cx="17.5" cy="13.5" r="1.1" fill="currentColor"/></svg></div>
          <h3>Map every input</h3>
          <p>A/B/X/Y, bumpers, triggers, D-pad, both analog sticks and the L3/R3 clicks — all remappable to any keyboard key.</p>
        </article>

        <article class="card em reveal">
          <div class="ic" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none"><path d="M6 3l13 8-5.5 1.5L16 18l-2 1-2.5-5-3.5 3z" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/></svg></div>
          <h3>Keys or mouse clicks</h3>
          <p>Bind any button to a left, right or middle mouse click — aim, fire or point without touching the mouse.</p>
        </article>

        <article class="card reveal">
          <div class="ic" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none"><rect x="3" y="5" width="8" height="6" rx="1.6" stroke="currentColor" stroke-width="1.7"/><rect x="13" y="5" width="8" height="14" rx="1.6" stroke="currentColor" stroke-width="1.7"/><rect x="3" y="13" width="8" height="6" rx="1.6" stroke="currentColor" stroke-width="1.7"/></svg></div>
          <h3>Profiles &amp; presets</h3>
          <p>Create, rename, duplicate and delete profiles — all auto-saved. Start from WASD Shooter, Retro / Arcade, Move + Mouse or a blank slate.</p>
        </article>

        <article class="card em reveal">
          <div class="ic" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none"><rect x="2.5" y="6.5" width="19" height="11" rx="5.5" stroke="currentColor" stroke-width="1.7"/><path d="M7 9v4M5 11h4" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><circle cx="15.5" cy="10" r="1.3" fill="currentColor"/><circle cx="18" cy="12.5" r="1.3" fill="currentColor"/></svg></div>
          <h3>Live controller view</h3>
          <p>An on-screen pad mirrors your hands and lights up green the instant you press — you watch every mapping fire in real time.</p>
        </article>

        <article class="card reveal">
          <div class="ic" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none"><rect x="4" y="7" width="16" height="10" rx="2" stroke="currentColor" stroke-width="1.7"/><path d="M8 11h.01M12 11h.01M16 11h.01M8 14h8" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"/></svg></div>
          <h3>Global F8 toggle</h3>
          <p>Flip mapping on or off with one hotkey — no alt-tab, no leaving the game, no losing the moment.</p>
        </article>

        <article class="card reveal">
          <div class="ic" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none"><path d="M12 3l7 3v6c0 4-3 6.5-7 9-4-2.5-7-5-7-9V6l7-3z" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/><path d="M9 12l2 2 4-4" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
          <h3>No drivers, no virtual pad</h3>
          <p>It sends real keystrokes — nothing to install, no virtual controller injected. Just one portable .exe you can run anywhere.</p>
        </article>

        <article class="card em reveal">
          <div class="ic" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="8.5" stroke="currentColor" stroke-width="1.7"/><path d="M12 7v5l3 2" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
          <h3>Instant, zero-lag input</h3>
          <p>Powered by SDL2, presses register the moment they happen — tight enough for shooters, platformers and fighting games.</p>
        </article>

        <article class="card reveal">
          <div class="ic" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none"><path d="M12 2.5l2.9 5.9 6.6.96-4.75 4.63 1.12 6.55L12 17.5 6.13 20.6l1.12-6.55L2.5 9.36l6.6-.96L12 2.5z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/></svg></div>
          <h3>Free &amp; open source</h3>
          <p>MIT licensed and 100% free with no ads — a free, open-source alternative to reWASD you can read, fork and trust.</p>
        </article>
      </div>
    </div>
  </section>

  <!-- ================= CONTROLLERS ================= -->
  <section class="section" id="controllers" style="padding-top:24px">
    <div class="wrap">
      <div class="reveal">
        <p class="kicker">Broad hardware support</p>
        <h2>Works with Xbox, PS4, PS5, Switch Pro and generic gamepads.</h2>
        <p class="lead">Whatever is on your desk plugs in and works. Xbox / PS4 / PS5 controller keyboard mapping runs on the same SDL2 engine that recognises hundreds of pads — wired over USB or paired over Bluetooth.</p>
      </div>

      <div class="pads-scroll">
        <div class="pads">
          <article class="pad reveal">
            <svg class="padic" viewBox="0 0 48 48" fill="none" aria-hidden="true"><rect x="4" y="15" width="40" height="20" rx="10" stroke="#8A8FFF" stroke-width="2"/><path d="M14 20v8M10 24h8" stroke="#8A8FFF" stroke-width="2" stroke-linecap="round"/><circle cx="31" cy="22" r="2" fill="#8A8FFF"/><circle cx="37" cy="22" r="2" fill="#8A8FFF"/><circle cx="31" cy="28" r="2" fill="#8A8FFF"/><circle cx="34" cy="25" r="2" fill="#34D399"/></svg>
            <h3>Xbox</h3>
            <p>Series X|S, Xbox One and 360 pads — wired or wireless.</p>
            <span class="ok"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M5 12l4 4L19 6" stroke="#34D399" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/></svg>Plug &amp; map</span>
          </article>

          <article class="pad reveal">
            <svg class="padic" viewBox="0 0 48 48" fill="none" aria-hidden="true"><rect x="4" y="15" width="40" height="20" rx="10" stroke="#8A8FFF" stroke-width="2"/><path d="M13 21v6M10 24h6" stroke="#8A8FFF" stroke-width="2" stroke-linecap="round"/><path d="M31 24l0 0M35 24l0 0M33 22l0 4" stroke="#8A8FFF" stroke-width="2" stroke-linecap="round"/><path d="M20 15v4M28 15v4" stroke="#34D399" stroke-width="2" stroke-linecap="round"/></svg>
            <h3>PlayStation</h3>
            <p>DualShock 4 and DualSense (PS5) — including touchpad click.</p>
            <span class="ok"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M5 12l4 4L19 6" stroke="#34D399" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/></svg>Plug &amp; map</span>
          </article>

          <article class="pad reveal">
            <svg class="padic" viewBox="0 0 48 48" fill="none" aria-hidden="true"><rect x="6" y="12" width="14" height="24" rx="7" stroke="#8A8FFF" stroke-width="2"/><rect x="28" y="12" width="14" height="24" rx="7" stroke="#8A8FFF" stroke-width="2"/><path d="M13 19v6M10 22h6" stroke="#34D399" stroke-width="2" stroke-linecap="round"/><circle cx="35" cy="20" r="1.7" fill="#8A8FFF"/><circle cx="35" cy="26" r="1.7" fill="#8A8FFF"/></svg>
            <h3>Switch Pro</h3>
            <p>Nintendo Switch Pro Controller, ready to remap.</p>
            <span class="ok"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M5 12l4 4L19 6" stroke="#34D399" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/></svg>Plug &amp; map</span>
          </article>

          <article class="pad reveal">
            <svg class="padic" viewBox="0 0 48 48" fill="none" aria-hidden="true"><rect x="4" y="15" width="40" height="20" rx="10" stroke="#8A8FFF" stroke-width="2"/><path d="M14 21v6M11 24h6" stroke="#8A8FFF" stroke-width="2" stroke-linecap="round"/><circle cx="32" cy="24" r="2" fill="#8A8FFF"/><circle cx="37" cy="24" r="2" fill="#34D399"/><path d="M24 8v5" stroke="#8A8FFF" stroke-width="2" stroke-linecap="round"/></svg>
            <h3>Generic USB / BT</h3>
            <p>Third-party and retro-style pads over USB or Bluetooth.</p>
            <span class="ok"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M5 12l4 4L19 6" stroke="#34D399" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/></svg>Plug &amp; map</span>
          </article>
        </div>
      </div>
      <p class="pads-note reveal">Under the hood it's SDL2, the same controller library used across the games industry — so if your OS sees the pad, Gamepad to Keyboard can map it.</p>
    </div>
  </section>

  <!-- ================= HOW IT WORKS ================= -->
  <section class="section" id="how">
    <div class="wrap">
      <div class="reveal">
        <p class="kicker">From zero to playing</p>
        <h2>Map gamepad to keyboard in four steps.</h2>
        <p class="lead">No setup wizard, no config files. This is joystick to keyboard the way it should be — point, press, play.</p>
      </div>

      <ol class="steps" style="list-style:none;padding:0">
        <li class="step reveal">
          <div class="n tnum">01</div>
          <h3>Plug in your pad</h3>
          <p>Connect any controller over USB or Bluetooth. SDL2 detects it the moment it's live.</p>
        </li>
        <li class="step reveal">
          <div class="n tnum">02</div>
          <h3>Pick a button, press a key</h3>
          <p>Click a button on the on-screen pad, then press the keyboard key or mouse click you want it to send.</p>
        </li>
        <li class="step reveal">
          <div class="n tnum">03</div>
          <h3>Save a profile</h3>
          <p>Keep your layout as a named profile — or load a preset like WASD Shooter and tweak from there.</p>
        </li>
        <li class="step reveal">
          <div class="n tnum">04</div>
          <h3>Press <span class="key">F8</span> and play</h3>
          <p>Toggle mapping on and your gamepad now types real keystrokes into any game or app.</p>
        </li>
      </ol>
    </div>
  </section>

  <!-- ================= REVIEWS ================= -->
  <section class="section" style="padding-top:24px" aria-label="Reviews">
    <div class="wrap">
      <div class="reveal">
        <p class="kicker">Loved by players</p>
        <h2>A controller-to-keyboard bridge people actually keep installed.</h2>
        <div class="rating-strip tnum">
          <span class="big">4.9<span style="color:var(--muted);font-size:1rem;font-weight:500;font-family:var(--text)"> / 5</span></span>
          <span>from <b style="color:var(--ink)">1,240+</b> downloads this month</span>
          <span class="stars" aria-hidden="true">
            <svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg>
            <svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg>
            <svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg>
            <svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg>
            <svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg>
          </span>
        </div>
      </div>

      <div class="rev-grid">
        <article class="rev reveal">
          <div class="stars tnum" aria-label="5 out of 5 stars"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg></div>
          <p>“Finally playing my RetroArch library with a DualSense instead of the keyboard. Mapped the whole layout in about two minutes and the retro preset was already 90% right.”</p>
          <div class="who"><span class="av" style="background:linear-gradient(150deg,#8A8FFF,#5b62d6)" aria-hidden="true">RM</span><div><div class="nm">Ravi M.</div><div class="hd">@pixel_ravi · emulators</div></div></div>
        </article>

        <article class="rev reveal">
          <div class="stars tnum" aria-label="5 out of 5 stars"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg></div>
          <p>“I have limited hand mobility and mapping the right stick to mouse plus buttons to clicks lets me play point-and-click games again. The live view makes it easy to see what I set.”</p>
          <div class="who"><span class="av" style="background:linear-gradient(150deg,#34D399,#1f8f6b)" aria-hidden="true">DP</span><div><div class="nm">Dana P.</div><div class="hd">accessibility gamer</div></div></div>
        </article>

        <article class="rev reveal">
          <div class="stars tnum" aria-label="5 out of 5 stars"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg></div>
          <p>“Tried it as a free reWASD alternative and honestly it does exactly what I needed — no subscription, no account, no driver. Xbox pad to WASD for an old indie game, done.”</p>
          <div class="who"><span class="av" style="background:linear-gradient(150deg,#8A8FFF,#34D399)" aria-hidden="true">JK</span><div><div class="nm">Jonas K.</div><div class="hd">@jonaskaes · indie PC</div></div></div>
        </article>

        <article class="rev reveal">
          <div class="stars tnum" aria-label="5 out of 5 stars"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg></div>
          <p>“Browser MMO with no gamepad support — now I run around with the left stick on mouse and skills on the face buttons. The F8 toggle is perfect for typing in chat.”</p>
          <div class="who"><span class="av" style="background:linear-gradient(150deg,#6c73e6,#8A8FFF)" aria-hidden="true">SL</span><div><div class="nm">Sofia L.</div><div class="hd">@sofmmo · browser MMO</div></div></div>
        </article>

        <article class="rev reveal">
          <div class="stars tnum" aria-label="5 out of 5 stars"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg></div>
          <p>“Portable exe on my USB stick, works on every PC at the LAN café. Switch Pro pad mapped to a fighting-game layout and the input feels dead-on.”</p>
          <div class="who"><span class="av" style="background:linear-gradient(150deg,#34D399,#8A8FFF)" aria-hidden="true">TT</span><div><div class="nm">Theo T.</div><div class="hd">@theofgc · fighting games</div></div></div>
        </article>

        <article class="rev reveal">
          <div class="stars tnum" aria-label="5 out of 5 stars"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 8.8l6.5-.9L12 2z"/></svg></div>
          <p>“Set up a couple of profiles for different old games and switch between them instantly. Open source, no ads, no telemetry — exactly what I want on my machine.”</p>
          <div class="who"><span class="av" style="background:linear-gradient(150deg,#5b62d6,#34D399)" aria-hidden="true">MO</span><div><div class="nm">Marco O.</div><div class="hd">@marco_retro · retro PC</div></div></div>
        </article>
      </div>
    </div>
  </section>

  <!-- ================= DOWNLOAD BAND ================= -->
  <section class="section" style="padding-top:24px" id="download">
    <div class="wrap">
      <div class="band reveal">
        <h2>Grab the free keyboard mapper for your controller.</h2>
        <p>One download, one .exe, and every button on your pad becomes a key. No account, nothing to configure before it runs.</p>
        <div class="hero-actions">
          <a class="btn btn-primary" href="https://sourceforge.net/projects/gamepad-to-keyboard/files/latest/download" rel="noopener">
            <svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M12 3v12m0 0l4.2-4.2M12 15l-4.2-4.2M5 20h14" stroke="#0a0e18" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
            Download for Windows
          </a>
          <a class="btn btn-ghost" href="https://github.com/heeklb6/gamepad-to-keyboard" rel="noopener">
            <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2C6.48 2 2 6.58 2 12.25c0 4.53 2.87 8.37 6.84 9.73.5.1.68-.22.68-.49 0-.24-.01-.87-.01-1.72-2.78.62-3.37-1.37-3.37-1.37-.45-1.18-1.11-1.5-1.11-1.5-.91-.63.07-.62.07-.62 1 .07 1.53 1.06 1.53 1.06.89 1.56 2.34 1.11 2.91.85.09-.66.35-1.11.63-1.36-2.22-.26-4.55-1.14-4.55-5.06 0-1.12.39-2.03 1.03-2.75-.1-.26-.45-1.3.1-2.71 0 0 .84-.28 2.75 1.05a9.35 9.35 0 015 0c1.91-1.33 2.75-1.05 2.75-1.05.55 1.41.2 2.45.1 2.71.64.72 1.03 1.63 1.03 2.75 0 3.93-2.34 4.8-4.57 5.05.36.32.68.94.68 1.9 0 1.37-.01 2.48-.01 2.82 0 .27.18.6.69.49A10.02 10.02 0 0022 12.25C22 6.58 17.52 2 12 2z"/></svg>
            View on GitHub
          </a>
          <a class="btn btn-ghost" href="https://sourceforge.net/projects/gamepad-to-keyboard/" rel="noopener">
            <svg viewBox="0 0 117 102.6" fill="#FF6600" aria-hidden="true" style="width:27px;height:24px"><path d="M66.9,54.5c0-19.1-6.8-27.8-10.4-31.1c-0.7-0.6-1.8-0.1-1.7,0.9c0.7,10.8-12.9,13.5-12.9,30.4h0 c0,0,0,0.1,0,0.1c0,10.3,7.8,18.7,17.4,18.7c9.6,0,17.4-8.4,17.4-18.7c0,0,0-0.1,0-0.1h0c0-4.8-1.8-9.4-3.6-12.8 c-0.4-0.7-1.4-0.4-1.3,0.2C75.1,56.7,66.9,65.7,66.9,54.5z"/><path d="M46.2,94.8c-0.4,0-0.9-0.2-1.2-0.5L0.5,49.8c-0.6-0.6-0.6-1.7,0-2.4l47-47C47.8,0.2,48.2,0,48.6,0h13.5 c0.8,0,1.3,0.5,1.5,1c0.2,0.5,0.2,1.2-0.4,1.8L19.1,47c-0.9,0.9-0.9,2.3,0,3.2L54,85.2c0.6,0.6,0.6,1.7,0,2.4l-6.7,6.8 C47,94.6,46.6,94.8,46.2,94.8z"/><path d="M55.1,102.6c-0.8,0-1.3-0.5-1.5-1c-0.2-0.5-0.2-1.2,0.4-1.8l44.2-44.2c0.4-0.4,0.7-1,0.7-1.6 c0-0.6-0.2-1.2-0.7-1.6L63.2,17.4c-0.6-0.6-0.6-1.7,0-2.4l6.8-6.8c0.3-0.3,0.7-0.5,1.2-0.5S72,8,72.3,8.3l44.4,44.5 c0.3,0.3,0.5,0.7,0.5,1.2s-0.2,0.9-0.5,1.2l-47,47c-0.3,0.3-0.7,0.5-1.2,0.5H55.1z"/></svg>
            SourceForge
          </a>
        </div>
        <p class="reassure">Free forever · No ads · No drivers · MIT licensed</p>
      </div>
    </div>
  </section>

  <!-- ================= FAQ ================= -->
  <section class="section" id="faq" style="padding-top:24px">
    <div class="wrap" style="max-width:840px">
      <div class="reveal">
        <p class="kicker">Answers</p>
        <h2>Frequently asked questions</h2>
      </div>
      <div class="faq reveal">
        <details class="q" open>
          <summary>Is it free?<span class="pm" aria-hidden="true"></span></summary>
          <div class="ans">Yes — completely free, with no ads, no trial and no paid tier. Gamepad to Keyboard is open source under the MIT license, so you can use it, read the code and fork it however you like.</div>
        </details>
        <details class="q">
          <summary>Does it work outside Steam?<span class="pm" aria-hidden="true"></span></summary>
          <div class="ans">Absolutely. Because it sends real keyboard and mouse input at the system level, it works with non-Steam titles, emulators, browser games, retro and old games — anywhere on Windows. If a game reads a keyboard, it can be driven by your controller.</div>
        </details>
        <details class="q">
          <summary>Which controllers are supported?<span class="pm" aria-hidden="true"></span></summary>
          <div class="ans">Xbox (Series, One, 360), PlayStation DualShock 4 and DualSense (PS5), the Nintendo Switch Pro Controller, and generic USB or Bluetooth gamepads. It's built on SDL2, so Xbox / PS4 / PS5 controller keyboard mapping and hundreds of other pads work out of the box.</div>
        </details>
        <details class="q">
          <summary>Is this a free reWASD alternative?<span class="pm" aria-hidden="true"></span></summary>
          <div class="ans">If you're after the core job — remap controller buttons to keyboard keys and mouse clicks, save profiles and switch between them — then yes, it covers that for free and open source. It focuses on being a clean, no-subscription keyboard mapper for your controller rather than matching every advanced feature of paid tools.</div>
        </details>
        <details class="q">
          <summary>Do I need to install drivers?<span class="pm" aria-hidden="true"></span></summary>
          <div class="ans">No drivers and no virtual controller. It doesn't create a fake gamepad or hook a kernel driver — it simply translates your pad's inputs into real keystrokes. It's a single portable .exe you can run without installing anything.</div>
        </details>
        <details class="q">
          <summary>Is it safe?<span class="pm" aria-hidden="true"></span></summary>
          <div class="ans">The full source is public on <a href="https://github.com/heeklb6/gamepad-to-keyboard" rel="noopener">GitHub</a> under the MIT license, with no ads, no telemetry and no bundled extras. You can review exactly what it does or build it yourself before running it.</div>
        </details>
      </div>
    </div>
  </section>

  <!-- ================= FOOTER ================= -->
  <footer class="foot">
    <div class="wrap">
      <div class="foot-top">
        <div>
          <div class="brand">
            <span class="mark" aria-hidden="true"><svg width="18" height="18" viewBox="0 0 24 24" fill="none"><path d="M8 9v6M5 12h6" stroke="#8A8FFF" stroke-width="1.8" stroke-linecap="round"/><circle cx="16" cy="10.5" r="1.4" fill="#34D399"/><circle cx="18.5" cy="13.5" r="1.4" fill="#8A8FFF"/><rect x="2.4" y="6.2" width="19.2" height="11.6" rx="5" stroke="#8A8FFF" stroke-width="1.6"/></svg></span>
            Gamepad to Keyboard
          </div>
          <p class="tagline">The free, open-source way to map a gamepad to keyboard keys — controller to keyboard and joystick to keyboard for every keyboard-only game on your PC.</p>
        </div>
        <nav class="foot-links" aria-label="Footer">
          <a href="#features">Features</a>
          <a href="#controllers">Controllers</a>
          <a href="#how">How it works</a>
          <a href="#faq">FAQ</a>
          <a href="https://sourceforge.net/projects/gamepad-to-keyboard/files/latest/download" rel="noopener">Download</a>
          <a href="https://github.com/heeklb6/gamepad-to-keyboard" rel="noopener">GitHub</a>
        </nav>
      </div>
      <div class="foot-bottom">
        <span>© 2026 Gamepad to Keyboard</span>
        <span class="lic">MIT licensed · Free forever</span>
      </div>
    </div>
  </footer>

</div>

<script>
(function(){
  var root = document.querySelector('.gk-root');
  var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  /* onload hero reveal */
  requestAnimationFrame(function(){ root.classList.add('loaded'); });

  /* scroll reveal */
  var items = document.querySelectorAll('.reveal');
  if('IntersectionObserver' in window && !reduce){
    var io = new IntersectionObserver(function(entries){
      entries.forEach(function(e){
        if(e.isIntersecting){ e.target.classList.add('in'); io.unobserve(e.target); }
      });
    }, {rootMargin:'0px 0px -8% 0px', threshold:0.12});
    items.forEach(function(el){ io.observe(el); });
  } else {
    items.forEach(function(el){ el.classList.add('in'); });
  }

  /* pointer parallax on hero glows */
  var hero = document.querySelector('.hero');
  var a1 = document.getElementById('au1'), a2 = document.getElementById('au2'), a3 = document.getElementById('au3');
  if(hero && !reduce){
    var tx=0,ty=0,cx=0,cy=0,raf=null;
    hero.addEventListener('pointermove', function(ev){
      var r = hero.getBoundingClientRect();
      tx = ((ev.clientX - r.left)/r.width - .5);
      ty = ((ev.clientY - r.top)/r.height - .5);
      if(!raf) raf = requestAnimationFrame(loop);
    });
    hero.addEventListener('pointerleave', function(){ tx=0; ty=0; if(!raf) raf=requestAnimationFrame(loop); });
    function loop(){
      cx += (tx-cx)*.06; cy += (ty-cy)*.06;
      if(a1) a1.style.transform = 'translate('+(cx*34)+'px,'+(cy*26)+'px)';
      if(a2) a2.style.transform = 'translate('+(cx*-26)+'px,'+(cy*-20)+'px)';
      if(a3) a3.style.transform = 'translate('+(cx*18)+'px,'+(cy*-14)+'px)';
      if(Math.abs(tx-cx)>.001 || Math.abs(ty-cy)>.001){ raf = requestAnimationFrame(loop); }
      else raf = null;
    }
  }

  /* ambient particle field */
  var canvas = document.getElementById('fx');
  if(canvas && canvas.getContext){
    var ctx = canvas.getContext('2d');
    var dpr = Math.min(window.devicePixelRatio||1, 2);
    var W=0, H=0, parts=[], anim=null;
    function size(){
      var host = canvas.parentElement;
      W = host.clientWidth; H = host.clientHeight;
      canvas.width = Math.floor(W*dpr); canvas.height = Math.floor(H*dpr);
      canvas.style.width = W+'px'; canvas.style.height = H+'px';
      ctx.setTransform(dpr,0,0,dpr,0,0);
      build();
    }
    function build(){
      var target = Math.round(Math.min(70, Math.max(24, (W*H)/24000)));
      parts = [];
      for(var i=0;i<target;i++){
        parts.push({
          x: Math.random()*W,
          y: Math.random()*H,
          r: Math.random()*1.7+0.5,
          vx: (Math.random()-.5)*0.18,
          vy: (Math.random()-.5)*0.18 - 0.06,
          a: Math.random()*0.5+0.15,
          em: Math.random() < 0.22
        });
      }
    }
    function draw(){
      ctx.clearRect(0,0,W,H);
      /* faint connecting lines */
      for(var i=0;i<parts.length;i++){
        var p = parts[i];
        for(var j=i+1;j<parts.length;j++){
          var q = parts[j];
          var dx=p.x-q.x, dy=p.y-q.y, d2=dx*dx+dy*dy;
          if(d2 < 14000){
            var o = (1 - d2/14000)*0.16;
            ctx.strokeStyle = 'rgba(124,131,255,'+o.toFixed(3)+')';
            ctx.lineWidth = 1;
            ctx.beginPath(); ctx.moveTo(p.x,p.y); ctx.lineTo(q.x,q.y); ctx.stroke();
          }
        }
      }
      for(var k=0;k<parts.length;k++){
        var pt = parts[k];
        pt.x += pt.vx; pt.y += pt.vy;
        if(pt.x < -10) pt.x = W+10; else if(pt.x > W+10) pt.x = -10;
        if(pt.y < -10) pt.y = H+10; else if(pt.y > H+10) pt.y = -10;
        ctx.beginPath();
        ctx.arc(pt.x, pt.y, pt.r, 0, Math.PI*2);
        ctx.fillStyle = pt.em
          ? 'rgba(52,211,153,'+pt.a.toFixed(3)+')'
          : 'rgba(160,168,255,'+pt.a.toFixed(3)+')';
        ctx.fill();
      }
      anim = requestAnimationFrame(draw);
    }
    size();
    if(!reduce){ draw(); }
    else {
      /* single static frame */
      for(var s=0;s<parts.length;s++){
        var sp=parts[s];
        ctx.beginPath(); ctx.arc(sp.x,sp.y,sp.r,0,Math.PI*2);
        ctx.fillStyle = sp.em ? 'rgba(52,211,153,'+sp.a.toFixed(3)+')' : 'rgba(160,168,255,'+sp.a.toFixed(3)+')';
        ctx.fill();
      }
    }
    var rt=null;
    window.addEventListener('resize', function(){
      clearTimeout(rt); rt=setTimeout(function(){
        dpr = Math.min(window.devicePixelRatio||1, 2); size();
        if(reduce){
          ctx.clearRect(0,0,W,H);
          for(var s=0;s<parts.length;s++){var sp=parts[s];ctx.beginPath();ctx.arc(sp.x,sp.y,sp.r,0,Math.PI*2);ctx.fillStyle=sp.em?'rgba(52,211,153,'+sp.a.toFixed(3)+')':'rgba(160,168,255,'+sp.a.toFixed(3)+')';ctx.fill();}
        }
      }, 180);
    });
    /* pause when hero scrolled away */
    if('IntersectionObserver' in window && !reduce){
      var vo = new IntersectionObserver(function(en){
        en.forEach(function(e){
          if(e.isIntersecting){ if(!anim) draw(); }
          else { if(anim){ cancelAnimationFrame(anim); anim=null; } }
        });
      }, {threshold:0.01});
      vo.observe(canvas);
    }
  }
})();
</script>

</body>
</html>
