{"id":51245703,"url":"https://github.com/thehashton/hashton.dev","last_synced_at":"2026-06-29T04:02:32.559Z","repository":{"id":356406063,"uuid":"1232338596","full_name":"thehashton/hashton.dev","owner":"thehashton","description":"Consultancy portfolio for Harry Ashton on all things frontend development, agency guidance, technical mentorship.","archived":false,"fork":false,"pushed_at":"2026-06-22T12:38:46.000Z","size":812,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-22T14:24:35.867Z","etag":null,"topics":["consultancy","contract","frontend","nextjs","portfolio","software","typescript"],"latest_commit_sha":null,"homepage":"https://hashton.dev","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thehashton.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-07T20:41:46.000Z","updated_at":"2026-06-22T12:38:50.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/thehashton/hashton.dev","commit_stats":null,"previous_names":["thehashton/hashton","thehashton/hashton.dev"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/thehashton/hashton.dev","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thehashton%2Fhashton.dev","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thehashton%2Fhashton.dev/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thehashton%2Fhashton.dev/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thehashton%2Fhashton.dev/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thehashton","download_url":"https://codeload.github.com/thehashton/hashton.dev/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thehashton%2Fhashton.dev/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34912252,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-29T02:00:05.398Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["consultancy","contract","frontend","nextjs","portfolio","software","typescript"],"created_at":"2026-06-29T04:02:31.940Z","updated_at":"2026-06-29T04:02:32.554Z","avatar_url":"https://github.com/thehashton.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Hashton\n\n**Harry Ashton** — Senior frontend engineer (contract \u0026 consulting). This repository is the source for my portfolio site; stack and setup are documented below if you need them.\n\n![Portfolio homepage preview](./public/images/hero-preview.png)\n\n---\n\n## What’s inside\n\n- **Visual system** — Paper-and-ink palette, hairline borders, hard shadows, monospace captions (Tailwind CSS v4 + design tokens in `src/styles/globals.css`).\n- **Hero** — Custom `HeroVideo` player (poster, fullscreen dialog, keyboard-friendly controls, reduced-motion aware).\n- **Work** — Case studies from `src/content/work/*.mdx` with dynamic `/work/[slug]` routes.\n- **Contact** — React Hook Form + Zod; `POST /api/contact` sends mail via [Resend](https://resend.com/) when configured, otherwise returns a graceful fallback for `mailto:`.\n- **SEO** — Metadata, Open Graph image, `robots.txt`, `sitemap.xml`, JSON-LD `Person` schema.\n- **Analytics** — Vercel Analytics \u0026 Speed Insights (optional in production).\n\n## Tech stack\n\n| Layer     | Choices                                                                    |\n| --------- | -------------------------------------------------------------------------- |\n| Framework | [Next.js](https://nextjs.org/) 15 (App Router), React 19, TypeScript       |\n| Styling   | Tailwind CSS v4, Framer Motion                                             |\n| Content   | MDX (`gray-matter`, `@next/mdx` / remote MDX pipeline as wired in the app) |\n| Forms     | react-hook-form, Zod                                                       |\n| Icons     | `simple-icons`, bespoke brand SVGs where needed                            |\n\n## Requirements\n\n- **Node.js** ≥ 18.18 (recommended: **20.x**)\n- **pnpm** (package manager for this repo)\n\n## Local development\n\n```bash\npnpm install\npnpm dev\n```\n\nOpen [http://localhost:3000](http://localhost:3000).\n\n```bash\npnpm lint      # ESLint\npnpm build     # production build (Turbopack)\npnpm start     # run production server locally\n```\n\n## Environment variables\n\nCreate a `.env.local` (not committed) for production-like behavior:\n\n| Variable               | Purpose                                                                           |\n| ---------------------- | --------------------------------------------------------------------------------- |\n| `NEXT_PUBLIC_SITE_URL` | Canonical site URL (metadata, OG, sitemap). Example: `https://hashton.vercel.app` |\n| `RESEND_API_KEY`       | Resend API key — contact form sends email when set                                |\n| `CONTACT_EMAIL`        | Inbox address for contact submissions                                             |\n| `CONTACT_FROM`         | Optional Resend `from` string (defaults in API route if unset)                    |\n\nIf `RESEND_API_KEY` or `CONTACT_EMAIL` is missing, the API still responds successfully with `fallback: true` so the UI can open the user’s mail client instead.\n\n## Project layout (high level)\n\n```\nsrc/\n  app/           # App Router pages, API routes, OG image\n  components/    # Layout, sections, video, UI primitives\n  content/work/  # MDX case studies\n  lib/           # Site config, nav, data helpers\n  styles/        # Global CSS + Tailwind theme\npublic/          # Static assets (e.g. video, posters)\n```\n\n## Deploy\n\nConfigured for **[Vercel](https://vercel.com/)**: connect the repo, set the env vars above, and deploy. Asset-heavy routes are static where possible; `/api/contact` runs on the Edge/Node runtime per Next defaults.\n\n---\n\nI maintain this repo at [@thehashton](https://github.com/thehashton).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthehashton%2Fhashton.dev","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthehashton%2Fhashton.dev","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthehashton%2Fhashton.dev/lists"}