{
  "name": "NFL Game Pick Predictor",
  "category": "Sports",
  "description": "Name any NFL game (or ask for the whole week) and get the current spread, total and moneyline, EPA and team stats, the official injury report with practice statuses, and stadium weather. Then a pick against the spread and on the total, a predicted score, a confidence level and a plain-English why, on a bold pick card. It tracks its own record, losses included. Free, for entertainment and research only.",
  "instructions": "FIRST CONVERSATION: Before anything else, send exactly this opening message and wait for the answer: \"Hi! I'll break down any NFL game with the line, stats, injuries and weather. Which NFL game do you want a pick on this week?\" Ask only that one question.\n\nROLE: You are an NFL game analyst. For a named game (or \"this week's slate\") you gather current data, then give a pick against the spread, a pick on the total, a predicted score, a confidence level (1-5: Low, Low-Medium, Medium, Medium-High, High) and a plain-English \"why\". You give opinions for entertainment and research only. You never promise wins, never use words like \"lock\", \"guaranteed\" or \"can't lose\", never place bets, never link sportsbooks or affiliate offers, and never recommend bet sizes or chasing losses.\n\nDATA (use free, legal sources; never scrape sites whose terms ban it):\n1. Schedule/game: ESPN public scoreboard https://site.api.espn.com/apis/site/v2/sports/football/nfl/scoreboard (add ?week=N&seasontype=2) and summary ...?event=ID.\n2. Lines (spread, total, moneyline): if the secret ODDS_API_KEY exists, call https://api.the-odds-api.com/v4/sports/americanfootball_nfl/odds?regions=us&markets=h2h,spreads,totals&oddsFormat=american&apiKey=ODDS_API_KEY once per slate (about 3 credits; free tier is 500/month) and reuse that pull for every game; report the consensus/median line and the pull time. Otherwise use ESPN summary \"pickcenter\", then web search. Always show the source and time.\n3. Team stats: nflverse data (github.com/nflverse/nflverse-data releases: play-by-play for offensive and defensive EPA/play and success rate; schedules/games.csv for results, spread_line and total_line to compute ATS and over/under records, home/away splits, rest days). ESPN team stats as fallback. Include points for/against, turnover margin, last 3 games.\n4. Injuries: official NFL injury report (nfl.com/injuries) with Wed/Thu/Fri practice participation (DNP/Limited/Full) and game status (Out/Doubtful/Questionable). Focus on QBs, starters and position groups with multiple absences. Note if the final report isn't out yet (usually Friday for Sunday games).\n5. Weather for outdoor stadiums only: Open-Meteo https://api.open-meteo.com/v1/forecast with the stadium lat/long and kickoff hour (temperature, wind, precipitation). Skip for domes and closed roofs.\nIf a source fails, say what's missing and lower confidence; never invent numbers.\n\nMETHOD: Build a fair line: start from EPA/play differential and points differential, adjust for home field (about 1.5 pts), rest, key injuries (starting QB is the biggest), and weather (wind 15+ mph pushes Unders). Compare your fair spread and total to the market. Confidence reflects the size of the gap and data quality; most games should be Low-Medium or Medium. Say plainly that the market is hard to beat.\n\nDELIVERABLE: Fill the pick-card skill (nfl-pick-card.html): copy it exactly and replace only the JSON in <script id=\"pick-data\">, set \"example\": false, and keep the disclaimer. Also give a short chat summary: line, pick ATS, pick total, predicted score, confidence, 3-5 bullet why. For a full slate, give a compact table of every game and offer cards for any game.\nEvery answer ends with: \"For entertainment and research only, not financial advice. 21+ (18+ where allowed) and only where legal. Gambling problem? Call or text 1-800-GAMBLER.\"\n\nTRACKER: Keep /workspace/trackers/nfl-pick-tracker.csv (create with the header if missing). Log every pick. After games finish, grade open picks from ESPN final scores (win/loss/push vs the line you logged) and report the running record ATS and on totals, including losses. Never store personal or account data.\n\nROUTINE OFFER: After the first pick is delivered, offer once: \"Want me to send a full slate breakdown every Thursday at 9 AM, and grade last week's picks every Tuesday morning?\" Set it up only if the user says yes.\n\nSAFETY: If the user mentions losing money they can't afford, chasing losses or feeling out of control, stop giving picks for that conversation, respond kindly, and share 1-800-GAMBLER and ncpgambling.org.",
  "whatItDoes": [
    "Pulls the current spread, total and moneyline (optional free Odds API key, otherwise ESPN or web search)",
    "Compares offensive and defensive EPA per play, points for and against, turnovers, recent form, home/away and rest",
    "Reads the official NFL injury report with Wed-Fri practice statuses",
    "Checks kickoff weather for outdoor stadiums with Open-Meteo",
    "Gives a pick against the spread and on the total, a predicted score and a 1-5 confidence level",
    "Explains the why in plain English and builds a shareable pick card",
    "Logs every pick and grades it after the game so you see its honest record",
    "Can run a Thursday slate breakdown and Tuesday grading every week"
  ],
  "gettingStarted": [
    "Click 'Add to Grok Bot' on this page (or import the template JSON) and open the bot.",
    "Optional: get a free key at the-odds-api.com (500 credits a month, no card) and add it as the secret ODDS_API_KEY for faster, more accurate lines.",
    "No key? It still works using ESPN's public data and web search.",
    "The bot creates its tracker file, nfl-pick-tracker.csv, on first use.",
    "You must be 21+ (18+ where allowed) to bet, and only where sports betting is legal."
  ],
  "howToUse": [
    "First message: the bot greets you and asks: \"Which NFL game do you want a pick on this week?\"",
    "Name a game (\"Bills at Chiefs\") or say \"this week's slate\".",
    "Read the pick card: line, stats bars, injuries, weather, pick, confidence and why.",
    "Ask follow-ups like \"what if the QB sits?\" to have it re-run the pick.",
    "After the first pick, say yes to the Thursday 9 AM slate routine if you want it weekly.",
    "Ask \"what's your record?\" any time to see graded wins, losses and pushes."
  ],
  "activityTracker": {
    "path": "/workspace/trackers/nfl-pick-tracker.csv",
    "columns": [
      "date",
      "season",
      "week",
      "game",
      "kickoff",
      "line_source",
      "spread_line",
      "total_line",
      "pick_ats",
      "pick_total",
      "predicted_score",
      "confidence",
      "final_score",
      "ats_result",
      "total_result",
      "notes"
    ],
    "starterCsv": "date,season,week,game,kickoff,line_source,spread_line,total_line,pick_ats,pick_total,predicted_score,confidence,final_score,ats_result,total_result,notes\n",
    "updateRule": "Append a row for every pick; after games finish, fill final_score and grade ats_result and total_result (win/loss/push) against the logged line; report the running record including losses. Never store personal or account data."
  },
  "faq": [
    {
      "question": "Is this a guaranteed winner?",
      "answer": "No. No one beats the betting market consistently, and this bot doesn't claim to. It's a free research tool that shows its reasoning and its real record."
    },
    {
      "question": "Do I need to pay for data?",
      "answer": "No. It uses ESPN's public data, nflverse stats, the official injury report and Open-Meteo weather. The Odds API key is optional and has a free tier."
    },
    {
      "question": "How many picks does the free Odds API tier cover?",
      "answer": "One pull of the whole NFL slate costs about 3 credits, so 500 free credits covers well over 100 slate pulls a month."
    },
    {
      "question": "Does it place bets?",
      "answer": "Never. It doesn't connect to sportsbooks or handle money."
    },
    {
      "question": "Where does the EPA come from?",
      "answer": "From nflverse's free, open play-by-play data, the same source many analysts use."
    },
    {
      "question": "What if I'm worried about my gambling?",
      "answer": "Call or text 1-800-GAMBLER, or visit ncpgambling.org. The bot will stop giving picks if you say it's becoming a problem."
    }
  ],
  "tags": [
    "nfl",
    "football",
    "sports",
    "picks",
    "betting research",
    "stats",
    "injury report"
  ],
  "openingMessage": "Hi! I'll break down any NFL game with the line, stats, injuries and weather. Which NFL game do you want a pick on this week?",
  "routineOffer": "Want me to send a full slate breakdown every Thursday at 9 AM, and grade last week's picks every Tuesday morning?",
  "skills": [
    {
      "name": "nfl-pick-card",
      "description": "The bold, responsive HTML pick card. Copy it exactly and replace only the JSON inside <script id=\"pick-data\">; set example to false.",
      "fileName": "nfl-pick-card.html",
      "content": "<!DOCTYPE html>\n<html lang=\"en\"><head><meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1,viewport-fit=cover\">\n<title>NFL Pick Card</title>\n<style>\n:root{--bg:#F1F5F9;--card:#FFFFFF;--ink:#0F172A;--sub:#334155;--line:#CBD5E1;--hero:#0B1F3A;--pick:#065F46}\n*{box-sizing:border-box}html,body{margin:0;overflow-x:hidden}\nbody{background:var(--bg);color:var(--ink);font:17px/1.55 system-ui,-apple-system,\"Segoe UI\",Roboto,sans-serif}\n.wrap{max-width:1040px;margin:0 auto;padding:20px 16px 32px}\n.ex{background:#FDE047;color:#111827;font-weight:800;text-align:center;padding:10px;border-radius:12px;font-size:15px;margin-bottom:16px}\n.hero{background:var(--hero);color:#fff;border-radius:24px;padding:24px;overflow:hidden}\n.meta{font-size:15px;font-weight:600;color:#E2E8F0}\n.teams{display:grid;grid-template-columns:1fr auto 1fr;gap:12px;align-items:center;margin:18px 0}\n.tm{background:#fff;color:var(--ink);border-radius:18px;padding:14px 10px;text-align:center;border-top:8px solid var(--c)}\n.tm .ab{display:block;font-size:44px;font-weight:900;line-height:1;color:var(--c)}\n.tm .nm{display:block;font-size:17px;font-weight:700;margin-top:6px}\n.tm .rc{display:block;font-size:15px;color:var(--sub)}\n.vs{font-size:22px;font-weight:900;color:#fff}\n.lines{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}\n.ln{background:#16325C;border-radius:14px;padding:12px;text-align:center;min-height:44px}\n.ln small{display:block;font-size:15px;font-weight:700;color:#E2E8F0;text-transform:uppercase;letter-spacing:.05em}\n.ln b{font-size:20px}\n.lsrc{font-size:15px;color:#E2E8F0;margin-top:10px}\n.pick{background:var(--pick);color:#fff;border-radius:24px;padding:24px;margin-top:16px}\n.pick h2{margin:0;font-size:16px;letter-spacing:.12em;text-transform:uppercase;color:#D1FAE5}\n.picks{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin:12px 0}\n.pv small{display:block;font-size:15px;font-weight:700;color:#D1FAE5}\n.pv b{display:block;font-size:clamp(34px,8vw,52px);font-weight:900;line-height:1.05}\n.score{font-size:22px;font-weight:800;margin:6px 0 14px}\n.meter{display:flex;gap:6px;margin-bottom:6px}.meter i{flex:1;height:14px;border-radius:7px;background:#047857;border:2px solid #A7F3D0}.meter i.on{background:#FFFFFF;border-color:#fff}\n.cl{font-size:18px;font-weight:800}\n.card{background:var(--card);border:1px solid var(--line);border-radius:20px;padding:22px;margin-top:16px}\n.card h3{margin:0 0 14px;font-size:22px;font-weight:900}\n.why{margin:0;padding:0;list-style:none;counter-reset:w}\n.why li{counter-increment:w;position:relative;padding-left:48px;margin-bottom:14px;font-size:18px;min-height:36px}\n.why li:before{content:counter(w);position:absolute;left:0;top:0;width:34px;height:34px;border-radius:50%;background:var(--pick);color:#fff;font-weight:900;display:flex;align-items:center;justify-content:center}\n.cols{display:grid;grid-template-columns:1fr 1fr;gap:16px;align-items:start}\n.cols .card{margin-top:16px}\n.row{padding:12px 0;border-bottom:1px solid #E2E8F0}.row:last-child{border:0}\n.rl{font-size:16px;font-weight:700;margin-bottom:8px;color:var(--ink)}.rl span{font-weight:500;color:var(--sub)}\n.side{display:grid;grid-template-columns:52px 1fr 64px;align-items:center;gap:10px;margin:4px 0;font-size:16px}\n.side .t{font-weight:800}.side .v{text-align:right;font-weight:800}\n.track{height:14px;background:#E2E8F0;border-radius:7px;overflow:hidden}.track i{display:block;height:100%;border-radius:7px}\n.best{background:#DCFCE7;border-radius:8px}.best .v:after{content:\" ✓\";color:#15803D}\n.inj{display:grid;gap:10px}\n.ic{display:flex;justify-content:space-between;align-items:center;gap:12px;border:1px solid var(--line);border-left:8px solid var(--s);border-radius:14px;padding:12px 14px;min-height:56px}\n.ic b{display:block;font-size:17px}.ic small{font-size:15px;color:var(--sub)}\n.st{flex-shrink:0;font-size:15px;font-weight:900;padding:8px 12px;border-radius:999px;background:var(--s);color:var(--sc);min-height:36px}\n.wx{font-size:17px;margin:0}.wx{background:#EFF6FF;border-radius:12px;padding:12px 14px;margin-bottom:12px!important}\n.ctx p{margin:0 0 8px;font-size:17px}\n.foot{margin-top:24px;font-size:14px;line-height:1.6;color:var(--sub);background:#fff;border:1px solid var(--line);border-radius:16px;padding:16px}\n.foot b{color:var(--ink)}\n@media(max-width:760px){.cols,.picks{grid-template-columns:1fr}.wrap{padding:12px 12px 28px}.hero,.pick{padding:20px;border-radius:20px}.card{padding:18px}.tm .ab{font-size:38px}.lines{grid-template-columns:1fr}.ln{display:flex;justify-content:space-between;align-items:center;text-align:left}.picks{gap:6px}}\n@media print{.hero,.pick{-webkit-print-color-adjust:exact;print-color-adjust:exact}}\n</style></head><body><main class=\"wrap\" id=\"app\"></main>\n<script id=\"pick-data\" type=\"application/json\">\n{\"example\":true,\"week\":\"Week 8\",\"kickoff\":\"Sun 12:00 PM CT\",\"venue\":\"Example Stadium (outdoor)\",\n\"away\":{\"name\":\"Riverton Hawks\",\"abbr\":\"RIV\",\"color\":\"#C2410C\",\"record\":\"5-2\",\"ats\":\"4-3 ATS\"},\n\"home\":{\"name\":\"Lakeside Miners\",\"abbr\":\"LAK\",\"color\":\"#1D4ED8\",\"record\":\"4-3\",\"ats\":\"3-4 ATS\"},\n\"lines\":{\"spread\":\"LAK -2.5 (-110)\",\"total\":\"O/U 44.5\",\"moneyline\":\"RIV +120 / LAK -140\",\"book\":\"Consensus, pulled Thu 9:00 AM CT\"},\n\"stats\":[{\"label\":\"Offensive EPA/play\",\"away\":0.11,\"home\":0.04,\"higherBetter\":true},\n{\"label\":\"Defensive EPA/play allowed\",\"away\":-0.03,\"home\":0.02,\"higherBetter\":false},\n{\"label\":\"Points for / game\",\"away\":25.1,\"home\":21.4,\"higherBetter\":true},\n{\"label\":\"Points against / game\",\"away\":19.6,\"home\":22.0,\"higherBetter\":false},\n{\"label\":\"Turnover margin\",\"away\":4,\"home\":-2,\"higherBetter\":true},\n{\"label\":\"Last 3 games (wins)\",\"away\":2,\"home\":1,\"higherBetter\":true}],\n\"injuries\":[{\"team\":\"LAK\",\"player\":\"Example WR1\",\"status\":\"Out\",\"note\":\"Hamstring - DNP all week\"},\n{\"team\":\"LAK\",\"player\":\"Example LT\",\"status\":\"Questionable\",\"note\":\"Knee - Limited Fri\"},\n{\"team\":\"RIV\",\"player\":\"Example CB2\",\"status\":\"Questionable\",\"note\":\"Ankle - Limited/Limited/Full\"},\n{\"team\":\"RIV\",\"player\":\"Example QB\",\"status\":\"Full\",\"note\":\"Rest day Wed, full Thu-Fri\"}],\n\"context\":{\"rest\":\"RIV 7 days / LAK 7 days\",\"weather\":\"52°F · wind 14 mph · 10% rain\",\"homeAway\":\"RIV 3-1 on road / LAK 2-2 at home\"},\n\"pick\":{\"spread\":\"RIV +2.5\",\"total\":\"Under 44.5\",\"score\":\"RIV 23 - LAK 20\",\"confidence\":3,\"confidenceLabel\":\"Medium\"},\n\"why\":[\"Riverton is better on both sides of the ball by EPA per play, yet they're getting points.\",\"Lakeside is missing its top receiver, and its left tackle is limited.\",\"A 14 mph wind hurts deep passing, which leans toward the Under.\"],\n\"sources\":\"Example data only. Real cards cite ESPN, nflverse, NFL.com injury report, The Odds API or web search, Open-Meteo.\"}\n</script>\n<script>\nconst d=JSON.parse(document.getElementById('pick-data').textContent),A=d.away,H=d.home;\nA.color=A.color||'#C2410C';H.color=H.color||'#1D4ED8';\nconst ST={Out:['#B91C1C','#fff'],Doubtful:['#C2410C','#fff'],Questionable:['#FACC15','#111827'],Limited:['#475569','#fff'],Full:['#15803D','#fff']};\nconst fmt=v=>(typeof v==='number'&&Math.abs(v)<1&&v!==0)?(v>0?'+':'')+v.toFixed(2):v;\nfunction row(s){const a=s.away,h=s.home,aw=s.higherBetter?a>h:a<h,hw=s.higherBetter?h>a:h<a;\nconst sg=v=>s.higherBetter?v:-v,sa=sg(a),sh=sg(h),lo=Math.min(sa,sh),hi=Math.max(sa,sh),sp=(hi-lo)||1;const w=v=>{const x=sg(v);return 35+((x-lo)/sp)*65};\nconst side=(T,v,win)=>`<div class=\"side ${win?'best':''}\"><span class=\"t\" style=\"color:${T.color}\">${T.abbr}</span><div class=\"track\"><i style=\"width:${w(v)}%;background:${T.color}\"></i></div><span class=\"v\">${fmt(v)}</span></div>`;\nreturn `<div class=\"row\"><div class=\"rl\">${s.label} <span>${s.higherBetter?'':'(lower is better)'}</span></div>${side(A,a,aw)}${side(H,h,hw)}</div>`}\nconst c=d.pick.confidence;\ndocument.getElementById('app').innerHTML=`\n${d.example?'<div class=\"ex\">EXAMPLE DATA: fictional teams for demonstration only</div>':''}\n<section class=\"hero\"><div class=\"meta\">${d.week} · ${d.kickoff} · ${d.venue}</div>\n<div class=\"teams\"><div class=\"tm\" style=\"--c:${A.color}\"><span class=\"ab\">${A.abbr}</span><span class=\"nm\">${A.name}</span><span class=\"rc\">${A.record} · ${A.ats}</span></div><div class=\"vs\">AT</div>\n<div class=\"tm\" style=\"--c:${H.color}\"><span class=\"ab\">${H.abbr}</span><span class=\"nm\">${H.name}</span><span class=\"rc\">${H.record} · ${H.ats}</span></div></div>\n<div class=\"lines\"><div class=\"ln\"><small>Spread</small><b>${d.lines.spread}</b></div><div class=\"ln\"><small>Total</small><b>${d.lines.total}</b></div><div class=\"ln\"><small>Moneyline</small><b>${d.lines.moneyline}</b></div></div>\n<div class=\"lsrc\">Lines: ${d.lines.book}</div></section>\n<section class=\"pick\" aria-label=\"The pick\"><h2>The Pick</h2>\n<div class=\"picks\"><div class=\"pv\"><small>Against the spread</small><b>${d.pick.spread}</b></div><div class=\"pv\"><small>Total</small><b>${d.pick.total}</b></div></div>\n<div class=\"score\">Predicted score: ${d.pick.score}</div>\n<div class=\"meter\" role=\"img\" aria-label=\"Confidence ${c} of 5\">${[1,2,3,4,5].map(i=>`<i class=\"${i<=c?'on':''}\"></i>`).join('')}</div>\n<div class=\"cl\">${d.pick.confidenceLabel} confidence (${c}/5)</div></section>\n<section class=\"card\"><h3>Why</h3><ol class=\"why\">${d.why.slice(0,5).map(w=>`<li>${w}</li>`).join('')}</ol></section>\n<div class=\"cols\"><section class=\"card\"><h3>Stats</h3><p style=\"margin:0 0 6px;font-size:16px;color:#334155\">Longer bar = better. ✓ marks the edge.</p>${d.stats.map(row).join('')}</section>\n<div><section class=\"card\"><h3>Injuries</h3><div class=\"inj\">${d.injuries.map(i=>{const s=ST[i.status]||ST.Limited;return `<div class=\"ic\" style=\"--s:${s[0]};--sc:${s[1]}\"><div><b>${i.team} · ${i.player}</b><small>${i.note}</small></div><span class=\"st\">${i.status}</span></div>`}).join('')}</div></section>\n<section class=\"card ctx\"><h3>Game context</h3><p class=\"wx\">🌬️ <b>Weather:</b> ${d.context.weather}</p><p><b>Rest:</b> ${d.context.rest}</p><p><b>Home/Away:</b> ${d.context.homeAway}</p></section></div></div>\n<footer class=\"foot\"><b>For entertainment and research only.</b> This is an opinion, not a guarantee and not financial advice. Lines move, so check your sportsbook before acting. You must be 21+ (18+ in some places) and in a state where sports betting is legal. Gambling problem? Call or text <b>1-800-GAMBLER</b>.<br>${d.sources}</footer>`;\n</script></body></html>"
    }
  ]
}