├── .gitignore ├── LICENSE.txt ├── README.md ├── components.json ├── eslint.config.mjs ├── next.config.mjs ├── next.config.ts ├── package-lock.json ├── package.json ├── postcss.config.mjs ├── public ├── blog │ ├── autograd-logic │ │ └── dag.png │ └── my-2025-resolution │ │ └── karpathy-tweet.png ├── gion-town.png └── pytorch │ └── inference_mode.png ├── src ├── app │ ├── about │ │ ├── layout.tsx │ │ ├── opengraph-image.alt.txt │ │ ├── opengraph-image.png │ │ ├── page.tsx │ │ ├── twitter-image.alt.txt │ │ └── twitter-image.png │ ├── blog │ │ ├── README.md │ │ ├── [slug] │ │ │ └── page.tsx │ │ ├── _components │ │ │ ├── BlogCard.tsx │ │ │ └── BlogHeader.tsx │ │ ├── _data │ │ │ └── posts.ts │ │ ├── _types │ │ │ └── blog.ts │ │ ├── layout.tsx │ │ ├── opengraph-image.alt.txt │ │ ├── opengraph-image.png │ │ ├── page.tsx │ │ ├── posts │ │ │ ├── autograd-logic │ │ │ │ ├── content.mdx │ │ │ │ ├── layout.tsx │ │ │ │ ├── opengraph-image.alt.txt │ │ │ │ ├── opengraph-image.png │ │ │ │ ├── page.tsx │ │ │ │ ├── twitter-image.alt.txt │ │ │ │ └── twitter-image.png │ │ │ ├── getting-started-with-machine-learning │ │ │ │ ├── layout.tsx │ │ │ │ ├── opengraph-image.alt.txt │ │ │ │ ├── opengraph-image.png │ │ │ │ ├── page.tsx │ │ │ │ ├── section-ids.ts │ │ │ │ ├── twitter-image.alt.txt │ │ │ │ └── twitter-image.png │ │ │ └── my-2025-resolution │ │ │ │ ├── content.mdx │ │ │ │ ├── layout.tsx │ │ │ │ ├── opengraph-image.alt.txt │ │ │ │ ├── opengraph-image.png │ │ │ │ ├── page.tsx │ │ │ │ ├── twitter-image.alt.txt │ │ │ │ └── twitter-image.png │ │ ├── twitter-image.alt.txt │ │ └── twitter-image.png │ ├── favicon.ico │ ├── globals.css │ ├── homepage │ │ └── page.tsx │ ├── layout.tsx │ ├── learning │ │ ├── layout.tsx │ │ ├── learning-utensils │ │ │ ├── layout.tsx │ │ │ └── page.tsx │ │ ├── opengraph-image.alt.txt │ │ ├── opengraph-image.png │ │ ├── page.tsx │ │ ├── twitter-image.alt.txt │ │ ├── twitter-image.png │ │ └── weekly-reflections │ │ │ ├── README.md │ │ │ ├── [week] │ │ │ ├── layout.tsx │ │ │ ├── page.tsx │ │ │ └── week-page.tsx │ │ │ ├── _data │ │ │ └── weeks.ts │ │ │ ├── content │ │ │ ├── week-1.mdx │ │ │ ├── week-2.mdx │ │ │ ├── week-23.mdx │ │ │ ├── week-24.mdx │ │ │ ├── week-3.mdx │ │ │ ├── week-4.mdx │ │ │ ├── week-5.mdx │ │ │ ├── week-6.mdx │ │ │ ├── week-7.mdx │ │ │ └── week-8.mdx │ │ │ ├── layout.tsx │ │ │ ├── page.tsx │ │ │ └── scripts │ │ │ ├── update-weeks.js │ │ │ └── update-weeks.ts │ ├── notes │ │ ├── [slug] │ │ │ └── page.tsx │ │ ├── _components │ │ │ ├── NotesCard.tsx │ │ │ └── NotesHeader.tsx │ │ ├── _data │ │ │ └── posts.ts │ │ ├── _types │ │ │ └── note-types.ts │ │ ├── books │ │ │ ├── layout.tsx │ │ │ ├── llm-from-scratch-raschka │ │ │ │ ├── chapter-1 │ │ │ │ │ ├── notes.mdx │ │ │ │ │ └── page.tsx │ │ │ │ ├── layout.tsx │ │ │ │ └── page.tsx │ │ │ └── page.tsx │ │ ├── layout.tsx │ │ ├── math │ │ │ └── page.tsx │ │ ├── opengraph-image.alt.txt │ │ ├── opengraph-image.png │ │ ├── page.tsx │ │ ├── pytorch │ │ │ ├── content.mdx │ │ │ ├── layout.tsx │ │ │ └── page.tsx │ │ ├── twitter-image.alt.txt │ │ └── twitter-image.png │ ├── opengraph-image.alt.txt │ ├── opengraph-image.jpg │ ├── page.tsx │ ├── twitter-image.alt.txt │ └── twitter-image.jpg ├── components │ ├── blocks │ │ ├── callout │ │ │ └── callout.tsx │ │ ├── code-block │ │ │ └── code-block.tsx │ │ ├── homepage │ │ │ ├── CurrentWork.tsx │ │ │ ├── HeroSection.tsx │ │ │ ├── HomepageSocials.tsx │ │ │ ├── QuickLinks.tsx │ │ │ └── SocialLinks.tsx │ │ └── table-of-contents │ │ │ └── table-of-contents.tsx │ ├── layout │ │ ├── container │ │ │ └── base-container.tsx │ │ ├── footer │ │ │ ├── BaseFooter.tsx │ │ │ ├── HomepageFooter.tsx │ │ │ ├── IndividualPageFooter.tsx │ │ │ ├── SectionFooter.tsx │ │ │ └── _components │ │ │ │ ├── FooterDivider.tsx │ │ │ │ ├── FooterLink.tsx │ │ │ │ └── FooterSection.tsx │ │ └── layout-stack │ │ │ └── layout-stack.tsx │ └── ui │ │ ├── accordion │ │ └── accordion.tsx │ │ ├── list │ │ └── list.tsx │ │ ├── math │ │ └── math.tsx │ │ ├── navbar │ │ └── Navbar.tsx │ │ ├── primitives │ │ ├── breadcrumb.tsx │ │ ├── button.tsx │ │ ├── hover-card.tsx │ │ ├── navigation-menu.tsx │ │ └── separator.tsx │ │ ├── ruler │ │ └── ruler.tsx │ │ ├── text-heading │ │ └── text-heading.tsx │ │ ├── text │ │ └── text.tsx │ │ └── theme │ │ ├── theme-provider.tsx │ │ └── theme-toggle.tsx ├── lib │ ├── mdx │ │ └── mdx-components.tsx │ └── utils │ │ └── utils.ts └── styles │ ├── fonts │ └── fonts.ts │ └── patterns.css ├── tailwind.config.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.* 7 | .yarn/* 8 | !.yarn/patches 9 | !.yarn/plugins 10 | !.yarn/releases 11 | !.yarn/versions 12 | 13 | # testing 14 | /coverage 15 | 16 | # next.js 17 | /.next/ 18 | /out/ 19 | 20 | # production 21 | /build 22 | 23 | # misc 24 | .DS_Store 25 | *.pem 26 | 27 | # debug 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | .pnpm-debug.log* 32 | 33 | # env files (can opt-in for committing if needed) 34 | .env* 35 | 36 | # vercel 37 | .vercel 38 | 39 | # typescript 40 | *.tsbuildinfo 41 | next-env.d.ts 42 | 43 | .vscode 44 | 45 | BlogPostContent.tsx -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 sumitdotml 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Website for my blog 2 | 3 | A minimalistic personal blog and learning documentation website built with Next.js, Tailwind, and TypeScript. 4 | 5 | ## Want to use this code for your own site? 6 | 7 | You are free to copy any part of this repository or even the entire thing. All I ask of you is to star this repository if you found it useful and maybe provide some credit & shoutout if you're feeling kind (but you don't have to if your vibes are not into these) :) 8 | 9 | ## Installation 10 | 11 | 1. Clone the repository 12 | 13 | ```bash 14 | git clone https://github.com/sumitdotml/website.git 15 | ``` 16 | 17 | 2. Go to the project directory 18 | 19 | ```bash 20 | cd website 21 | ``` 22 | 23 | 3. Install dependencies 24 | 25 | ```bash 26 | npm install 27 | ``` 28 | 29 | 4. Run the development server 30 | 31 | ```bash 32 | npm run dev 33 | ``` 34 | 35 | 5. Open the website in your browser 36 | 37 | ```bash 38 | http://localhost:3000 39 | ``` 40 | 41 | You may run into some issues when doing `npm install` because of the dependencies. You can always ask our AI friends to help you out. :) 42 | 43 | If there are any errors, issues or suggestions, please feel free to [open a new issue](https://github.com/sumitdotml/website/issues/new). 44 | 45 | ## Tools used 46 | 47 | Some ui components are from [shadcn/ui](https://ui.shadcn.com/docs/): 48 | 49 | - [Breadcrumb](https://ui.shadcn.com/docs/components/breadcrumb) 50 | - [Button](https://ui.shadcn.com/docs/components/button) 51 | - [Navigation Menu](https://ui.shadcn.com/docs/components/navigation-menu) 52 | - [Accordion](https://ui.shadcn.com/docs/components/accordion) 53 | - [Separator](https://ui.shadcn.com/docs/components/separator) 54 | - [Hover Card](https://ui.shadcn.com/docs/components/hover-card) 55 | 56 | ## To-Do 57 | 58 | - [ ] Make the navbar sticky for mobile and make the navbar move its original Y position a little higher and stick to the very top when the user scrolls down 59 | - [ ] Add a search bar 60 | - [ ] Add a graph visualization (similar to the [Obsidian graph view](https://help.obsidian.md/Plugins/Graph+view)) 61 | - [ ] Add a "On this page" (like a ToC) section to the top right of the page in the PC version. It should be hidden on mobile. -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.ts", 8 | "css": "src/app/globals.css", 9 | "baseColor": "neutral", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/styles/components", 15 | "utils": "@/styles/lib/utils", 16 | "ui": "@/styles/components/ui", 17 | "lib": "@/styles/lib", 18 | "hooks": "@/styles/hooks", 19 | "common-components": "@/app/common-components" 20 | }, 21 | "iconLibrary": "lucide" 22 | } -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | // eslint.config.mjs 2 | import path from "path"; 3 | import { fileURLToPath } from "url"; 4 | 5 | // Convert URL to path 6 | const __filename = fileURLToPath(import.meta.url); 7 | const __dirname = path.dirname(__filename); 8 | 9 | /** @type {import('eslint').Linter.FlatConfig[]} */ 10 | const eslintConfig = [ 11 | { 12 | files: ["**/*.{js,mjs,cjs,jsx,ts,tsx}"], 13 | languageOptions: { 14 | ecmaVersion: 2022, 15 | sourceType: "module", 16 | jsx: true, 17 | }, 18 | rules: { 19 | 'react/no-unescaped-entities': 'off', 20 | '@next/next/no-page-custom-font': 'off', 21 | }, 22 | }, 23 | ]; 24 | 25 | export default eslintConfig; -------------------------------------------------------------------------------- /next.config.mjs: -------------------------------------------------------------------------------- 1 | import createMDX from '@next/mdx' 2 | 3 | /** @type {import('next').NextConfig} */ 4 | const nextConfig = { 5 | pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'], 6 | async rewrites() { 7 | return [ 8 | { 9 | source: '/learning/weekly-reflections/week-:num', 10 | destination: '/learning/weekly-reflections/[week]?week=week-:num', 11 | }, 12 | ] 13 | }, 14 | } 15 | 16 | const withMDX = createMDX({ 17 | }) 18 | 19 | export default withMDX(nextConfig) 20 | -------------------------------------------------------------------------------- /next.config.ts: -------------------------------------------------------------------------------- 1 | import type { NextConfig } from "next"; 2 | 3 | const nextConfig: NextConfig = { 4 | /* config options here */ 5 | reactStrictMode: true, 6 | }; 7 | 8 | export default nextConfig; 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nextjs-site", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev --turbopack", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@mdx-js/loader": "^3.1.0", 13 | "@mdx-js/react": "^3.1.0", 14 | "@next/mdx": "^15.1.3", 15 | "@radix-ui/react-accordion": "^1.2.3", 16 | "@radix-ui/react-hover-card": "^1.1.4", 17 | "@radix-ui/react-navigation-menu": "^1.2.2", 18 | "@radix-ui/react-separator": "^1.1.1", 19 | "@radix-ui/react-slot": "^1.1.1", 20 | "@types/katex": "^0.16.7", 21 | "@types/mdx": "^2.0.13", 22 | "@vercel/analytics": "^1.4.1", 23 | "class-variance-authority": "^0.7.1", 24 | "clsx": "^2.1.1", 25 | "framer-motion": "^11.15.0", 26 | "katex": "^0.16.21", 27 | "lucide-react": "^0.468.0", 28 | "next": "^15.1.4", 29 | "next-mdx-remote": "^5.0.0", 30 | "next-themes": "^0.4.4", 31 | "prism-react-renderer": "^2.4.1", 32 | "react": "^19.0.0", 33 | "react-dom": "^19.0.0", 34 | "tailwind-merge": "^2.5.5", 35 | "tailwindcss-animate": "^1.0.7" 36 | }, 37 | "devDependencies": { 38 | "@eslint/eslintrc": "^3", 39 | "@types/node": "^20", 40 | "@types/react": "^19", 41 | "@types/react-dom": "^19", 42 | "eslint": "^9", 43 | "eslint-config-next": "15.1.0", 44 | "gray-matter": "^4.0.3", 45 | "postcss": "^8", 46 | "tailwindcss": "^3.4.1", 47 | "tsx": "^4.19.3", 48 | "typescript": "^5" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /public/blog/autograd-logic/dag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitdotml/website/0dd4528252337303b2cbe7d75f8c727f5d08ae97/public/blog/autograd-logic/dag.png -------------------------------------------------------------------------------- /public/blog/my-2025-resolution/karpathy-tweet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitdotml/website/0dd4528252337303b2cbe7d75f8c727f5d08ae97/public/blog/my-2025-resolution/karpathy-tweet.png -------------------------------------------------------------------------------- /public/gion-town.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitdotml/website/0dd4528252337303b2cbe7d75f8c727f5d08ae97/public/gion-town.png -------------------------------------------------------------------------------- /public/pytorch/inference_mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitdotml/website/0dd4528252337303b2cbe7d75f8c727f5d08ae97/public/pytorch/inference_mode.png -------------------------------------------------------------------------------- /src/app/about/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Metadata } from 'next' 2 | 3 | export const metadata: Metadata = { 4 | title: 'My Novice Journey\'s Monologue | sumit.ml', 5 | description: 'I don\'t really know what I\'m doing', 6 | openGraph: { 7 | title: 'My Novice Journey\'s Monologue | sumit.ml', 8 | description: 'I don\'t really know what I\'m doing', 9 | type: 'website', 10 | }, 11 | twitter: { 12 | card: 'summary_large_image', 13 | title: 'My Novice Journey: A Monologue', 14 | description: 'I don\'t really know what I\'m doing', 15 | } 16 | } 17 | 18 | export default function Layout({ 19 | children, 20 | }: { 21 | children: React.ReactNode 22 | }) { 23 | return children 24 | } -------------------------------------------------------------------------------- /src/app/about/opengraph-image.alt.txt: -------------------------------------------------------------------------------- 1 | My Novice Journey's Monologue | sumit.ml -------------------------------------------------------------------------------- /src/app/about/opengraph-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitdotml/website/0dd4528252337303b2cbe7d75f8c727f5d08ae97/src/app/about/opengraph-image.png -------------------------------------------------------------------------------- /src/app/about/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import BaseContainer from "@/components/layout/container/base-container" 4 | import { StackVertical } from "@/components/layout/layout-stack/layout-stack" 5 | import TextHeading from "@/components/ui/text-heading/text-heading" 6 | import { SectionFooter } from "@/components/layout/footer/SectionFooter" 7 | import Text from "@/components/ui/text/text" 8 | import { DynamicBreadcrumb } from "@/components/ui/primitives/breadcrumb" 9 | import { ThemeToggle } from "@/components/ui/theme/theme-toggle" 10 | 11 | export default function About() { 12 | return ( 13 | 14 | 15 |
16 | 22 | 23 |
24 | 25 |
26 | 27 | My Novice Journey: A Monologue 28 | 29 | January 14, 2025 30 | 31 | 32 | Hi, thanks for checking in! I like going on random tangents when I write, so I'm not sure if this is the best way to write about myself. But hey, I'm glad you're here. 33 | 34 | 35 | 36 | I have an interesting name. During my middle and high school years, I knew the existences of only 2 people with the same name as me. I thought it was not a very common name in my country, but turns out a name isn't limited to a country. And for those wondering, no I am not from India. Although I understand why you'd think so. It's all good. 37 | 38 | 39 | I studied in Japan as a business undergraduate for 4 years and received a degree in it, but I was truly never interested in anything related to business. Well, it's a long story about why I ended up at the university I ended up in and pursued the kind of degree I pursued despite having next to no interest in any of that, but life does really work in fascinating ways. I must say that it hasn't turned out too bad for myself. 40 | 41 | 42 | To be very brief, I was always into math and was always fascinated by the engineering behind a lot of things I would see in real life. Bridges have always been one of the most splendid pieces of architecture to me; these towering figures effortlessly handle countless vehicles weighing tons, and humans somehow learned how to do that? It's incredible. I tell this to my friends every time we go on some trips here in Japan (god bless this country is full of these) and they try to stay amused for my sake, but I can see it that their thoughts lie elsewhere. Maybe I'm just a nerd. But I think bridges are cool. So are rockets. Humans built all that. 43 | 44 | 45 | 46 | So yeah, I got introduced to the concept of Machine Learning by virtue of a professor at my university when I was a 3rd year student, completely frustrated with myself because I hated my major and had no option to pursue anything related to STEM. This man changed my life. 47 | 48 | 49 | Of course, I was not as driven when it came to getting indulged in AI-related learning as I am now, but I gradually began building an interest in the so-called AI-related field. Things ended up happening when I was a 4th-year student, and I ended up getting a new-grad role in SWE here in Japan. I had 0 experience in software, yet somehow I managed to break into tech. I know I am not revealing some important bits here about what went down, but I believe there was a good mixture of luck as well as just the tenacity of making something happen no matter what to break into tech (not necessarily AI since I knew it was a leap too big to take, although I did not take it out of the equation). 50 | 51 | 52 | I like to think of my progression in terms of a horizontal axis of real numbers between -10 to 10, where I believe -10 was me starting a degree that I clearly was not interested in after failing to be accepted into the program I wanted, -5 was when I found this professor who opened a new door towards the field of AI for me, -3 was when I first got a technical internship purely out of me selling my determination to learn, and finally 0 — the complete resetting of my negative career scale — when I first received a full-time tech role (my current one). In other words, my detours have finally converged, and my journey has finally started. 53 | 54 | 55 | I will not say that I was glad I took this detour, but I am glad that I got to experience it. I am glad that I got lucky. Or maybe I wasn't. Maybe this was always going to be how it was. In any case, it's an exciting time to be alive. 56 | 57 | 58 |
59 |
60 | 61 |
62 | ) 63 | } 64 | 65 | -------------------------------------------------------------------------------- /src/app/about/twitter-image.alt.txt: -------------------------------------------------------------------------------- 1 | My Novice Journey: A Monologue -------------------------------------------------------------------------------- /src/app/about/twitter-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitdotml/website/0dd4528252337303b2cbe7d75f8c727f5d08ae97/src/app/about/twitter-image.png -------------------------------------------------------------------------------- /src/app/blog/README.md: -------------------------------------------------------------------------------- 1 | 2 | ``` 3 | src/app/blog/ 4 | ├── _components/ 5 | │ ├── BlogCard.tsx # Individual blog post card component 6 | │ └── BlogHeader.tsx # Header with breadcrumb and title 7 | ├── _types/ 8 | │ └── blog.ts # TypeScript interfaces for blog data 9 | ├── _data/ 10 | │ └── posts.ts # Blog posts data 11 | └── page.tsx # Main blog listing page 12 | └── [slug]/ # Slug for the blog post 13 | ├── page.tsx # Blog post page 14 | 15 | ``` -------------------------------------------------------------------------------- /src/app/blog/[slug]/page.tsx: -------------------------------------------------------------------------------- 1 | import { notFound } from 'next/navigation' 2 | import { blogPosts } from '../_data/posts' 3 | 4 | type Params = Promise<{ slug: string }> 5 | 6 | // Generate static params for all blog posts 7 | export async function generateStaticParams() { 8 | return blogPosts.map((post) => ({ 9 | slug: post.slug, 10 | })) 11 | } 12 | 13 | export async function generateMetadata({ params }: { params: Params }) { 14 | const { slug } = await params 15 | 16 | return { 17 | title: `${blogPosts.find(post => post.slug === slug)?.title} | sumit.ml`, 18 | openGraph: { 19 | title: `${blogPosts.find(post => post.slug === slug)?.title} | sumit.ml`, 20 | description: `${blogPosts.find(post => post.slug === slug)?.description}`, 21 | images: [ 22 | { 23 | url: `/blog/posts/${slug}/opengraph-image.png`, 24 | width: 1200, 25 | height: 630, 26 | alt: `${blogPosts.find(post => post.slug === slug)?.description}`, 27 | }, 28 | ], 29 | }, 30 | twitter: { 31 | card: "summary_large_image", 32 | title: `${blogPosts.find(post => post.slug === slug)?.title} | sumit.ml`, 33 | description: `${blogPosts.find(post => post.slug === slug)?.description}`, 34 | images: [ 35 | { 36 | url: `/blog/posts/${slug}/twitter-image.png`, 37 | width: 1200, 38 | height: 630, 39 | alt: `${blogPosts.find(post => post.slug === slug)?.description}`, 40 | }, 41 | ], 42 | }, 43 | }; 44 | } 45 | 46 | 47 | export default async function BlogPost({ 48 | params 49 | }: { 50 | params: Params 51 | }) { 52 | const { slug } = await params 53 | 54 | // Find the matching blog post 55 | const post = blogPosts.find(post => post.slug === slug) 56 | 57 | // If no matching post is found, return 404 58 | if (!post) { 59 | notFound() 60 | } 61 | 62 | // Import and render the actual blog post component 63 | const PostComponent = (await import(`../posts/${slug}/page`)).default 64 | return 65 | } 66 | 67 | -------------------------------------------------------------------------------- /src/app/blog/_components/BlogCard.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link" 2 | import { cn } from "@/lib/utils/utils" 3 | import { StackVertical, StackHorizontal } from "@/components/layout/layout-stack/layout-stack" 4 | import Text from "@/components/ui/text/text" 5 | import TextHeading from "@/components/ui/text-heading/text-heading" 6 | import { BlogPost } from "../_types/blog" 7 | 8 | export function BlogCard({ post, isLast }: { post: BlogPost; isLast?: boolean }) { 9 | return ( 10 |
11 | 19 |
20 | 21 | 28 | {post.title} 29 | 30 | 35 | {post.description} 36 | 37 | 38 | 39 | {post.date} 40 | 41 | 42 | 43 | {post.readingTime} 44 | 45 | 46 | 47 |
48 | 49 | {!isLast && ( 50 |
51 | )} 52 |
53 | ) 54 | } -------------------------------------------------------------------------------- /src/app/blog/_components/BlogHeader.tsx: -------------------------------------------------------------------------------- 1 | import { StackVertical } from "@/components/layout/layout-stack/layout-stack" 2 | import Text from "@/components/ui/text/text" 3 | import TextHeading from "@/components/ui/text-heading/text-heading" 4 | import { DynamicBreadcrumb } from "@/components/ui/primitives/breadcrumb" 5 | import { ThemeToggle } from "@/components/ui/theme/theme-toggle" 6 | 7 | export function BlogHeader() { 8 | return ( 9 | 10 | Blog | sumit.ml 11 | 12 |
13 | 19 | 20 |
21 | 22 |
23 | 24 | Blog 25 | 26 | 27 | Thoughts on programming, machine learning, and technology 28 | 29 |
30 |
31 | ) 32 | } -------------------------------------------------------------------------------- /src/app/blog/_data/posts.ts: -------------------------------------------------------------------------------- 1 | import { BlogPost } from "../_types/blog" 2 | 3 | export const blogPosts: BlogPost[] = [ 4 | { 5 | id: 3, 6 | title: "Autograd Logic", 7 | description: "the logic behind how autograd links to optimization through loss minimization", 8 | date: "February 24, 2025", 9 | readingTime: "15 min read", 10 | slug: "autograd-logic" 11 | }, 12 | { 13 | id: 2, 14 | title: "My 2025 Resolution: Beyond the Roadmaps, Beyond the Timelines", 15 | description: "A week of self-reflection on my 2025 plan, and how I plan to elevate my knowledge fabric.", 16 | date: "January 14, 2025", 17 | readingTime: "5 min read", 18 | slug: "my-2025-resolution" 19 | }, 20 | { 21 | id: 1, 22 | title: "Getting Started with Machine Learning", 23 | description: "A comprehensive guide on getting started with machine learning, from math to practical implementation.", 24 | date: "December 25, 2024", 25 | readingTime: "10 min read", 26 | slug: "getting-started-with-machine-learning" 27 | } 28 | ] -------------------------------------------------------------------------------- /src/app/blog/_types/blog.ts: -------------------------------------------------------------------------------- 1 | export interface BlogPost { 2 | id: number; 3 | title: string; 4 | description: string; 5 | date: string; 6 | readingTime: string; 7 | slug: string; 8 | } -------------------------------------------------------------------------------- /src/app/blog/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Metadata } from 'next' 2 | 3 | export const metadata: Metadata = { 4 | title: 'Blog | sumit.ml', 5 | description: 'Thoughts, reflections, and learnings from my journey', 6 | openGraph: { 7 | title: 'Blog | sumit.ml', 8 | description: 'Thoughts, reflections, and learnings from my journey', 9 | type: 'website', 10 | }, 11 | twitter: { 12 | card: 'summary_large_image', 13 | title: 'Blog | sumit.ml', 14 | description: 'Thoughts, reflections, and learnings from my journey', 15 | } 16 | } 17 | 18 | export default function Layout({ 19 | children, 20 | }: { 21 | children: React.ReactNode 22 | }) { 23 | return children 24 | } -------------------------------------------------------------------------------- /src/app/blog/opengraph-image.alt.txt: -------------------------------------------------------------------------------- 1 | Blog | sumit.ml - Thoughts, reflections, and learnings from my journey -------------------------------------------------------------------------------- /src/app/blog/opengraph-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitdotml/website/0dd4528252337303b2cbe7d75f8c727f5d08ae97/src/app/blog/opengraph-image.png -------------------------------------------------------------------------------- /src/app/blog/page.tsx: -------------------------------------------------------------------------------- 1 | import BaseContainer from "@/components/layout/container/base-container" 2 | import { StackVertical } from "@/components/layout/layout-stack/layout-stack" 3 | import { BlogCard } from "./_components/BlogCard" 4 | import { BlogHeader } from "./_components/BlogHeader" 5 | import { blogPosts } from "./_data/posts" 6 | import { SectionFooter } from "@/components/layout/footer/SectionFooter" 7 | import { Metadata } from "next" 8 | 9 | export const metadata: Metadata = { 10 | title: 'Blog | sumit.ml', 11 | description: 'thoughts on machine learning, math, technology, and my journey', 12 | } 13 | 14 | export default function BlogListing() { 15 | return ( 16 | 17 | 18 | 19 | 20 | {blogPosts.map((post, index) => ( 21 | 26 | ))} 27 | 28 | 29 | 30 | 31 | ) 32 | } -------------------------------------------------------------------------------- /src/app/blog/posts/autograd-logic/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Metadata } from 'next' 2 | 3 | export const metadata: Metadata = { 4 | title: 'Autograd Logic | sumit.ml', 5 | description: 'the logic behind how autograd links to optimization through loss minimization', 6 | openGraph: { 7 | title: 'Autograd Logic | sumit.ml', 8 | description: 'the logic behind how autograd links to optimization through loss minimization', 9 | type: 'article', 10 | publishedTime: '2025-02-24T00:00:00.000Z', 11 | }, 12 | twitter: { 13 | card: 'summary_large_image', 14 | title: 'Autograd Logic', 15 | description: 'the logic behind how autograd links to optimization through loss minimization', 16 | } 17 | } 18 | 19 | export default function Layout({ 20 | children, 21 | }: { 22 | children: React.ReactNode 23 | }) { 24 | return children 25 | } -------------------------------------------------------------------------------- /src/app/blog/posts/autograd-logic/opengraph-image.alt.txt: -------------------------------------------------------------------------------- 1 | Autograd Logic | sumit.ml -------------------------------------------------------------------------------- /src/app/blog/posts/autograd-logic/opengraph-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitdotml/website/0dd4528252337303b2cbe7d75f8c727f5d08ae97/src/app/blog/posts/autograd-logic/opengraph-image.png -------------------------------------------------------------------------------- /src/app/blog/posts/autograd-logic/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import Content from './content.mdx' 4 | import { mdxComponents } from '@/lib/mdx/mdx-components' 5 | import BaseContainer from '@/components/layout/container/base-container' 6 | import { StackVertical } from '@/components/layout/layout-stack/layout-stack' 7 | import { DynamicBreadcrumb } from '@/components/ui/primitives/breadcrumb' 8 | import { ThemeToggle } from '@/components/ui/theme/theme-toggle' 9 | import { IndividualPageFooter } from '@/components/layout/footer/IndividualPageFooter' 10 | import TextHeading from '@/components/ui/text-heading/text-heading' 11 | import Text from '@/components/ui/text/text' 12 | 13 | export default function AutogradLogic() { 14 | return ( 15 | <> 16 | 17 | 18 |
19 | 26 | 27 |
28 | 29 |
30 | Autograd Logic 31 | February 24, 2025 | 15 min read 32 | 33 |
34 | 35 |
36 |
37 |
38 |
39 | 40 | 41 | 42 | ) 43 | } -------------------------------------------------------------------------------- /src/app/blog/posts/autograd-logic/twitter-image.alt.txt: -------------------------------------------------------------------------------- 1 | Autograd Logic -------------------------------------------------------------------------------- /src/app/blog/posts/autograd-logic/twitter-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitdotml/website/0dd4528252337303b2cbe7d75f8c727f5d08ae97/src/app/blog/posts/autograd-logic/twitter-image.png -------------------------------------------------------------------------------- /src/app/blog/posts/getting-started-with-machine-learning/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Metadata } from 'next' 2 | 3 | export const metadata: Metadata = { 4 | title: 'Getting Started with Machine Learning | sumit.ml', 5 | description: 'A beginner\'s guide to starting your ML journey', 6 | openGraph: { 7 | title: 'Getting Started with Machine Learning | sumit.ml', 8 | description: 'A beginner\'s guide to starting your ML journey', 9 | type: 'article', 10 | publishedTime: '2025-01-14T00:00:00.000Z', 11 | images: [ 12 | { 13 | url: '/blog/posts/getting-started-with-machine-learning/opengraph-image.png', 14 | width: 1200, 15 | height: 630, 16 | } 17 | ], 18 | }, 19 | twitter: { 20 | card: 'summary_large_image', 21 | title: 'Getting Started with Machine Learning', 22 | description: 'A beginner\'s guide to starting your ML journey', 23 | images: ['/blog/posts/getting-started-with-machine-learning/twitter-image.png'], 24 | } 25 | } 26 | 27 | export default function Layout({ 28 | children, 29 | }: { 30 | children: React.ReactNode 31 | }) { 32 | return children 33 | } -------------------------------------------------------------------------------- /src/app/blog/posts/getting-started-with-machine-learning/opengraph-image.alt.txt: -------------------------------------------------------------------------------- 1 | Getting Started with Machine Learning | sumit.ml -------------------------------------------------------------------------------- /src/app/blog/posts/getting-started-with-machine-learning/opengraph-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitdotml/website/0dd4528252337303b2cbe7d75f8c727f5d08ae97/src/app/blog/posts/getting-started-with-machine-learning/opengraph-image.png -------------------------------------------------------------------------------- /src/app/blog/posts/getting-started-with-machine-learning/section-ids.ts: -------------------------------------------------------------------------------- 1 | export const SECTION_IDS = { 2 | ARTICLE_CONTENT: 'article-content', 3 | MATH: { 4 | MATH: 'math', 5 | COURSERA_MATH_FOR_ML: 'course-math-for-ml', 6 | MATH_ACADEMY: 'math-academy', 7 | LINALG_3B1B: 'linalg-3b1b', 8 | CALCULUS_3B1B: 'calculus-3b1b' 9 | }, 10 | PROGRAMMING: { 11 | PROGRAMMING: 'programming', 12 | PYTORCH_ZERO_TO_MASTERY: 'pytorch-zero-to-mastery', 13 | PYTORCH_OFFICIAL_DOCS: 'pytorch-official-docs', 14 | PYTHON_BASICS: 'python-basics', 15 | PRACTICAL_PYTHON: 'practical-python', 16 | ADVANCED_PYTHON: 'advanced-python' 17 | }, 18 | ML_STUFF: { 19 | NN_3B1B: '3b1b-neural-networks', 20 | ML_HANDS_ON: 'hands-on-ml' 21 | } 22 | } as const; -------------------------------------------------------------------------------- /src/app/blog/posts/getting-started-with-machine-learning/twitter-image.alt.txt: -------------------------------------------------------------------------------- 1 | Getting Started with Machine Learning -------------------------------------------------------------------------------- /src/app/blog/posts/getting-started-with-machine-learning/twitter-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitdotml/website/0dd4528252337303b2cbe7d75f8c727f5d08ae97/src/app/blog/posts/getting-started-with-machine-learning/twitter-image.png -------------------------------------------------------------------------------- /src/app/blog/posts/my-2025-resolution/content.mdx: -------------------------------------------------------------------------------- 1 | Last Monday was a national holiday in Japan due to [成人の日](https://en.wikipedia.org/wiki/Coming_of_Age_Day), so I had 1 extra day off to do some much-needed self-reflection. 2 | 3 | This has been a massive week for me in terms of rearranging my thoughts and strengthening my belief in what I want to do and achieve by the end of 2025. Like always, I did some research and firstly built [a resolution list](https://github.com/sumitdotml/resolution-for-2025). Nothing unusual. 4 | 5 | Something slightly different that I did this time — unlike how I did it for last year's resolution — was to actually reach out to people who have learned the things I want to learn and get their constructive criticisms so that I would ensure I avoided doing things with diminishing returns or things that wouldn't matter as much as some other aspects. A full-time job takes a lot of toll on me, and while I still can dedicate 3-4 hours per day to studying and learning outside of work, this in my opinion is still quite a limited amount of time per day and I wanted to ensure I was wasting as little of it as possible. 6 | 7 | Back to the resolution talk. As you can probably see when you check it out, it's pretty much like a detailed roadmap. I've always followed roadmaps religiously ever since I started seriously learning things during my 4th-year at university, and they haven't gone wrong for me. Something was different here, and it was likely because of what I wanted from myself: efficiency in learning. 8 | 9 | One of my achievements in 2024 was being able to conquer discipline and consistency towards learning. I've always been a passionate learner and I have had, for a long time, a strong confidence in myself — confidence in my strengths and my weaknesses alike. Last year was truly the year I was able to prove to myself that I, in fact, also bear the discipline in consistency & putting in effort; almost every day since mid-August, I dedicated time to getting things done in the morning pre-work & also late in the evening after work. Learning became a second nature to me, so much so that I wouldn't even think about it. I just did it. On the other hand, after I had firm control over my habit, I started getting the feeling of [whether those 3 hours a day would be enough](https://x.com/sumitdotml/status/1851834662202802299). As this one saying by an economist goes: "There is never enough of anything to fully satisfy all those who want it". Used to hear it a lot during my university days. ___Edit while proofreading___: you know what, maybe this quote kind of means something else (lol). Anyway, you probably get what I'm trying to say here, so I won't bother deleting this. 10 | 11 | 12 | Which meant that my next stage here was efficiency: getting more done in less time. And that's pretty much what the people whom I had asked for feedback indicated as well. The "roadmap" I had indicated a more bottom-up approach, which is fine in normal cases but I received clear-cut examples from people who mentioned that they managed to achieve paces that were multiple levels higher by just breaking things down from the top based on concepts rather than conventional roadmaps with assignments and deadlines. [Elliot Arledge](https://x.com/elliotarledge), one of the people whom I'd asked for feedback, took a portion out of my roadmap and shared something that genuinely made me wonder — and I'm saying this unironically — why I wasn't already doing it: 13 | 14 | > _"Doing practice problems by hand works for some, but there's a high chance you will go 10x faster building cool projects. You're allowed to use AI tools to speed this up. No it doesn't count as cheating."_ 15 | 16 | This was an interesting outlook for me. I've tended to first try to get the theory down (let's say I learn the definition, theory, etc. like the ML course by Andrew Ng), followed by a mini project or just playing around with code to get my hands dirty. And as I feel confident enough, I move on to some other topic. So, it's pretty much been an approach that builds up mini concepts one by one. Since I've been thinking of ways to up my pace of learning anyway, I've decided, after a week of self-reflection, that I want to try it this way and see how it goes for me. 17 | 18 | Words are cheap, however, so I need to first prove to myself that I am, indeed, doing it properly over the next few months. 19 | 20 | So this means my 2025 resolution list is basically already obsolete. But that's quite exciting. 21 | 22 | Which means? I am going to concurrently juggle Python, Math, and traditional ML first; I need to finish the Math for ML course on Math Academy, get myself more comfortable with Python + traditional ML, and then hop on to building project pipelines. 23 | 24 | This all pretty much connects with the advice that I'd received from [Karpathy](https://x.com/karpathy) as well: 25 | 26 | > _"go go go and count the hours and iterate. Pick up projects, complete them, publish them, write about them, repeat gl"_ 27 | 28 | 2024 was my year of discipline and preliminaries. 2025 is the year where there will be multiple echelons of elevations in my knowledge fabric. Watch this space. 29 | 30 |
31 | --- 32 | 33 | ### Resources 34 | 35 | 1. I found a really nice video on YouTube that reflects on 1 year of constant learning and how it was a mistake to not reinforce the concepts through projects. Pretty much the same takeaway as this blog. You can refer to it [here](https://www.youtube.com/watch?v=dk3dQf7yZFI). 36 | 37 | 2. I made a project-based learning repository on GitHub where I am planning to document all my projects. [This](https://github.com/sumitdotml/ml-deepdive) is the link. 38 | 39 | 40 | 3. "How to become an expert" by Karpathy: 41 | 42 | ![Karpathy's tweet](/blog/my-2025-resolution/karpathy-tweet.png) 43 | 44 | _Screenshot taken from Andrej Karpathy's tweet made on Nov 8, 2020. [Link](https://x.com/karpathy/status/1325154823856033793)._ 45 | -------------------------------------------------------------------------------- /src/app/blog/posts/my-2025-resolution/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Metadata } from 'next' 2 | 3 | export const metadata: Metadata = { 4 | title: 'My 2025 Resolution: Beyond the Roadmaps | sumit.ml', 5 | description: 'Beyond the Roadmaps, Beyond the Timelines - A reflection on learning efficiency', 6 | openGraph: { 7 | title: 'My 2025 Resolution: Beyond the Roadmaps | sumit.ml', 8 | description: 'Beyond the Roadmaps, Beyond the Timelines - A reflection on learning efficiency', 9 | type: 'article', 10 | publishedTime: '2025-01-14T00:00:00.000Z', 11 | }, 12 | twitter: { 13 | card: 'summary_large_image', 14 | title: 'My 2025 Resolution: Beyond the Roadmaps, Beyond the Timelines', 15 | description: 'A reflection on learning efficiency', 16 | } 17 | } 18 | 19 | export default function Layout({ 20 | children, 21 | }: { 22 | children: React.ReactNode 23 | }) { 24 | return children 25 | } -------------------------------------------------------------------------------- /src/app/blog/posts/my-2025-resolution/opengraph-image.alt.txt: -------------------------------------------------------------------------------- 1 | My 2025 Resolution: Beyond the Roadmaps, Beyond the Timelines | sumit.ml -------------------------------------------------------------------------------- /src/app/blog/posts/my-2025-resolution/opengraph-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitdotml/website/0dd4528252337303b2cbe7d75f8c727f5d08ae97/src/app/blog/posts/my-2025-resolution/opengraph-image.png -------------------------------------------------------------------------------- /src/app/blog/posts/my-2025-resolution/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import Content from './content.mdx' 4 | import { mdxComponents } from '@/lib/mdx/mdx-components' 5 | import BaseContainer from '@/components/layout/container/base-container' 6 | import { StackVertical } from '@/components/layout/layout-stack/layout-stack' 7 | import { DynamicBreadcrumb } from '@/components/ui/primitives/breadcrumb' 8 | import { ThemeToggle } from '@/components/ui/theme/theme-toggle' 9 | import { IndividualPageFooter } from '@/components/layout/footer/IndividualPageFooter' 10 | import TextHeading from '@/components/ui/text-heading/text-heading' 11 | import Text from '@/components/ui/text/text' 12 | 13 | export default function MySelfReflectionFor2025() { 14 | return ( 15 | <> 16 | 17 | 18 |
19 | 26 | 27 |
28 | 29 |
30 | My 2025 Resolution: Beyond the Roadmaps, Beyond the Timelines 31 | January 14, 2025 | 5 min read 32 | 33 |
34 | 35 |
36 |
37 |
38 |
39 | 40 | 41 | 42 | ) 43 | } -------------------------------------------------------------------------------- /src/app/blog/posts/my-2025-resolution/twitter-image.alt.txt: -------------------------------------------------------------------------------- 1 | My 2025 Resolution: Beyond the Roadmaps, Beyond the Timelines -------------------------------------------------------------------------------- /src/app/blog/posts/my-2025-resolution/twitter-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitdotml/website/0dd4528252337303b2cbe7d75f8c727f5d08ae97/src/app/blog/posts/my-2025-resolution/twitter-image.png -------------------------------------------------------------------------------- /src/app/blog/twitter-image.alt.txt: -------------------------------------------------------------------------------- 1 | Blog | sumit.ml -------------------------------------------------------------------------------- /src/app/blog/twitter-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitdotml/website/0dd4528252337303b2cbe7d75f8c727f5d08ae97/src/app/blog/twitter-image.png -------------------------------------------------------------------------------- /src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitdotml/website/0dd4528252337303b2cbe7d75f8c727f5d08ae97/src/app/favicon.ico -------------------------------------------------------------------------------- /src/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @layer base { 6 | :root { 7 | --background: 0 0% 100%; 8 | --foreground: 240 10% 3.9%; 9 | 10 | --card: 0 0% 100%; 11 | --card-foreground: 240 10% 3.9%; 12 | 13 | --popover: 0 0% 100%; 14 | --popover-foreground: 240 10% 3.9%; 15 | 16 | --primary: 240 5.9% 10%; 17 | --primary-foreground: 0 0% 98%; 18 | 19 | --secondary: 240 4.8% 95.9%; 20 | --secondary-foreground: 240 5.9% 10%; 21 | 22 | --muted: 240 4.8% 95.9%; 23 | --muted-foreground: 240 3.8% 46.1%; 24 | 25 | --accent: 240 4.8% 95.9%; 26 | --accent-foreground: 240 5.9% 10%; 27 | 28 | --destructive: 0 84.2% 60.2%; 29 | --destructive-foreground: 0 0% 98%; 30 | 31 | --border: 240 5.9% 90%; 32 | --input: 240 5.9% 90%; 33 | --ring: 240 5.9% 10%; 34 | 35 | --radius: 0.5rem; 36 | } 37 | 38 | .dark { 39 | --background: 222 47% 5%; 40 | --foreground: 210 20% 85%; 41 | 42 | --card: 222 47% 5%; 43 | --card-foreground: 210 20% 85%; 44 | 45 | --popover: 222 47% 5%; 46 | --popover-foreground: 210 20% 85%; 47 | 48 | --primary: 210 20% 85%; 49 | --primary-foreground: 222 47% 5%; 50 | 51 | --secondary: 217 32% 17%; 52 | --secondary-foreground: 210 20% 85%; 53 | 54 | --muted: 217 32% 17%; 55 | --muted-foreground: 215 16% 70%; 56 | 57 | --accent: 217 32% 17%; 58 | --accent-foreground: 210 20% 85%; 59 | 60 | --destructive: 0 62.8% 30.6%; 61 | --destructive-foreground: 210 20% 85%; 62 | 63 | --border: 217 32% 17%; 64 | --input: 217 32% 17%; 65 | --ring: 212.7 26.8% 83.9%; 66 | } 67 | } 68 | 69 | @layer base { 70 | * { 71 | @apply border-border; 72 | } 73 | body { 74 | @apply bg-background text-foreground; 75 | } 76 | } 77 | 78 | -------------------------------------------------------------------------------- /src/app/homepage/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import BaseContainer from "@/components/layout/container/base-container" 4 | import { StackVertical } from "@/components/layout/layout-stack/layout-stack" 5 | import { HomepageFooter } from "@/components/layout/footer/HomepageFooter" 6 | import { HeroSection } from "@/components/blocks/homepage/HeroSection" 7 | import { CurrentWork } from "@/components/blocks/homepage/CurrentWork" 8 | import { Navbar } from "@/components/ui/navbar/Navbar" 9 | import { ThemeToggle } from "@/components/ui/theme/theme-toggle" 10 | import { HomepageSocials } from "@/components/blocks/homepage/HomepageSocials" 11 | 12 | export default function Homepage() { 13 | return ( 14 | <> 15 | 16 |
17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import './globals.css' 2 | import type { Metadata } from 'next' 3 | import { ThemeProvider } from '@/components/ui/theme/theme-provider' 4 | import { cn } from '@/lib/utils/utils' 5 | import { Analytics } from "@vercel/analytics/react" 6 | import { monoFont, sansFont, codeFont } from '@/styles/fonts/fonts' 7 | 8 | export const metadata: Metadata = { 9 | title: 'sumit.ml', 10 | description: 'a site where I document my ML learning journey & share my thoughts', 11 | } 12 | 13 | export default function RootLayout({ 14 | children, 15 | }: { 16 | children: React.ReactNode 17 | }) { 18 | return ( 19 | 25 | 28 | 34 |
35 |
36 |
37 | {children} 38 | 39 |
40 |
41 |
42 |
43 | 44 | 45 | ) 46 | } 47 | 48 | -------------------------------------------------------------------------------- /src/app/learning/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Metadata } from 'next' 2 | 3 | export const metadata: Metadata = { 4 | title: 'Learning | sumit.ml', 5 | description: 'My journey of learning ML and Math, documented week by week', 6 | openGraph: { 7 | title: 'Learning | sumit.ml', 8 | description: 'My journey of learning ML and Math, documented week by week', 9 | type: 'website', 10 | images: [ 11 | { 12 | url: '/learning/opengraph-image.png', 13 | width: 1200, 14 | height: 630, 15 | } 16 | ], 17 | }, 18 | twitter: { 19 | card: 'summary_large_image', 20 | title: 'Learning | sumit.ml', 21 | description: 'My journey of learning ML and Math, documented week by week', 22 | images: ['/learning/twitter-image.png'], 23 | } 24 | } 25 | 26 | export default function Layout({ 27 | children, 28 | }: { 29 | children: React.ReactNode 30 | }) { 31 | return children 32 | } -------------------------------------------------------------------------------- /src/app/learning/learning-utensils/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Metadata } from 'next' 2 | 3 | export const metadata: Metadata = { 4 | title: 'Learning Utensils | sumit.ml', 5 | description: 'Tools, resources, and materials I use in my learning journey', 6 | openGraph: { 7 | title: 'Learning Utensils | sumit.ml', 8 | description: 'Tools, resources, and materials I use in my learning journey', 9 | type: 'website', 10 | }, 11 | twitter: { 12 | card: 'summary_large_image', 13 | title: 'Learning Utensils | sumit.ml', 14 | description: 'Tools, resources, and materials I use in my learning journey', 15 | } 16 | } 17 | 18 | export default function Layout({ 19 | children, 20 | }: { 21 | children: React.ReactNode 22 | }) { 23 | return children 24 | } -------------------------------------------------------------------------------- /src/app/learning/learning-utensils/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import BaseContainer from "@/components/layout/container/base-container" 4 | import { StackVertical } from "@/components/layout/layout-stack/layout-stack" 5 | import TextHeading from "@/components/ui/text-heading/text-heading" 6 | import Text from "@/components/ui/text/text" 7 | import { DynamicBreadcrumb } from "@/components/ui/primitives/breadcrumb" 8 | import { ThemeToggle } from "@/components/ui/theme/theme-toggle" 9 | import { IndividualPageFooter } from "@/components/layout/footer/IndividualPageFooter" 10 | import Link from "next/link" 11 | 12 | export default function LearningUtensils() { 13 | return ( 14 | 15 | 16 | {/* Breadcrumb */} 17 |
18 | 25 | 26 |
27 | 28 | {/* Header Content */} 29 |
30 | 31 | Learning Utensils 32 | 33 | 34 | All my learning utensils for people that might be interested (idk why you'd be interested but here you go) 35 | 36 | 37 | 38 | Keyboard: Nuphy Air75 V2 39 | Notebook (physical): Normal notebook from Muji Japan 40 | Pen: 0.5 black ink ballpoint pen from Muji Japan (same store as above) 41 | Monitor: Dell U2520DR 42 | Math website I use: Math Academy 43 | 44 | 45 |
46 | 47 |
48 | 49 | 50 | 51 |
52 | ) 53 | } -------------------------------------------------------------------------------- /src/app/learning/opengraph-image.alt.txt: -------------------------------------------------------------------------------- 1 | My journey of learning ML and Math, documented week by week | sumit.ml -------------------------------------------------------------------------------- /src/app/learning/opengraph-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitdotml/website/0dd4528252337303b2cbe7d75f8c727f5d08ae97/src/app/learning/opengraph-image.png -------------------------------------------------------------------------------- /src/app/learning/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import BaseContainer from "@/components/layout/container/base-container" 4 | import { StackVertical } from "@/components/layout/layout-stack/layout-stack" 5 | import TextHeading from "@/components/ui/text-heading/text-heading" 6 | import { SectionFooter } from "@/components/layout/footer/SectionFooter" 7 | import Text from "@/components/ui/text/text" 8 | import { DynamicBreadcrumb } from "@/components/ui/primitives/breadcrumb" 9 | import { ThemeToggle } from "@/components/ui/theme/theme-toggle" 10 | import Link from "next/link" 11 | 12 | export default function Learning() { 13 | return ( 14 | 15 | 16 |
17 | 23 | 24 |
25 | 26 |
27 | 28 | Learning 29 | 30 | 31 | A collection of my learning: weekly reflections, materials I use, and more. 32 | 33 | 34 | 35 | 39 | 43 | Weekly Reflections 44 | 45 | 46 | 50 | 54 | Learning Utensils 55 | 56 | 57 | 58 |
59 |
60 | 61 |
62 | ) 63 | } -------------------------------------------------------------------------------- /src/app/learning/twitter-image.alt.txt: -------------------------------------------------------------------------------- 1 | Learning | sumit.ml -------------------------------------------------------------------------------- /src/app/learning/twitter-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitdotml/website/0dd4528252337303b2cbe7d75f8c727f5d08ae97/src/app/learning/twitter-image.png -------------------------------------------------------------------------------- /src/app/learning/weekly-reflections/README.md: -------------------------------------------------------------------------------- 1 | # Weekly Reflections - Dynamic System 2 | 3 | This directory contains a dynamic system for weekly reflections. This approach allows me to easily add new weekly reflections without having to create and copy multiple files each time. 4 | 5 | ## Adding a New Weekly Reflection 6 | 7 | ### 1. Create an MDX file 8 | 9 | Create a new MDX file in the `content` directory with the name format `week-X.mdx`: 10 | 11 | ```bash 12 | touch src/app/learning/weekly-reflections/content/week-X.mdx 13 | ``` 14 | 15 | Where `X` is the week number (e.g., `week-9.mdx`). 16 | 17 | ### 2. Add Content to the MDX File 18 | 19 | Then I can add content to the MDX file. I can use the following template: 20 | 21 | ```md 22 | # Week X, 2025 (Month Day - Month Day) 23 | 24 | My content goes here. 25 | ``` 26 | 27 | ### 3. Update the `weeks.ts` File 28 | 29 | I can update the `weeks.ts` file with either: 30 | 31 | #### Option A: Manually update weeks.ts 32 | 33 | This adds a new entry at the top of the `weeks` array: 34 | 35 | ```typescript 36 | { 37 | title: 'Week X, 2025 (Month Day - Month Day)', 38 | href: '/learning/weekly-reflections/week-X', 39 | date: new Date('YYYY-MM-DD') // End date of the week 40 | }, 41 | ``` 42 | 43 | #### Option B: Automatically update weeks.ts (Recommended) 44 | 45 | I can run the update script with one of these commands: 46 | 47 | ```bash 48 | # JavaScript version (easier) 49 | node src/app/learning/weekly-reflections/scripts/update-weeks.js 50 | 51 | # TypeScript version (alternative) 52 | npx tsx src/app/learning/weekly-reflections/scripts/update-weeks.ts 53 | ``` 54 | 55 | This script will: 56 | 1. Scan the `content` directory for all MDX files 57 | 2. Extract titles and date information from each file 58 | 3. Automatically update the `weeks.ts` file 59 | 60 | ## How It Works 61 | 62 | The system uses Next.js dynamic routes to generate pages for each week. The `[week]` directory contains the dynamic route handler that: 63 | 64 | 1. Loads the appropriate MDX content 65 | 2. Generates metadata 66 | 3. Renders the content directly with my site's MDX components 67 | 68 | This approach maintains my existing site structure and appearance while reducing repetitive work. 69 | 70 | ## Content Organization 71 | 72 | All my weekly reflection content is stored in individual MDX files in the `content` directory: 73 | 74 | - `content/week-1.mdx` 75 | - `content/week-2.mdx` 76 | - `content/week-3.mdx` 77 | - and so on... 78 | 79 | The URLs for the weekly reflections remain the same (e.g., `/learning/weekly-reflections/week-1`), but they now point to the new dynamic system. 80 | -------------------------------------------------------------------------------- /src/app/learning/weekly-reflections/[week]/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Metadata } from 'next' 2 | import { weeks } from '../_data/weeks' 3 | 4 | // Define the params type for the layout 5 | interface LayoutParams { 6 | params: Promise<{ 7 | week: string; 8 | }>; 9 | children: React.ReactNode; 10 | } 11 | 12 | // Helper to format date range for a given week number 13 | function getDateRangeForWeek(weekNum: number) { 14 | // Find the week in the weeks array 15 | const weekData = weeks.find(w => w.href.includes(`week-${weekNum}`)) 16 | if (weekData) { 17 | // Extract the date range from the title 18 | const dateMatch = weekData.title.match(/\((.*?)\)/) 19 | return dateMatch ? dateMatch[1] : 'Unknown date range' 20 | } 21 | return 'Unknown date range' 22 | } 23 | 24 | export async function generateMetadata({ params }: LayoutParams): Promise { 25 | // Await the params since it's a Promise in Next.js 15 26 | const resolvedParams = await params; 27 | const weekParam = resolvedParams.week as string; 28 | const weekNumber = parseInt(weekParam.replace('week-', '')) 29 | const dateRange = getDateRangeForWeek(weekNumber) 30 | 31 | return { 32 | title: `Week ${weekNumber}, 2025 | Weekly Reflections | sumit.ml`, 33 | description: `My learning journey and reflections from Week ${weekNumber} (${dateRange})`, 34 | openGraph: { 35 | title: `Week ${weekNumber}, 2025 | Weekly Reflections | sumit.ml`, 36 | description: `My learning journey and reflections from Week ${weekNumber} (${dateRange})`, 37 | type: 'article', 38 | publishedTime: new Date().toISOString(), 39 | }, 40 | twitter: { 41 | card: 'summary_large_image', 42 | title: `Week ${weekNumber}, 2025 | Weekly Reflections`, 43 | description: `My learning journey and reflections from Week ${weekNumber} (${dateRange})`, 44 | } 45 | } 46 | } 47 | 48 | export default function Layout({ children }: { children: React.ReactNode }) { 49 | return children 50 | } -------------------------------------------------------------------------------- /src/app/learning/weekly-reflections/[week]/page.tsx: -------------------------------------------------------------------------------- 1 | import fs from 'fs' 2 | import path from 'path' 3 | import { Metadata } from 'next' 4 | import WeekPage from './week-page' 5 | import matter from 'gray-matter' 6 | 7 | // Define page props interface 8 | interface PageParams { 9 | params: Promise<{ 10 | week: string; 11 | }>; 12 | searchParams?: Promise<{ 13 | week?: string; 14 | }>; 15 | } 16 | 17 | export async function generateMetadata({ params, searchParams }: PageParams): Promise { 18 | // Await params since it's a Promise in Next.js 15 19 | const resolvedParams = await params; 20 | const resolvedSearchParams = searchParams ? await searchParams : undefined; 21 | 22 | const weekParam = resolvedSearchParams?.week || resolvedParams.week as string; 23 | const weekNumber = parseInt(weekParam.replace('week-', ''), 10) 24 | 25 | // Read the MDX file to get the year 26 | const contentPath = path.join(process.cwd(), 'src/app/learning/weekly-reflections/content', `${weekParam}.mdx`) 27 | const content = fs.readFileSync(contentPath, 'utf8') 28 | const { content: mdxContent } = matter(content) 29 | 30 | // Extract year from the content 31 | const titleMatch = mdxContent.match(/# Week \d+, (\d{4})/) 32 | const year = titleMatch ? titleMatch[1] : new Date().getFullYear() 33 | 34 | const title = `Week ${weekNumber}, ${year} | Weekly Reflections` 35 | const description = `My learning journey and reflections from Week ${weekNumber}, ${year}` 36 | const url = `https://sumit.ml/learning/weekly-reflections/week-${weekNumber}` 37 | 38 | return { 39 | title, 40 | description, 41 | openGraph: { 42 | title: `Week ${weekNumber}, ${year} | Weekly Reflections | sumit.ml`, 43 | description, 44 | type: 'article', 45 | url 46 | }, 47 | twitter: { 48 | card: 'summary_large_image', 49 | title: `Week ${weekNumber}, ${year} | Weekly Reflections`, 50 | description, 51 | site: '@sumitdotml', 52 | creator: '@sumitdotml' 53 | } 54 | } 55 | } 56 | 57 | export async function generateStaticParams() { 58 | const contentDir = path.join(process.cwd(), 'src/app/learning/weekly-reflections/content') 59 | 60 | return fs.existsSync(contentDir) 61 | ? fs.readdirSync(contentDir) 62 | .filter(file => file.endsWith('.mdx')) 63 | .map(file => ({ week: file.replace('.mdx', '') })) 64 | : [] 65 | } 66 | 67 | export default async function Page({ params, searchParams }: PageParams) { 68 | // Await params since it's a Promise in Next.js 15 69 | const resolvedParams = await params; 70 | const resolvedSearchParams = searchParams ? await searchParams : undefined; 71 | 72 | const weekParam = resolvedSearchParams?.week || resolvedParams.week as string; 73 | return 74 | } -------------------------------------------------------------------------------- /src/app/learning/weekly-reflections/[week]/week-page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { mdxComponents } from '@/lib/mdx/mdx-components' 4 | import BaseContainer from "@/components/layout/container/base-container" 5 | import { StackVertical } from "@/components/layout/layout-stack/layout-stack" 6 | import { DynamicBreadcrumb } from "@/components/ui/primitives/breadcrumb" 7 | import { ThemeToggle } from "@/components/ui/theme/theme-toggle" 8 | import { IndividualPageFooter } from "@/components/layout/footer/IndividualPageFooter" 9 | import { useMemo } from 'react' 10 | import dynamic from 'next/dynamic' 11 | import { monoFont } from '@/styles/fonts/fonts' 12 | 13 | interface WeekPageProps { 14 | weekParam: string 15 | } 16 | 17 | export default function WeekPage({ weekParam }: WeekPageProps) { 18 | const weekNumber = weekParam.replace('week-', '') 19 | 20 | const Content = useMemo(() => { 21 | return dynamic( 22 | () => import(`../content/${weekParam}.mdx`).then(mod => { 23 | const Component = mod.default 24 | return (props: any) => 25 | }), 26 | { 27 | loading: () =>

Loading...

, 28 | ssr: true 29 | } 30 | ) 31 | }, [weekParam]) 32 | 33 | return ( 34 | 35 | 36 |
37 | 45 | 46 |
47 | 48 |
49 | 50 |
51 |
52 | 53 | 54 |
55 | ) 56 | } -------------------------------------------------------------------------------- /src/app/learning/weekly-reflections/_data/weeks.ts: -------------------------------------------------------------------------------- 1 | interface Week { 2 | title: string; 3 | href: string; 4 | date: Date; 5 | } 6 | 7 | interface MonthGroup { 8 | month: string; 9 | weeks: Week[]; 10 | } 11 | 12 | const weeks: Week[] = [ 13 | { 14 | title: "Week 24, 2026 (June 9 - June 15)", 15 | href: "/learning/weekly-reflections/week-24", 16 | date: new Date("2025-06-15T12:00:00.000Z"), 17 | }, 18 | { 19 | title: "Week 23, 2026 (June 2 - June 8)", 20 | href: "/learning/weekly-reflections/week-23", 21 | date: new Date("2025-06-08T12:00:00.000Z"), 22 | }, 23 | { 24 | title: "Week 8, 2025 (Feb 17 - Feb 23)", 25 | href: "/learning/weekly-reflections/week-8", 26 | date: new Date("2025-02-23T12:00:00.000Z"), 27 | }, 28 | { 29 | title: "Week 7, 2025 (Feb 10 - Feb 16)", 30 | href: "/learning/weekly-reflections/week-7", 31 | date: new Date("2025-02-16T12:00:00.000Z"), 32 | }, 33 | { 34 | title: "Week 6, 2025 (Feb 3 - Feb 9)", 35 | href: "/learning/weekly-reflections/week-6", 36 | date: new Date("2025-02-09T12:00:00.000Z"), 37 | }, 38 | { 39 | title: "Week 5, 2025 (Jan 27 - Feb 2)", 40 | href: "/learning/weekly-reflections/week-5", 41 | date: new Date("2025-02-02T12:00:00.000Z"), 42 | }, 43 | { 44 | title: "Week 4, 2025 (Jan 20 - Jan 26)", 45 | href: "/learning/weekly-reflections/week-4", 46 | date: new Date("2025-01-26T12:00:00.000Z"), 47 | }, 48 | { 49 | title: "Week 3, 2025 (Jan 14 - Jan 19)", 50 | href: "/learning/weekly-reflections/week-3", 51 | date: new Date("2025-01-19T12:00:00.000Z"), 52 | }, 53 | { 54 | title: "Week 2, 2025 (Jan 6 - Jan 12)", 55 | href: "/learning/weekly-reflections/week-2", 56 | date: new Date("2025-01-12T12:00:00.000Z"), 57 | }, 58 | { 59 | title: "Week 1, 2025 (Jan 1 - Jan 5)", 60 | href: "/learning/weekly-reflections/week-1", 61 | date: new Date("2025-01-05T12:00:00.000Z"), 62 | }, 63 | ]; 64 | 65 | export function getWeeksByMonth(): MonthGroup[] { 66 | const groupedWeeks = weeks.reduce((acc: { [key: string]: Week[] }, week) => { 67 | const monthYear = week.date.toLocaleString("ja-JP", { 68 | month: "long", 69 | year: "numeric", 70 | }); 71 | if (!acc[monthYear]) { 72 | acc[monthYear] = []; 73 | } 74 | acc[monthYear].push(week); 75 | return acc; 76 | }, {}); 77 | 78 | return Object.entries(groupedWeeks) 79 | .map(([month, weeks]) => ({ 80 | month, 81 | weeks, 82 | })) 83 | .sort((a, b) => { 84 | const [aMonth, aYear] = a.month.split(" "); 85 | const [bMonth, bYear] = b.month.split(" "); 86 | if (aYear !== bYear) return parseInt(bYear) - parseInt(aYear); 87 | return ( 88 | new Date(Date.parse(`${bMonth} 1, 2000`)).getMonth() - 89 | new Date(Date.parse(`${aMonth} 1, 2000`)).getMonth() 90 | ); 91 | }); 92 | } 93 | 94 | export { weeks }; 95 | -------------------------------------------------------------------------------- /src/app/learning/weekly-reflections/content/week-1.mdx: -------------------------------------------------------------------------------- 1 | # Week 1, 2025 (Jan 1 - Jan 5) 2 | 3 | Currently in the middle of my vacation here, will be back to learning in a week. Feels bad :( -------------------------------------------------------------------------------- /src/app/learning/weekly-reflections/content/week-2.mdx: -------------------------------------------------------------------------------- 1 | # Week 2, 2025 (Jan 6 - Jan 12) 2 | 3 | Mildly cheated this week with 8 days instead of 7 since Monday was a national holiday in Japan due to [成人の日](https://en.wikipedia.org/wiki/Coming_of_Age_Day). 4 | 5 | After receiving feedback from experienced learners, I'm moving away from my traditional bottom-up, theory-first approach to a more efficient, project-driven method. 6 | 7 | In other words, instead of overly specific timelines and roadmaps, I'll take a top-down approach by picking up projects, completing them, publishing them, writing about them, and basically going full-throttle at each step, counting the hours, and continuously iterating. 8 | 9 | This week, I've resumed my Math Academy habit and am seriously pursuing Python to accelerate my journey to project pipelines. My 2025 resolution list is now obsolete, but this change is exciting rather than discouraging. 10 | 11 | --- 12 | 13 | ### Updated 2025 Plan 14 | 15 | #### Concurrent focus on Python, Math, and traditional ML to start things off 16 | 17 | - Complete Math for ML course on Math Academy 18 | - Build Python proficiency for practical implementation 19 | 20 | #### Transition to building project pipelines 21 | 22 | - Implement top-down, concept-based learning approach 23 | - Prove the effectiveness of this new method through consistent application 24 | 25 | --- 26 | Words are cheap, however, so I need to prove this approach works over the next few months. Watch this space as I elevate my knowledge fabric through this new learning paradigm. 27 | 28 | This is actually a summarized version of the actual reflection I wrote for this week. I decided to move the long-form reflection to the [blog](/blog/my-2025-resolution) since I thought it fit better there. -------------------------------------------------------------------------------- /src/app/learning/weekly-reflections/content/week-23.mdx: -------------------------------------------------------------------------------- 1 | # Week 23, 2025 (Jun 2 - Jun 8) 2 | 3 | Well, my activity on this site has been a rotter for the past few months. It's not that I haven't been doing anything, but I just haven't been documenting it on this site. A lot of things have been happening, but more on them maybe sometime later. For now, let me share what I did this week! 4 | 5 | 6 | 1. Solved 5 [Deep-ML](https://www.deep-ml.com/) problems. These have been pretty fun and also good exercises for my brain. I'm planning to do 1 problem each day from here. 7 | 8 | 2. Made my first open-source contribution :) well, although it wasn't much, it was a nice feeling. I basically submitted a solution to the Deep-ML repository. Hasn't been accepted yet, but I did what I could, so it's all good. 9 | 10 | 3. Gotten quite faimilar with RNNs and ConvNets. These were my main focus over the past week or so. I've written some (crude) code snippets on [this](https://github.com/sumitdotml/deep-learning) GitHub repo. 11 | 12 | 4. Also learned some C++! I've really wanted to start learning this language for quite a while, and over the last week, I finally made some fundamental strides. I've done a bit of the usual stuff (like cin, cout, vector, how compiling works, separating modules and headers, and so on). I plan to do a little bit of this every week as well. Maybe I should also try solving the Deep-ML problems in C++ once I do that in Python (maybe). Should be fun! 13 | 14 | 5. Also, my 2nd week in a row of using solely neovim for everything! Even now, this is currently being written on my mac mini's website directory through a ssh connection from my other macbook :) so much fun to be able to control my mac mini remotely haha (I learned how to do this this week as well!) 15 | 16 | I think this is the gist of it for this week. Will be documenting my learning on this site regularly from here onwards :) will also start writing a lot more blogs; can't be slacking off too much!!! 17 | 18 | See you soon! 19 | -------------------------------------------------------------------------------- /src/app/learning/weekly-reflections/content/week-24.mdx: -------------------------------------------------------------------------------- 1 | import CodeBlock from "@/components/blocks/code-block/code-block"; 2 | import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from "@/components/ui/accordion/accordion"; 3 | import Ruler from "@/components/ui/ruler/ruler"; 4 | 5 | # Week 24, 2025 (Jun 9 - Jun 15) 6 | 7 | So, this week has been pretty busy for me in terms of work, and it brings no joy in admitting this but I had to do plenty of overtime work because of the current status of my team's project. I was handed out the biggest task I have ever been since I started working here, and it's been quite exciting but -- given the scale -- also quite challenging. 8 | 9 | One takeaway from this: I love programming, but I despise writing tests. 10 | 11 | For my weekly learning, I did try what I could, but personally, I think this has been an underwhelming one. Here's what I can all think of: 12 | 13 | - I've been trying to code a simple transformer using pure [Tinygrad](https://github.com/tinygrad/tinygrad). I have gotten into this habit lately of watching George Hotz streams and the way he programs, and I've kinda wanted to contribute to Tinygrad for a bit, so thought this would be a good way to get used to the library. Read some docs, watched some streams. Haven't completed writing the transformer yet ([current progress](https://github.com/sumitdotml/transformer-with-tinygrad/)), but should be done soon. Frankly, think I've been a bit lazy. Not good enough. 14 | 15 | - Solved 2 [Deep-ML](https://www.deep-ml.com/) problems. Been very fun, but I was supposed to do one each day... not good enough. 16 | 17 | - Studied KV Cache via the latest KV Cache pull request I saw in the [nanoVLM](https://github.com/huggingface/nanoVLM) repository. They're doing pretty good out there. Their [KV Cache blog](https://huggingface.co/blog/kv-cache) is pretty nice. 18 | 19 | - Coded a tic-tac-toe game in C++. This... does not sound very impressive but well, it did take me a little bit to craft the storing & pattern matching logic in this language. Was super fun. 20 | 21 | ... and that's pretty much it. 22 | 23 | I saw that Sebastian Raschka dropped a new Substack post about coding KV Cache from scratch, so I'll do that this upcoming week. And among other things. See you next week! 24 | 25 | 26 | 27 | 28 | 29 | Tic-tac-toe code if you wanna peek 30 | 31 |

32 | `ttt-functions.h` 33 |

34 | 35 | #include 36 | 37 | bool check_for_win(std::vector> X); 38 | void draw_board(std::vector> board); 39 | `} language="cpp" className="w-full" /> 40 |
41 | 42 |

43 | `ttt-functions.cpp` 44 |

45 | 46 | #include 47 | 48 | bool check_for_win(std::vector> X) { 49 | // lambda in c++ looks like this 50 | auto same = [](int a, int b, int c) { return (a != 0 && a == b && b == c); }; 51 | 52 | // rows and cols 53 | for (int i = 0; i < 3; i++) { 54 | if (same(X[0][i], X[1][i], X[2][i])) 55 | return true; 56 | if (same(X[i][0], X[i][1], X[i][2])) 57 | return true; 58 | } 59 | // diagonals 60 | if (same(X[0][0], X[1][1], X[2][2])) 61 | return true; 62 | if (same(X[0][2], X[1][1], X[2][0])) 63 | return true; 64 | 65 | return false; 66 | } 67 | 68 | void draw_board(std::vector> board) { 69 | auto mark = [](int v) -> char { 70 | if (v == 1) 71 | return 'O'; 72 | if (v == 2) 73 | return 'X'; 74 | return ' '; 75 | }; 76 | 77 | std::cout << " 1 2 3\n" 78 | << " +---+---+---+\n"; 79 | 80 | for (int r = 0; r < 3; ++r) { 81 | std::cout << r + 1 << " |"; 82 | for (int c = 0; c < 3; ++c) { 83 | std::cout << ' ' << mark(board[r][c]) << " |"; 84 | } 85 | std::cout << "\n +---+---+---+\n"; 86 | } 87 | } 88 | `} language="cpp" className="w-full" /> 89 |
90 | 91 |

92 | `main.cpp` 93 |

94 | 96 | #include 97 | 98 | #include "ttt-functions.h" 99 | 100 | int main(int argc, char *argv[]) { 101 | // std::vector(3, 0) == [0, 0, 0] 102 | // std::vector(3, [0, 0, 0]) == [0, 0, 0] * 3 (a 3x3 matrix, kind of) 103 | std::vector> board(3, std::vector(3, 0)); 104 | int moves = 1; 105 | int A_input, B_input; 106 | 107 | while (moves < 10) { 108 | bool made_move = false; 109 | std::cout << "Move " << moves << "\n"; 110 | 111 | // ========== A ========== 112 | while (!made_move) { 113 | std::cout 114 | << "You are player A. You are assigned 'O'. Choose a position. " 115 | "E.g., 11 for row 1, element 1. 22 for row 2, element 2. 33 for " 116 | "row 3, element 3.\n-> "; 117 | std::cin >> A_input; 118 | 119 | int row = A_input / 10; 120 | int col = A_input % 10; 121 | 122 | if (row < 1 || row > 3 || col < 1 || col > 3) { 123 | std::cout << "Out of range. Try again.\n"; 124 | continue; 125 | } 126 | 127 | if (board[row - 1][col - 1] != 0) { 128 | std::cout << "This square is occupied. Try again.\n"; 129 | continue; 130 | } 131 | board[row - 1][col - 1] = 1; 132 | draw_board(board); 133 | if (check_for_win(board)) { 134 | std::cout << "A is the winner!\n"; 135 | return 0; 136 | } 137 | if (moves == 9) { 138 | std::cout << "It's a draw!\n"; 139 | return 0; 140 | } 141 | made_move = true; 142 | ++moves; 143 | } 144 | 145 | made_move = false; // Reset for player B 146 | 147 | // ========== B ========== 148 | while (!made_move) { 149 | std::cout 150 | << "You are player B. You are assigned 'X'. Choose a position. " 151 | "E.g., 11 for row 1, element 1. 22 for row 2, element 2. 33 for " 152 | "row 3, element 3:\n-> "; 153 | std::cin >> B_input; 154 | 155 | int row = B_input / 10; 156 | int col = B_input % 10; 157 | 158 | if (row < 1 || row > 3 || col < 1 || col > 3) { 159 | std::cout << "Out of range. Try again." << std::endl; 160 | continue; 161 | } 162 | 163 | if (board[row - 1][col - 1] != 0) { 164 | std::cout << "This square is occupied. Try again." << std::endl; 165 | continue; 166 | } 167 | board[row - 1][col - 1] = 2; 168 | draw_board(board); 169 | if (check_for_win(board)) { 170 | std::cout << "B is the winner!" << std::endl; 171 | return 0; 172 | } 173 | made_move = true; 174 | ++moves; 175 | } 176 | } 177 | return 0; 178 | } 179 | `} language="cpp" className="w-full" /> 180 |
181 |
182 |
-------------------------------------------------------------------------------- /src/app/learning/weekly-reflections/content/week-3.mdx: -------------------------------------------------------------------------------- 1 | # Week 3, 2025 (Jan 14 - Jan 19) 2 | 3 | A 6-day week since this week started on Tuesday. 4 | 5 | I started seriously pursuing Python and PyTorch this week. Unfortunately, I could not get a lot of math done and it kind of sucks that it's becoming quite difficult for me to resume my previous habit of doing math daily. In my defense though, however, this is largely because of me focusing more on Python & PyTorch. More in details below. 6 | 7 | --- 8 | 9 | ### Python & PyTorch 10 | 11 | - Deepened my understanding about the data structures in Python by looking up materials across the web and solving some exercises (particularly the `zip` function) 12 | - Studied the inheritance property of Python classes (particularly `super`) 13 | - Started practicing PyTorch from scratch by building and analyzing some simple models (mlp, linear regression, etc) 14 | - Got to know about `torch.inference_mode()` and its efficiency compared to `torch.no_grad()` during eval 15 | 16 | --- 17 | 18 | ### Math 19 | 20 | - Linear dependence & independence 21 | - Subspaces of n-dimensional space 22 | 23 | --- 24 | 25 | ### Miscellaneous 26 | 27 | - reconfigured my whole site by revamping & repurposing every component (since I wasn't a fan of how everything as structured) 28 | - wrote a __[blog](/blog/my-2025-resolution)__ on my resolution for 2025 29 | 30 | --- 31 | 32 | Yup, this is not a lot and I admit it. I had horrible sleep for 4 consecutive days during the workdays, so I was unable to use my brain for any activity at all :( sucks, really. -------------------------------------------------------------------------------- /src/app/learning/weekly-reflections/content/week-4.mdx: -------------------------------------------------------------------------------- 1 | # Week 4, 2025 (Jan 20 - Jan 26) 2 | 3 | I started doing my first project of 2024 this week. 4 | 5 | For the majority of the week, I mostly focused on rebuilding my habit of doing 1-1.5 hours of math in [Math Academy](https://mathacademy.com), and I succeeded! 6 | 7 | During weekdays, I was able to: 8 | - hit at least 50xp (translates to roughly 1.5 hours of study for me) each day for all days except one 9 | - do a lot of Python and PyTorch practice! Even added a little to my [PyTorch notes](/notes/pytorch). 10 | - talk to at least 3 of my mutuals from twitter and get to know them better. It's an amazing feeling talking to people who know their stuff. 11 | 12 | During the weekend, I did not do a lot of math as I got quite busy with meeting friends and also wasting time here and there. However, I finally managed to create a rough fulcrum for my next few months of learning: **deep learning architecture design and optimization**. I also made a [GitHub repository](https://github.com/sumitdotml/ml-deepdive) to record my project-based learning approach, and I have decided that my first project is going to be [building an autograd engine from scratch](https://github.com/sumitdotml/chibigrad)! This is going to be my main focus from here; I hope to finish this within a week. 13 | 14 | Next week is going to be amazing :) -------------------------------------------------------------------------------- /src/app/learning/weekly-reflections/content/week-5.mdx: -------------------------------------------------------------------------------- 1 | # Week 5, 2025 (Jan 27 - Feb 2) 2 | 3 | So erm, this week was mainly about trying to complete my autograd engine project and a little bit of math. 4 | 5 | ### Autograd Engine Project 6 | 7 | - completed basic parts: a tensor class, arithmetic, power, matmul, dot, MSE, Linear class, and amongst others 8 | - tried to implement the project in pure Python, but got humbled by broadcasting issues. too difficult for a noob like me 9 | - switched to numpy solely because of the broadcasting errors I couldn't resolve by using pure Python, and this, too, gave me a big headache 10 | - finally managed to get the broadcasting to work, but then I hit a wall with the backprop implementation: gradients were not being computed correctly 11 | - ultimately got the backprop to work, now building some tests to verify everything: arithmetic (add, sub, mul, div), power, matmul, dot, MSE, etc. 12 | 13 | Here's the [project repo](https://github.com/sumitdotml/chibigrad) with the latest updates. 14 | 15 | --- 16 | 17 | ### Math 18 | 19 | I did not do too much math this week since I got quite busy banging my head against the wall due to the autograd project. 20 | 21 | But did manage to cross 5000xp in Math Academy! -------------------------------------------------------------------------------- /src/app/learning/weekly-reflections/content/week-6.mdx: -------------------------------------------------------------------------------- 1 | # Week 6, 2025 (Feb 3 - Feb 9) 2 | 3 | I completed my Autograd Engine project this week! (well, sort of) 4 | 5 | Well, I was thinking of what to call it when I first started it, and I ultimately thought it would be a good idea to call it [chibigrad](https://jisho.org/word/%E7%A6%BF%E3%81%B3) since it's a tiny grad engine I built from scratch. 6 | 7 | I did a lot of refactoring for the `Tensor` as well as the `Linear` classes, and also added a simple ReLU activation function. 8 | 9 | I realized how many bugs and errors my project had (especially gradient accumulation, broadcasting, backprop logic, handling of different data types, etc.) because of the tests I had added, and this resulted in me adding a lot more tests to verify the correctness of my project. Thank god for language models since I would not have been able to write all them tests! 10 | 11 | So this week was mostly about refactoring and adding tests. 12 | 13 | The engine works relatively nice, surprisingly, and I am quite happy with the results. 14 | 15 | The repo link is [here](https://github.com/sumitdotml/chibigrad). I yapped quite a bit on this page as you can clearly notice, but you might probably get a better understanding of the project by reading the repo code since it's pretty simple and sweet. 16 | 17 | From here on, I think I will start jumping into more neural network architecture design and optimization projects. -------------------------------------------------------------------------------- /src/app/learning/weekly-reflections/content/week-7.mdx: -------------------------------------------------------------------------------- 1 | # Week 7, 2025 (Feb 10 - Feb 16) 2 | 3 | Could not do much this week due to some personal stuff and also because I was busy with searching for new apartments and getting gassed out. 4 | 5 | Next week might not be very different but I'm hoping all I'll have to worry about is the apartment hunt. That way, I think I will still have enough time to at least do some learning and studying. -------------------------------------------------------------------------------- /src/app/learning/weekly-reflections/content/week-8.mdx: -------------------------------------------------------------------------------- 1 | # Week 8, 2025 (Feb 17 - Feb 23) 2 | 3 | Will update this more properly soon. But I studied a lot of Transformer architecture related stuff. Documenting that in [this repo](https://github.com/sumitdotml/transformer-study). 4 | 5 | Also wrote a quick so-called blog for reflecting what I learned from my [chibigrad](https://github.com/sumitdotml/chibigrad) project. 6 | 7 | You can go to that blog page from [here](/blog/autograd-logic). -------------------------------------------------------------------------------- /src/app/learning/weekly-reflections/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Metadata } from 'next' 2 | 3 | export const metadata: Metadata = { 4 | title: 'Weekly Reflections | sumit.ml', 5 | description: 'Weekly documentation of my learning progress, reflections, and insights', 6 | openGraph: { 7 | title: 'Weekly Reflections | sumit.ml', 8 | description: 'Weekly documentation of my learning progress, reflections, and insights', 9 | type: 'website', 10 | }, 11 | twitter: { 12 | card: 'summary_large_image', 13 | title: 'Weekly Reflections | sumit.ml', 14 | description: 'Weekly documentation of my learning progress, reflections, and insights', 15 | } 16 | } 17 | 18 | export default function Layout({ 19 | children, 20 | }: { 21 | children: React.ReactNode 22 | }) { 23 | return children 24 | } -------------------------------------------------------------------------------- /src/app/learning/weekly-reflections/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import BaseContainer from "@/components/layout/container/base-container"; 4 | import { StackVertical } from "@/components/layout/layout-stack/layout-stack"; 5 | import TextHeading from "@/components/ui/text-heading/text-heading"; 6 | import Text from "@/components/ui/text/text"; 7 | import { DynamicBreadcrumb } from "@/components/ui/primitives/breadcrumb"; 8 | import { ThemeToggle } from "@/components/ui/theme/theme-toggle"; 9 | import { IndividualPageFooter } from "@/components/layout/footer/IndividualPageFooter"; 10 | import { getWeeksByMonth } from "./_data/weeks"; 11 | import Link from "next/link"; 12 | import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion/accordion"; 13 | import { cn } from "@/lib/utils/utils"; 14 | import { monoFont } from "@/styles/fonts/fonts"; 15 | 16 | export default function WeeklyReflections() { 17 | const monthGroups = getWeeksByMonth(); 18 | // Only the most recent month should be open by default 19 | const mostRecentMonth = monthGroups[0]?.month; 20 | 21 | return ( 22 | 23 | 24 |
25 | 32 | 33 |
34 | 35 |
36 | 37 | Weekly Reflections 38 | 39 | 40 | My attempt at documenting, reflecting on, and being grateful for 41 | what I learned each week in my pursuit of knowledge. 42 | 43 | 44 | 49 | {monthGroups.map((group) => ( 50 | 55 | 61 | 70 | {group.month} 71 | 78 | 79 | 80 | 81 |
82 | 83 | {group.weeks.map((week, weekIndex) => ( 84 |
93 | 106 | {week.title} 107 | 108 | {/* Hover indicator */} 109 |
118 |
119 | ))} 120 | 121 |
122 | 123 | 124 | ))} 125 | 126 |
127 | 128 | 129 | 130 | 131 | ); 132 | } -------------------------------------------------------------------------------- /src/app/learning/weekly-reflections/scripts/update-weeks.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This script updates the weeks.ts file based on the content in the content folder 3 | * I can run it with: node src/app/learning/weekly-reflections/scripts/update-weeks.js 4 | */ 5 | 6 | const fs = require('fs'); 7 | const path = require('path'); 8 | const matter = require('gray-matter'); 9 | 10 | const contentDir = path.join(process.cwd(), 'src/app/learning/weekly-reflections/content'); 11 | const weeksFilePath = path.join(process.cwd(), 'src/app/learning/weekly-reflections/_data/weeks.ts'); 12 | 13 | // Read all MDX files from the content directory 14 | const contentFiles = fs.readdirSync(contentDir) 15 | .filter(file => file.endsWith('.mdx')) 16 | .sort((a, b) => { 17 | // Sort by week number in descending order 18 | const weekA = parseInt(a.replace('week-', '').replace('.mdx', '')); 19 | const weekB = parseInt(b.replace('week-', '').replace('.mdx', '')); 20 | return weekB - weekA; 21 | }); 22 | 23 | const weeks = []; 24 | 25 | // Process each file to extract title and date information 26 | contentFiles.forEach(file => { 27 | const filePath = path.join(contentDir, file); 28 | const content = fs.readFileSync(filePath, 'utf8'); 29 | const weekNumber = file.replace('week-', '').replace('.mdx', ''); 30 | 31 | // Extract the title and date range from the MDX frontmatter or content 32 | const { content: mdxContent } = matter(content); 33 | const titleMatch = mdxContent.match(/# Week \d+, \d{4} \((.*?)\)/); 34 | 35 | if (titleMatch) { 36 | const dateRange = titleMatch[1]; 37 | const title = `Week ${weekNumber}, 2025 (${dateRange})`; 38 | const weekPath = `/learning/weekly-reflections/week-${weekNumber}`; 39 | 40 | // Try to extract end date from the date range 41 | const dateMatch = dateRange.match(/(\w+) (\d+)/g); 42 | let endDate = new Date(); 43 | 44 | if (dateMatch && dateMatch.length > 1) { 45 | const lastDate = dateMatch[1]; // e.g., "Feb 16" 46 | const [month, day] = lastDate.split(' '); 47 | 48 | // Convert month to number 49 | const monthMap = { 50 | 'Jan': 0, 'Feb': 1, 'Mar': 2, 'Apr': 3, 'May': 4, 'Jun': 5, 51 | 'Jul': 6, 'Aug': 7, 'Sep': 8, 'Oct': 9, 'Nov': 10, 'Dec': 11 52 | }; 53 | 54 | if (monthMap[month] !== undefined) { 55 | endDate = new Date(2025, monthMap[month], parseInt(day)); 56 | } 57 | } 58 | 59 | weeks.push({ 60 | title, 61 | href: weekPath, 62 | date: endDate 63 | }); 64 | } 65 | }); 66 | 67 | // Generate the updated weeks.ts file content 68 | const fileContent = `interface Week { 69 | title: string; 70 | href: string; 71 | date: Date; 72 | } 73 | 74 | interface MonthGroup { 75 | month: string; 76 | weeks: Week[]; 77 | } 78 | 79 | const weeks: Week[] = [ 80 | ${weeks.map(week => ` { 81 | title: '${week.title}', 82 | href: '${week.href}', 83 | date: new Date('${week.date.toISOString().split('T')[0]}') 84 | }`).join(',\n')} 85 | ] 86 | 87 | export function getWeeksByMonth(): MonthGroup[] { 88 | const groupedWeeks = weeks.reduce((acc: { [key: string]: Week[] }, week) => { 89 | const monthYear = week.date.toLocaleString('en-US', { month: 'long', year: 'numeric' }); 90 | if (!acc[monthYear]) { 91 | acc[monthYear] = []; 92 | } 93 | acc[monthYear].push(week); 94 | return acc; 95 | }, {}); 96 | 97 | return Object.entries(groupedWeeks).map(([month, weeks]) => ({ 98 | month, 99 | weeks 100 | })).sort((a, b) => { 101 | const [aMonth, aYear] = a.month.split(' '); 102 | const [bMonth, bYear] = b.month.split(' '); 103 | if (aYear !== bYear) return parseInt(bYear) - parseInt(aYear); 104 | return new Date(Date.parse(\`\${bMonth} 1, 2000\`)).getMonth() - 105 | new Date(Date.parse(\`\${aMonth} 1, 2000\`)).getMonth(); 106 | }); 107 | } 108 | 109 | export { weeks }; 110 | `; 111 | 112 | // Write the updated content to weeks.ts 113 | fs.writeFileSync(weeksFilePath, fileContent, 'utf8'); 114 | 115 | console.log('Updated weeks.ts file successfully!'); -------------------------------------------------------------------------------- /src/app/learning/weekly-reflections/scripts/update-weeks.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This script updates the weeks.ts file based on the content in the content folder 3 | * I can run it with: npx tsx src/app/learning/weekly-reflections/scripts/update-weeks.ts 4 | */ 5 | 6 | import fs from 'fs'; 7 | import path from 'path'; 8 | import matter from 'gray-matter'; 9 | 10 | interface Week { 11 | title: string; 12 | href: string; 13 | date: Date; 14 | } 15 | 16 | const contentDir = path.join(process.cwd(), 'src/app/learning/weekly-reflections/content'); 17 | const weeksFilePath = path.join(process.cwd(), 'src/app/learning/weekly-reflections/_data/weeks.ts'); 18 | 19 | // Read all MDX files from the content directory 20 | const contentFiles = fs.readdirSync(contentDir) 21 | .filter(file => file.endsWith('.mdx')) 22 | .sort((a, b) => { 23 | // Sort by week number in descending order 24 | const weekA = parseInt(a.replace('week-', '').replace('.mdx', '')); 25 | const weekB = parseInt(b.replace('week-', '').replace('.mdx', '')); 26 | return weekB - weekA; 27 | }); 28 | 29 | const weeks: Week[] = []; 30 | 31 | // Process each file to extract title and date information 32 | contentFiles.forEach(file => { 33 | const filePath = path.join(contentDir, file); 34 | const content = fs.readFileSync(filePath, 'utf8'); 35 | const weekNumber = file.replace('week-', '').replace('.mdx', ''); 36 | 37 | // Extract the title and date range from the MDX frontmatter or content 38 | const { content: mdxContent } = matter(content); 39 | const titleMatch = mdxContent.match(/# Week \d+, \d{4} \((.*?)\)/); 40 | 41 | if (titleMatch) { 42 | const dateRange = titleMatch[1]; 43 | const title = `Week ${weekNumber}, 2025 (${dateRange})`; 44 | const weekPath = `/learning/weekly-reflections/week-${weekNumber}`; 45 | 46 | // Try to extract end date from the date range 47 | const dateMatch = dateRange.match(/(\w+) (\d+)/g); 48 | let endDate = new Date(); 49 | 50 | if (dateMatch && dateMatch.length > 1) { 51 | const lastDate = dateMatch[dateMatch.length - 1]; // Get the last date in the range 52 | const [month, day] = lastDate.split(' '); 53 | 54 | // Convert month to number 55 | const monthMap: {[key: string]: number} = { 56 | 'Jan': 0, 'Feb': 1, 'Mar': 2, 'Apr': 3, 'May': 4, 'Jun': 5, 57 | 'Jul': 6, 'Aug': 7, 'Sep': 8, 'Oct': 9, 'Nov': 10, 'Dec': 11 58 | }; 59 | 60 | if (monthMap[month] !== undefined) { 61 | // Set the time to noon to avoid timezone issues 62 | endDate = new Date(2025, monthMap[month], parseInt(day), 12, 0, 0); 63 | } 64 | } 65 | 66 | weeks.push({ 67 | title, 68 | href: weekPath, 69 | date: endDate 70 | }); 71 | } 72 | }); 73 | 74 | // Generate the updated weeks.ts file content 75 | const fileContent = `interface Week { 76 | title: string; 77 | href: string; 78 | date: Date; 79 | } 80 | 81 | interface MonthGroup { 82 | month: string; 83 | weeks: Week[]; 84 | } 85 | 86 | const weeks: Week[] = [ 87 | ${weeks.map(week => ` { 88 | title: '${week.title}', 89 | href: '${week.href}', 90 | date: new Date('${week.date.getFullYear()}-${String(week.date.getMonth() + 1).padStart(2, '0')}-${String(week.date.getDate()).padStart(2, '0')}T12:00:00.000Z') 91 | }`).join(',\n')} 92 | ] 93 | 94 | export function getWeeksByMonth(): MonthGroup[] { 95 | const groupedWeeks = weeks.reduce((acc: { [key: string]: Week[] }, week) => { 96 | const monthYear = week.date.toLocaleString('ja-JP', { month: 'long', year: 'numeric' }); 97 | if (!acc[monthYear]) { 98 | acc[monthYear] = []; 99 | } 100 | acc[monthYear].push(week); 101 | return acc; 102 | }, {}); 103 | 104 | return Object.entries(groupedWeeks).map(([month, weeks]) => ({ 105 | month, 106 | weeks 107 | })).sort((a, b) => { 108 | const [aMonth, aYear] = a.month.split(' '); 109 | const [bMonth, bYear] = b.month.split(' '); 110 | if (aYear !== bYear) return parseInt(bYear) - parseInt(aYear); 111 | return new Date(Date.parse(\`\${bMonth} 1, 2000\`)).getMonth() - 112 | new Date(Date.parse(\`\${aMonth} 1, 2000\`)).getMonth(); 113 | }); 114 | } 115 | 116 | export { weeks }; 117 | `; 118 | 119 | // Write the updated content to weeks.ts 120 | fs.writeFileSync(weeksFilePath, fileContent, 'utf8'); 121 | 122 | console.log('Updated weeks.ts file successfully!'); -------------------------------------------------------------------------------- /src/app/notes/[slug]/page.tsx: -------------------------------------------------------------------------------- 1 | import { notFound } from 'next/navigation' 2 | import { notes } from '../_data/posts' 3 | 4 | type Params = Promise<{ slug: string }> 5 | 6 | // Generate static params for all reference pages 7 | export async function generateStaticParams() { 8 | return notes.map((post) => ({ 9 | slug: post.slug, 10 | })) 11 | } 12 | 13 | export async function generateMetadata({ params }: { params: Params }) { 14 | const { slug } = await params 15 | 16 | return { 17 | title: `${notes.find(post => post.slug === slug)?.title} | sumit.ml`, 18 | openGraph: { 19 | title: `${notes.find(post => post.slug === slug)?.title} | sumit.ml`, 20 | description: `${notes.find(post => post.slug === slug)?.description}`, 21 | images: [ 22 | { 23 | url: `/references/posts/${slug}/opengraph-image.png`, 24 | width: 1200, 25 | height: 630, 26 | alt: `${notes.find(post => post.slug === slug)?.description}`, 27 | }, 28 | ], 29 | }, 30 | twitter: { 31 | card: "summary_large_image", 32 | title: `${notes.find(post => post.slug === slug)?.title} | sumit.ml`, 33 | description: `${notes.find(post => post.slug === slug)?.description}`, 34 | images: [ 35 | { 36 | url: `/references/posts/${slug}/twitter-image.png`, 37 | width: 1200, 38 | height: 630, 39 | alt: `${notes.find(post => post.slug === slug)?.description}`, 40 | }, 41 | ], 42 | }, 43 | }; 44 | } 45 | 46 | 47 | export default async function Reference({ 48 | params 49 | }: { 50 | params: Params 51 | }) { 52 | const { slug } = await params 53 | 54 | // Find the matching blog post 55 | const post = notes.find(post => post.slug === slug) 56 | 57 | // If no matching post is found, return 404 58 | if (!post) { 59 | notFound() 60 | } 61 | 62 | // Import and render the actual blog post component 63 | const PostComponent = (await import(`../${slug}/page`)).default 64 | return 65 | } -------------------------------------------------------------------------------- /src/app/notes/_components/NotesCard.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link" 2 | import { cn } from "@/lib/utils/utils" 3 | import { StackVertical, StackHorizontal } from "@/components/layout/layout-stack/layout-stack" 4 | import Text from "@/components/ui/text/text" 5 | import TextHeading from "@/components/ui/text-heading/text-heading" 6 | import { NotesTypes } from "../_types/note-types" 7 | 8 | export function NotesCard({ post, isLast }: { post: NotesTypes; isLast?: boolean }) { 9 | const isExternalLink = post.href.startsWith('http') 10 | 11 | return ( 12 |
13 | 22 |
23 | 24 | 31 | {post.title} 32 | 33 | 38 | {post.description} 39 | 40 | 41 | 42 | Last Updated: {post.lastUpdated} 43 | 44 | 45 | 46 |
47 | 48 | {!isLast && ( 49 |
50 | )} 51 |
52 | ) 53 | } -------------------------------------------------------------------------------- /src/app/notes/_components/NotesHeader.tsx: -------------------------------------------------------------------------------- 1 | import { StackVertical } from "@/components/layout/layout-stack/layout-stack" 2 | import Text from "@/components/ui/text/text" 3 | import TextHeading from "@/components/ui/text-heading/text-heading" 4 | import { DynamicBreadcrumb } from "@/components/ui/primitives/breadcrumb" 5 | import { ThemeToggle } from "@/components/ui/theme/theme-toggle" 6 | 7 | export function NotesHeader() { 8 | return ( 9 | 10 | Notes | sumit.ml 11 | 12 |
13 | 19 | 20 |
21 | 22 |
23 | 24 | Notes 25 | 26 | 27 | A collection of notes that I have collected from my learning journey. Mostly Math and ML-related. 28 | 29 |
30 |
31 | ) 32 | } -------------------------------------------------------------------------------- /src/app/notes/_data/posts.ts: -------------------------------------------------------------------------------- 1 | import { NotesTypes } from "../_types/note-types" 2 | 3 | export const notes: NotesTypes[] = [ 4 | { 5 | id: 3, 6 | title: "Math References", 7 | description: "Formulas from my math learning journey for quick reference.", 8 | lastUpdated: "January 14, 2025", 9 | href: "https://sumitdotml.notion.site/math" 10 | }, 11 | { 12 | id: 2, 13 | title: "PyTorch References", 14 | description: "PyTorch code snippets that I've used & learned from for quick reference.", 15 | lastUpdated: "January 20, 2025", 16 | href: "/notes/pytorch" 17 | }, 18 | { 19 | id: 1, 20 | title: "Books", 21 | description: "Notes and summaries from the books I'm reading to learn ML and Math.", 22 | lastUpdated: "January 14, 2025", 23 | href: "/notes/books" 24 | } 25 | ] 26 | -------------------------------------------------------------------------------- /src/app/notes/_types/note-types.ts: -------------------------------------------------------------------------------- 1 | export interface NotesTypes { 2 | id: number; 3 | title: string; 4 | description: string; 5 | lastUpdated: string; 6 | slug?: string; 7 | href: string; 8 | } -------------------------------------------------------------------------------- /src/app/notes/books/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Metadata } from 'next' 2 | 3 | export const metadata: Metadata = { 4 | title: 'Books | sumit.ml', 5 | description: 'Notes and summaries from the books I\'m reading to learn ML and Math', 6 | openGraph: { 7 | title: 'Books | sumit.ml', 8 | description: 'Notes and summaries from the books I\'m reading to learn ML and Math', 9 | type: 'website', 10 | }, 11 | twitter: { 12 | card: 'summary_large_image', 13 | title: 'Books | sumit.ml', 14 | description: 'Notes and summaries from the books I\'m reading to learn ML and Math', 15 | } 16 | } 17 | 18 | export default function Layout({ 19 | children, 20 | }: { 21 | children: React.ReactNode 22 | }) { 23 | return children 24 | } -------------------------------------------------------------------------------- /src/app/notes/books/llm-from-scratch-raschka/chapter-1/notes.mdx: -------------------------------------------------------------------------------- 1 | # Chapter 1 2 | 3 | GPT-3 is a foundation model. 4 | 5 | ## Notes & Takeaways 6 | 7 | ### Stages when creating LLMs 8 | 9 | 1. Data collection, sampling, attention mechanism, building the architecture 10 | 2. Pretraining to build the foundation model 11 | 3. Training (basically finetuning) for specific domain purpose 12 | 13 | --- 14 | 15 | ### Transformer architecture 16 | 17 | Encoder-decoder 18 | 19 | Encoder has a multi-head attention layer and a feed forward layer. 20 | 21 | Decoder has a masked multi-head attention layer, another multi-head attention layer, and a feed-forward layer. 22 | 23 | --- 24 | 25 | ### GPT architecture 26 | 27 | Only decoder. 28 | 29 | --- 30 | 31 | ### Other takeaways 32 | 33 | The transformer architecture is not easy, man. For a noob that has never read a paper or implemented an architecture before. Truthfully speaking, I'm still stuck on the scaled dot-product attention notations (Q, K, V). Well, I think I'm slightly getting ahead of myself by trying to understand this on chapter 1 when it's discussed on chapter 3 in the book. I'll just take it step-by-step from here, I guess. 34 | 35 | Overall, a straightforward chapter with a very high-level overview of things. Hands-on approaches start from chapter 2, I think! 36 | -------------------------------------------------------------------------------- /src/app/notes/books/llm-from-scratch-raschka/chapter-1/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import Notes from './notes.mdx' 4 | import { mdxComponents } from '@/lib/mdx/mdx-components' 5 | import BaseContainer from '@/components/layout/container/base-container' 6 | import { StackVertical } from '@/components/layout/layout-stack/layout-stack' 7 | import { DynamicBreadcrumb } from '@/components/ui/primitives/breadcrumb' 8 | import { ThemeToggle } from '@/components/ui/theme/theme-toggle' 9 | import { IndividualPageFooter } from '@/components/layout/footer/IndividualPageFooter' 10 | 11 | export default function Chapter1() { 12 | return ( 13 | <> 14 | 15 | 16 | {/* Breadcrumb */} 17 |
18 | 27 | 28 |
29 | 30 | {/* MDX Content */} 31 |
32 | 33 |
34 |
35 |
36 | 37 | 38 | 39 | ) 40 | } -------------------------------------------------------------------------------- /src/app/notes/books/llm-from-scratch-raschka/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Metadata } from 'next' 2 | 3 | export const metadata: Metadata = { 4 | title: 'LLM from Scratch Notes | Books | sumit.ml', 5 | description: 'My notes and learnings from "Build a Large Language Model (from Scratch)" by Sebastian Raschka', 6 | openGraph: { 7 | title: 'LLM from Scratch Notes | Books | sumit.ml', 8 | description: 'My notes and learnings from "Build a Large Language Model (from Scratch)" by Sebastian Raschka', 9 | type: 'article', 10 | publishedTime: '2025-01-14T00:00:00.000Z', 11 | }, 12 | twitter: { 13 | card: 'summary_large_image', 14 | title: 'LLM from Scratch Notes | Books | sumit.ml', 15 | description: 'My notes and learnings from "Build a Large Language Model (from Scratch)" by Sebastian Raschka', 16 | } 17 | } 18 | 19 | export default function Layout({ 20 | children, 21 | }: { 22 | children: React.ReactNode 23 | }) { 24 | return children 25 | } -------------------------------------------------------------------------------- /src/app/notes/books/llm-from-scratch-raschka/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import BaseContainer from "@/components/layout/container/base-container"; 4 | import { DynamicBreadcrumb } from "@/components/ui/primitives/breadcrumb"; 5 | import { IndividualPageFooter } from "@/components/layout/footer/IndividualPageFooter"; 6 | import { StackVertical } from "@/components/layout/layout-stack/layout-stack"; 7 | import Ruler from "@/components/ui/ruler/ruler"; 8 | import TextHeading from "@/components/ui/text-heading/text-heading"; 9 | import Text from "@/components/ui/text/text"; 10 | import { ThemeToggle } from "@/components/ui/theme/theme-toggle"; 11 | import Link from "next/link"; 12 | 13 | export default function LLMFromScratchRaschka() { 14 | 15 | return ( 16 | <> 17 | 18 | 19 |
20 | 28 | 29 |
30 | 31 |
32 | LLM From Scratch 33 | Last updated: December 31, 2024 34 | 35 | 36 | This is a book that I'm reading to gain a deeper understanding of LLMs. 37 | 38 | 39 | 40 | 41 | 42 | The page is currently under construction. Every chapter link below is a placeholder. 43 | 44 | 45 | 46 | I am planning to integrate MDX for each chapter notes since I took notes in Jupyter Notebooks for each chapter and it's too 面倒い to manually translate them into typescript. Too much work. Might as well just learn new concepts if I have the time to do all that 47 | 48 | 49 | 50 | 51 | Chapter 1 Notes 52 | Chapter 2 Notes 53 | Chapter 3 Notes 54 | Chapter 4 Notes 55 | Chapter 5 Notes 56 | Chapter 6 Notes 57 | 58 |
59 |
60 |
61 | 62 | 63 | ) 64 | } -------------------------------------------------------------------------------- /src/app/notes/books/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import BaseContainer from "@/components/layout/container/base-container" 4 | import { StackVertical } from "@/components/layout/layout-stack/layout-stack" 5 | import TextHeading from "@/components/ui/text-heading/text-heading" 6 | import Text from "@/components/ui/text/text" 7 | import { DynamicBreadcrumb } from "@/components/ui/primitives/breadcrumb" 8 | import { ThemeToggle } from "@/components/ui/theme/theme-toggle" 9 | import { IndividualPageFooter } from "@/components/layout/footer/IndividualPageFooter" 10 | import Link from "next/link" 11 | 12 | export default function Books() { 13 | return ( 14 | 15 | 16 |
17 | 24 | 25 |
26 | 27 |
28 | 29 | Books 30 | 31 | 32 | A collection of books I've read and taken notes on. 33 | 34 | 35 | 36 | 37 | LLMs From Scratch by Sebastian Raschka 38 | 39 | 40 | ^The pages within this section are currently under construction. 41 | 42 | 43 |
44 | 45 |
46 | 47 | 48 | 49 |
50 | ) 51 | } 52 | 53 | -------------------------------------------------------------------------------- /src/app/notes/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Metadata } from 'next' 2 | 3 | export const metadata: Metadata = { 4 | title: 'My Notes | sumit.ml', 5 | description: 'A collection of references and notes from my learning journey', 6 | openGraph: { 7 | title: 'My Notes | sumit.ml', 8 | description: 'A collection of references and notes from my learning journey', 9 | type: 'website', 10 | }, 11 | twitter: { 12 | card: 'summary_large_image', 13 | title: 'My Notes | sumit.ml', 14 | description: 'A collection of references and notes from my learning journey', 15 | } 16 | } 17 | 18 | export default function Layout({ 19 | children, 20 | }: { 21 | children: React.ReactNode 22 | }) { 23 | return children 24 | } -------------------------------------------------------------------------------- /src/app/notes/math/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { StackVertical } from "@/components/layout/layout-stack/layout-stack"; 4 | import BaseContainer from "@/components/layout/container/base-container"; 5 | import TextHeading from "@/components/ui/text-heading/text-heading"; 6 | import Text from "@/components/ui/text/text"; 7 | import { IndividualPageFooter } from "@/components/layout/footer/IndividualPageFooter"; 8 | import { DynamicBreadcrumb } from "@/components/ui/primitives/breadcrumb"; 9 | import { ThemeToggle } from "@/components/ui/theme/theme-toggle"; 10 | import Link from "next/link"; 11 | 12 | export default function MathReferences() { 13 | return ( 14 | <> 15 | 16 | 17 |
18 | 25 | 26 |
27 | 28 | 29 | 30 | Math References 31 | 32 | 33 | If you have somehow reached this page, you probably have too much time on your hands. But if it's a genuine mistake, click the link below to see all my math references. 34 | 35 | 36 | This one 37 | 38 | 39 |
40 |
41 | 42 | 43 | 44 | 45 | ) 46 | } -------------------------------------------------------------------------------- /src/app/notes/opengraph-image.alt.txt: -------------------------------------------------------------------------------- 1 | Notes | sumit.ml - A collection of references and notes from my learning journey -------------------------------------------------------------------------------- /src/app/notes/opengraph-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitdotml/website/0dd4528252337303b2cbe7d75f8c727f5d08ae97/src/app/notes/opengraph-image.png -------------------------------------------------------------------------------- /src/app/notes/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { StackVertical } from "@/components/layout/layout-stack/layout-stack"; 4 | import BaseContainer from "@/components/layout/container/base-container"; 5 | import { notes } from "./_data/posts"; 6 | import { NotesCard } from "./_components/NotesCard"; 7 | import { NotesHeader } from "./_components/NotesHeader"; 8 | import { SectionFooter } from "@/components/layout/footer/SectionFooter"; 9 | 10 | export default function Notes() { 11 | return ( 12 | <> 13 | 14 | 15 | 16 | 17 | {notes.map((note, index) => ( 18 | 23 | ))} 24 | 25 | 26 | 27 | 28 | 29 | ) 30 | } -------------------------------------------------------------------------------- /src/app/notes/pytorch/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Metadata } from 'next' 2 | 3 | export const metadata: Metadata = { 4 | title: 'PyTorch References | Notes | sumit.ml', 5 | description: 'PyTorch code snippets and examples from my learning journey', 6 | openGraph: { 7 | title: 'PyTorch References | Notes | sumit.ml', 8 | description: 'PyTorch code snippets and examples from my learning journey', 9 | type: 'article', 10 | publishedTime: '2025-01-20T00:00:00.000Z', 11 | }, 12 | twitter: { 13 | card: 'summary_large_image', 14 | title: 'PyTorch References | Notes | sumit.ml', 15 | description: 'PyTorch code snippets and examples from my learning journey', 16 | } 17 | } 18 | 19 | export default function Layout({ 20 | children, 21 | }: { 22 | children: React.ReactNode 23 | }) { 24 | return children 25 | } 26 | -------------------------------------------------------------------------------- /src/app/notes/pytorch/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import Content from "./content.mdx"; 4 | import { mdxComponents } from "@/lib/mdx/mdx-components"; 5 | import BaseContainer from "@/components/layout/container/base-container"; 6 | import { StackVertical } from "@/components/layout/layout-stack/layout-stack"; 7 | import { DynamicBreadcrumb } from "@/components/ui/primitives/breadcrumb"; 8 | import { ThemeToggle } from "@/components/ui/theme/theme-toggle"; 9 | import { IndividualPageFooter } from "@/components/layout/footer/IndividualPageFooter"; 10 | 11 | export default function PyTorchReferences() { 12 | return ( 13 | 14 | 15 |
16 | 23 | 24 |
25 |
26 | 27 |
28 |
29 | 30 | 34 |
35 | ); 36 | } 37 | -------------------------------------------------------------------------------- /src/app/notes/twitter-image.alt.txt: -------------------------------------------------------------------------------- 1 | Notes - A collection of references and notes from my learning journey -------------------------------------------------------------------------------- /src/app/notes/twitter-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitdotml/website/0dd4528252337303b2cbe7d75f8c727f5d08ae97/src/app/notes/twitter-image.png -------------------------------------------------------------------------------- /src/app/opengraph-image.alt.txt: -------------------------------------------------------------------------------- 1 | Home | sumit.ml 2 | Sumit's personal website - A place where I document my learning journey in ML and Math -------------------------------------------------------------------------------- /src/app/opengraph-image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitdotml/website/0dd4528252337303b2cbe7d75f8c727f5d08ae97/src/app/opengraph-image.jpg -------------------------------------------------------------------------------- /src/app/page.tsx: -------------------------------------------------------------------------------- 1 | import Homepage from 'app/homepage/page' 2 | 3 | export default function Home() { 4 | return ( 5 | <> 6 | 7 | 8 | ) 9 | } -------------------------------------------------------------------------------- /src/app/twitter-image.alt.txt: -------------------------------------------------------------------------------- 1 | Home | sumit.ml 2 | Sumit's personal website - A place where I document my learning journey in ML and Math -------------------------------------------------------------------------------- /src/app/twitter-image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumitdotml/website/0dd4528252337303b2cbe7d75f8c727f5d08ae97/src/app/twitter-image.jpg -------------------------------------------------------------------------------- /src/components/blocks/callout/callout.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils/utils' 2 | import Text from '@/components/ui/text/text' 3 | import { Info, AlertTriangle, CheckCircle2, AlertCircle, Lightbulb } from 'lucide-react' 4 | import { monoFont } from '@/styles/fonts/fonts' 5 | 6 | interface CalloutProps { 7 | children: React.ReactNode; 8 | className?: string; 9 | variant?: 'purple' | 'orange' | 'green' | 'blue' | 'red'; 10 | title?: string; 11 | marginTop?: 'none' | 'sm' | 'md' | 'lg'; 12 | marginBottom?: 'none' | 'sm' | 'md' | 'lg'; 13 | } 14 | 15 | const margins = { 16 | none: '!m-0', 17 | sm: '!my-2 sm:!my-2', 18 | md: '!my-4 sm:!my-4', 19 | lg: '!my-8 sm:!my-8' 20 | } 21 | 22 | const marginTop = { 23 | none: '!mt-0', 24 | sm: '!mt-2 sm:!mt-2', 25 | md: '!mt-4 sm:!mt-4', 26 | lg: '!mt-8 sm:!mt-8' 27 | } 28 | 29 | const marginBottom = { 30 | none: '!mb-0', 31 | sm: '!mb-2 sm:!mb-2', 32 | md: '!mb-4 sm:!mb-4', 33 | lg: '!mb-8 sm:!mb-8' 34 | } 35 | 36 | const variants = { 37 | purple: { 38 | container: 'bg-purple-50 dark:bg-purple-950 text-purple-950 dark:text-purple-50', 39 | title: 'text-purple-800 dark:text-purple-200 font-bold', 40 | icon: 'text-purple-700 dark:text-purple-300', 41 | border: 'border-purple-200 dark:border-purple-800', 42 | Icon: Lightbulb 43 | }, 44 | orange: { 45 | container: 'bg-orange-50 dark:bg-orange-950 text-orange-950 dark:text-orange-50', 46 | title: 'text-orange-800 dark:text-orange-200 font-bold', 47 | icon: 'text-orange-700 dark:text-orange-300', 48 | border: 'border-orange-200 dark:border-orange-800', 49 | Icon: AlertTriangle 50 | }, 51 | red: { 52 | container: 'bg-red-50 dark:bg-red-950 text-red-950 dark:text-red-50', 53 | title: 'text-red-800 dark:text-red-200 font-bold', 54 | icon: 'text-red-700 dark:text-red-300', 55 | border: 'border-red-200 dark:border-red-800', 56 | Icon: AlertCircle 57 | }, 58 | green: { 59 | container: 'bg-emerald-50/80 dark:bg-green-950 text-emerald-800 dark:text-green-50', 60 | title: 'text-emerald-700 dark:text-green-200 font-bold', 61 | icon: 'text-emerald-600 dark:text-green-300', 62 | border: 'border-emerald-200 dark:border-green-800', 63 | Icon: CheckCircle2 64 | }, 65 | blue: { 66 | container: 'bg-blue-50 dark:bg-blue-950 text-blue-950 dark:text-blue-50', 67 | title: 'text-blue-800 dark:text-blue-200 font-bold', 68 | icon: 'text-blue-700 dark:text-blue-300', 69 | border: 'border-blue-200 dark:border-blue-800', 70 | Icon: Info 71 | } 72 | } 73 | 74 | export default function Callout({ 75 | children, 76 | className, 77 | variant = 'purple', 78 | title, 79 | marginTop: mt, 80 | marginBottom: mb 81 | }: CalloutProps) { 82 | const IconComponent = variants[variant].Icon 83 | const spacing = mt || mb ? null : 'md' 84 | 85 | return ( 86 |
96 | {title && ( 97 |
98 | 99 | {title} 100 |
101 | )} 102 |
103 | {children} 104 |
105 |
106 | ) 107 | } -------------------------------------------------------------------------------- /src/components/blocks/homepage/CurrentWork.tsx: -------------------------------------------------------------------------------- 1 | import { motion } from 'framer-motion' 2 | import { Code, Brain, Divide, Rotate3D } from 'lucide-react' 3 | import { StackVertical } from '@/components/layout/layout-stack/layout-stack' 4 | import Text from '@/components/ui/text/text' 5 | import TextHeading from '@/components/ui/text-heading/text-heading' 6 | import Link from 'next/link' 7 | 8 | interface WorkItemProps { 9 | icon: React.ReactNode; 10 | text: string; 11 | delay: number; 12 | hyperlink?: string; 13 | hyperlinkText?: string; 14 | endText?: string; 15 | } 16 | 17 | function WorkItem({ icon, text, delay, hyperlink, hyperlinkText, endText }: WorkItemProps) { 18 | return ( 19 | 25 |
26 | {icon} 27 |
28 | 29 | {text} 30 | {hyperlink && hyperlinkText && ( 31 | 32 | {hyperlinkText} 33 | 34 | )} 35 | {endText && ( 36 | {endText} 37 | )} 38 | 39 |
40 | ) 41 | } 42 | 43 | export function CurrentWork() { 44 | const items = [ 45 | { 46 | icon: , 47 | text: "Studying traditional ML" 48 | }, 49 | { 50 | icon: , 51 | text: "Learning math for ML" 52 | }, 53 | { 54 | icon: , 55 | text: "Mastering the language of Python" 56 | }, 57 | 58 | { 59 | icon: , 60 | text: "Learning to get comfy with PyTorch till 5D", 61 | } 62 | // { 63 | // icon: , 64 | // text: "Reading ", 65 | // hyperlink: "/notes/books", 66 | // hyperlinkText: "ML Books", 67 | // endText: "" 68 | // } 69 | ] 70 | 71 | return ( 72 | 77 | 78 | Current Ongoings 79 | 80 | {items.map((item, index) => ( 81 | 90 | ))} 91 | 92 | 93 | 94 | ) 95 | } -------------------------------------------------------------------------------- /src/components/blocks/homepage/HeroSection.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { motion } from 'framer-motion' 4 | import { monoFont } from '@/styles/fonts/fonts' 5 | import { cn } from '@/lib/utils/utils' 6 | import TextHeading from '@/components/ui/text-heading/text-heading' 7 | import Text from '@/components/ui/text/text' 8 | import { StackVertical } from '@/components/layout/layout-stack/layout-stack' 9 | import Link from 'next/link' 10 | import Image from 'next/image' 11 | import Ruler from '@/components/ui/ruler/ruler' 12 | import { List, ListItem } from '@/components/ui/list/list' 13 | 14 | export function HeroSection() { 15 | return ( 16 | 22 |
23 | 24 | 35 | 👾 36 | 37 | 38 | 44 | 45 | sumit.ml 46 | 47 | 48 | 49 | 54 | 55 | Hi! I am Sumit. 56 | 57 | 58 | 59 | 60 | 65 | 66 | I'm a swe based in Tokyo. I love coffee, machine learning, math, and among others. Glad to have you here! Feel free to look around :) 67 | 68 | 69 | 70 | 71 | 76 | 77 | This is my graph of thoughts, notes, and ideas. 78 | 79 | 80 | 81 | 82 | 83 | I ramble about things on my{' '} 84 | 85 | blog 86 | 87 | ; you can check it out if you're interested. 88 | 89 | 90 | 91 | 92 | 93 | Here are some reads I recommend from this site if you're interested: 94 | 95 | 96 | 97 | 98 | 99 | 100 | My novice journey, a monologue 101 | 102 | 103 | My 2025 Resolution: Beyond the Roadmaps, Beyond the Timelines 104 | 105 | 106 | 107 | Getting Started with Machine Learning 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | I also document my learnings through learning reflections every week. You can take a look at those{' '} 116 | 117 | here 118 | 119 | . 120 | 121 | 122 | 123 | 124 |
125 | 126 | 132 |
133 | A photo of Gion Town, Kyoto I took on March 2024. 141 |
142 |
143 |
144 | ) 145 | } 146 | -------------------------------------------------------------------------------- /src/components/blocks/homepage/HomepageSocials.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import TextHeading from '@/components/ui/text-heading/text-heading' 4 | import Text from '@/components/ui/text/text' 5 | import Link from 'next/link' 6 | 7 | export function HomepageSocials() { 8 | return ( 9 |
10 | Socials 11 | 12 | I’m always open to chat! Please feel free to ping me at sumit@sumit.ml or Twitter if you have any questions or just wanna talk. 13 | 14 |
15 | 16 | ) 17 | } -------------------------------------------------------------------------------- /src/components/blocks/homepage/QuickLinks.tsx: -------------------------------------------------------------------------------- 1 | import { motion } from 'framer-motion' 2 | import Link from 'next/link' 3 | import { ArrowRight } from 'lucide-react' 4 | import { cn } from '@/lib/utils/utils' 5 | import { StackVertical } from '@/components/layout/layout-stack/layout-stack' 6 | import Ruler from '@/components/ui/ruler/ruler' 7 | 8 | interface QuickLinkProps { 9 | href: string; 10 | title: string; 11 | description: string; 12 | } 13 | 14 | function QuickLink({ href, title, description }: QuickLinkProps) { 15 | return ( 16 | 17 | 27 |
28 |

29 | {title} 30 |

31 |

32 | {description} 33 |

34 |
35 | 36 |
37 | 38 | ) 39 | } 40 | 41 | export function QuickLinks() { 42 | const links = [ 43 | { 44 | href: '/blog', 45 | title: 'Blog', 46 | description: 'Thoughts on ML, programming, and technology' 47 | }, 48 | ] 49 | 50 | return ( 51 | 56 | 57 | 58 | {links.map((link, index) => ( 59 | 60 | ))} 61 | 62 | 63 | 64 | ) 65 | } -------------------------------------------------------------------------------- /src/components/blocks/homepage/SocialLinks.tsx: -------------------------------------------------------------------------------- 1 | import { motion } from 'framer-motion' 2 | import Link from 'next/link' 3 | import { Github, Twitter, Mail } from 'lucide-react' 4 | import { cn } from '@/lib/utils/utils' 5 | import { monoFont } from '@/styles/fonts/fonts' 6 | import { StackVertical } from '@/components/layout/layout-stack/layout-stack' 7 | 8 | interface SocialLinkProps { 9 | href: string; 10 | icon: React.ReactNode; 11 | label: string; 12 | delay: number; 13 | } 14 | 15 | function SocialLink({ href, icon, label, delay }: SocialLinkProps) { 16 | return ( 17 | 22 | 32 | 36 | {icon} 37 | 38 | {label} 39 | 40 | 41 | ) 42 | } 43 | 44 | export function SocialLinks() { 45 | const links = [ 46 | { 47 | href: "https://github.com/sumitdotml", 48 | icon: , 49 | label: "github" 50 | }, 51 | { 52 | href: "https://x.com/sumitdotml", 53 | icon: , 54 | label: "twitter" 55 | }, 56 | { 57 | href: "mailto:sumit@sumit.ml", 58 | icon: , 59 | label: "email" 60 | } 61 | ] 62 | 63 | return ( 64 | 69 | 70 |
71 | Find me on 72 |
73 |
74 | {links.map((link, index) => ( 75 | 80 | ))} 81 |
82 |
83 |
84 | ) 85 | } -------------------------------------------------------------------------------- /src/components/blocks/table-of-contents/table-of-contents.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | import { cn } from '@/lib/utils/utils'; 3 | 4 | interface TableOfContentsProps { 5 | contentId: string; 6 | } 7 | 8 | interface HeadingItem { 9 | id: string; 10 | text: string; 11 | level: number; 12 | } 13 | 14 | export function TableOfContents({ contentId }: TableOfContentsProps) { 15 | const [headings, setHeadings] = useState([]); 16 | const [activeId, setActiveId] = useState(''); 17 | 18 | useEffect(() => { 19 | const content = document.getElementById(contentId); 20 | if (!content) return; 21 | 22 | const elements = content.querySelectorAll('h1, h2, h3'); 23 | const items: HeadingItem[] = Array.from(elements).map((element) => ({ 24 | id: element.id, 25 | text: element.textContent || '', 26 | level: parseInt(element.tagName[1]), 27 | })); 28 | 29 | setHeadings(items); 30 | 31 | const observer = new IntersectionObserver( 32 | (entries) => { 33 | entries.forEach((entry) => { 34 | if (entry.isIntersecting) { 35 | setActiveId(entry.target.id); 36 | } 37 | }); 38 | }, 39 | { rootMargin: '0px 0px -80% 0px' } 40 | ); 41 | 42 | elements.forEach((element) => observer.observe(element)); 43 | 44 | return () => observer.disconnect(); 45 | }, [contentId]); 46 | 47 | return ( 48 |
49 | 69 |
70 | ); 71 | } -------------------------------------------------------------------------------- /src/components/layout/container/base-container.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils/utils' 2 | 3 | interface BaseContainerProps { 4 | children: React.ReactNode; 5 | size?: 'sm' | 'md' | 'lg' | 'xl' | 'full'; 6 | paddingX?: 'none' | 'sm' | 'md' | 'lg'; 7 | paddingY?: 'none' | 'sm' | 'md' | 'lg' | 'xl'; 8 | center?: boolean; 9 | className?: string; 10 | } 11 | 12 | const sizes = { 13 | sm: 'max-w-2xl', 14 | md: 'max-w-3xl', 15 | lg: 'max-w-4xl', 16 | xl: 'max-w-5xl', 17 | full: 'max-w-full' 18 | } 19 | 20 | const paddingX = { 21 | none: 'px-0', 22 | sm: 'px-2 sm:px-3 md:px-4', 23 | md: 'px-3 sm:px-4 md:px-6', 24 | lg: 'px-4 sm:px-6 md:px-8' 25 | } 26 | 27 | const paddingY = { 28 | none: 'py-0', 29 | sm: 'py-2 sm:py-3 md:py-4', 30 | md: 'py-3 sm:py-4 md:py-6', 31 | lg: 'py-4 sm:py-6 md:py-8', 32 | xl: 'py-6 sm:py-8 md:py-12' 33 | } 34 | 35 | export default function BaseContainer({ 36 | children, 37 | size = 'md', 38 | paddingX: px = 'md', 39 | paddingY: py = 'md', 40 | center = false, 41 | className 42 | }: BaseContainerProps) { 43 | return ( 44 |
52 | {children} 53 |
54 | ) 55 | } -------------------------------------------------------------------------------- /src/components/layout/footer/BaseFooter.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { cn } from '@/lib/utils/utils' 4 | import { monoFont } from '@/styles/fonts/fonts' 5 | import { Github, Twitter, Mail } from 'lucide-react' 6 | import Link from 'next/link' 7 | import { motion } from 'framer-motion' 8 | 9 | interface BaseFooterProps { 10 | color?: string; 11 | navigationLinks?: React.ReactNode; 12 | className?: string; 13 | showToTop?: boolean; 14 | showSectionName?: boolean; 15 | showSocialLinks?: boolean; 16 | showCopyright?: boolean; 17 | } 18 | 19 | export function BaseFooter({ 20 | color = 'purple', 21 | navigationLinks, 22 | className, 23 | showToTop = true, 24 | showSectionName = true, 25 | showSocialLinks = true, 26 | showCopyright = true 27 | }: BaseFooterProps) { 28 | const socialLinks = [ 29 | { href: "mailto:sumit@sumit.ml", icon: }, 30 | { href: "https://github.com/sumitdotml", icon: }, 31 | { href: "https://x.com/sumitdotml", icon: } 32 | ] 33 | 34 | return ( 35 |
36 | {/* Gradient Line */} 37 |
38 |
55 |
56 | 57 |
63 | {/* Navigation Links - First Row */} 64 | {navigationLinks && (showToTop || showSectionName) && ( 65 |
66 | {navigationLinks} 67 |
68 | )} 69 | 70 | {/* Social Links and Copyright - Second Row */} 71 | {(showSocialLinks || showCopyright) && ( 72 |
73 | {/* Social Links */} 74 | {showSocialLinks && ( 75 |
76 | {socialLinks.map((link, index) => ( 77 | 88 | 99 | {link.icon} 100 | 101 | 102 | ))} 103 |
104 | )} 105 | 106 | {/* Copyright */} 107 | {showCopyright && ( 108 | 114 | © {new Date().getFullYear()} sumit.ml 115 | 116 | )} 117 |
118 | )} 119 |
120 | 121 | {/* Bottom padding */} 122 |
123 |
124 | ) 125 | } -------------------------------------------------------------------------------- /src/components/layout/footer/HomepageFooter.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { BaseFooter } from './BaseFooter' 4 | import { FooterLink } from './_components/FooterLink' 5 | 6 | interface HomepageFooterProps { 7 | color?: string; 8 | showToTop?: boolean; 9 | showSocialLinks?: boolean; 10 | showCopyright?: boolean; 11 | } 12 | 13 | export function HomepageFooter({ 14 | color = 'purple', 15 | showToTop = true, 16 | showSocialLinks = true, 17 | showCopyright = true 18 | }: HomepageFooterProps) { 19 | const navigationLinks = showToTop ? ( 20 | To the Top 21 | ) : null 22 | 23 | return ( 24 | 32 | ) 33 | } -------------------------------------------------------------------------------- /src/components/layout/footer/IndividualPageFooter.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { usePathname } from 'next/navigation' 4 | import { BaseFooter } from './BaseFooter' 5 | import { FooterLink } from './_components/FooterLink' 6 | import { FooterDivider } from './_components/FooterDivider' 7 | 8 | interface IndividualPageFooterProps { 9 | sectionName?: string; 10 | parentPageName?: string; 11 | showToTop?: boolean; 12 | showParentPage?: boolean; 13 | showHomePage?: boolean; 14 | showSocialLinks?: boolean; 15 | showCopyright?: boolean; 16 | } 17 | 18 | export function IndividualPageFooter({ 19 | sectionName, 20 | parentPageName, 21 | showToTop = true, 22 | showParentPage = true, 23 | showHomePage = true, 24 | showSocialLinks = true, 25 | showCopyright = true 26 | }: IndividualPageFooterProps) { 27 | const pathname = usePathname() 28 | 29 | // Get the parent path and name dynamically if not provided 30 | const getParentInfo = () => { 31 | if (parentPageName) return { name: parentPageName, path: pathname.split('/').slice(0, -1).join('/') } 32 | 33 | const pathParts = pathname.split('/') 34 | // Remove empty string and current page 35 | const filteredParts = pathParts.filter(part => part) 36 | 37 | if (filteredParts.length <= 1) { 38 | return { name: sectionName || 'Home', path: '/' } 39 | } 40 | 41 | // Get parent path (one level up) 42 | const parentPath = '/' + filteredParts.slice(0, -1).join('/') 43 | 44 | // Format the parent name 45 | const parentName = filteredParts[filteredParts.length - 2] 46 | .split('-') 47 | .map(word => word.charAt(0).toUpperCase() + word.slice(1)) 48 | .join(' ') 49 | 50 | return { name: parentName, path: parentPath } 51 | } 52 | 53 | const { name: parentName, path: parentPath } = getParentInfo() 54 | 55 | const navigationLinks = ( 56 |
57 | {showToTop && ( 58 | <> 59 | To the Top 60 | {(showParentPage || showHomePage) && } 61 | 62 | )} 63 | {showParentPage && ( 64 | <> 65 | {parentName} Page 66 | {showHomePage && } 67 | 68 | )} 69 | {showHomePage && ( 70 | Home Page 71 | )} 72 |
73 | ) 74 | 75 | return ( 76 | 84 | ) 85 | } -------------------------------------------------------------------------------- /src/components/layout/footer/SectionFooter.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { BaseFooter } from './BaseFooter' 4 | import { FooterLink } from './_components/FooterLink' 5 | import { FooterDivider } from './_components/FooterDivider' 6 | 7 | interface SectionFooterProps { 8 | color?: string; 9 | showToTop?: boolean; 10 | showHomePage?: boolean; 11 | showSocialLinks?: boolean; 12 | showCopyright?: boolean; 13 | } 14 | 15 | export function SectionFooter({ 16 | color = 'purple', 17 | showToTop = true, 18 | showHomePage = true, 19 | showSocialLinks = true, 20 | showCopyright = true 21 | }: SectionFooterProps) { 22 | const navigationLinks = ( 23 | <> 24 | {showToTop && ( 25 | <> 26 | To the Top 27 | {showHomePage && } 28 | 29 | )} 30 | {showHomePage && ( 31 | Home Page 32 | )} 33 | 34 | ) 35 | 36 | return ( 37 | 45 | ) 46 | } -------------------------------------------------------------------------------- /src/components/layout/footer/_components/FooterDivider.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils/utils'; 2 | 3 | interface FooterDividerProps { 4 | color?: string; 5 | vertical?: boolean; 6 | } 7 | 8 | export function FooterDivider({ color = 'purple', vertical = true }: FooterDividerProps) { 9 | return ( 10 |
17 | ) 18 | } -------------------------------------------------------------------------------- /src/components/layout/footer/_components/FooterLink.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import Link from 'next/link' 4 | import { motion } from 'framer-motion' 5 | import { cn } from '@/lib/utils/utils' 6 | 7 | interface FooterLinkProps { 8 | href: string; 9 | children: React.ReactNode; 10 | color?: string; 11 | external?: boolean; 12 | icon?: React.ReactNode; 13 | } 14 | 15 | export function FooterLink({ href, children, color = 'purple', external, icon }: FooterLinkProps) { 16 | return ( 17 | 33 | {icon && ( 34 | 39 | {icon} 40 | 41 | )} 42 | {children} 43 | 44 | ) 45 | } -------------------------------------------------------------------------------- /src/components/layout/footer/_components/FooterSection.tsx: -------------------------------------------------------------------------------- 1 | interface FooterSectionProps { 2 | children: React.ReactNode; 3 | } 4 | 5 | export function FooterSection({ children }: FooterSectionProps) { 6 | return ( 7 |
8 | {children} 9 |
10 | ) 11 | } -------------------------------------------------------------------------------- /src/components/layout/layout-stack/layout-stack.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils/utils' 2 | 3 | interface FlexStackProps { 4 | children: React.ReactNode; 5 | className?: string; 6 | gap?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl'; 7 | } 8 | 9 | const gaps = { 10 | none: '', 11 | xs: 'space-y-0.5 sm:space-y-1', 12 | sm: 'space-y-1 sm:space-y-2', 13 | md: 'space-y-2 sm:space-y-4', 14 | lg: 'space-y-4 sm:space-y-8', 15 | xl: 'space-y-6 sm:space-y-12' 16 | } 17 | 18 | export function StackVertical({ children, className, gap = 'md' }: FlexStackProps) { 19 | return ( 20 |
21 | {children} 22 |
23 | ); 24 | } 25 | 26 | export function StackHorizontal({ children, className, gap = 'md' }: FlexStackProps) { 27 | return ( 28 |
37 | {children} 38 |
39 | ); 40 | } 41 | 42 | interface GridLayoutProps extends FlexStackProps { 43 | cols?: 1 | 2 | 3 | 4; 44 | } 45 | 46 | export function GridLayout({ children, className, gap = 'md', cols = 3 }: GridLayoutProps) { 47 | return ( 48 |
54 | {children} 55 |
56 | ); 57 | } -------------------------------------------------------------------------------- /src/components/ui/accordion/accordion.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as AccordionPrimitive from "@radix-ui/react-accordion" 5 | import { ChevronDown } from "lucide-react" 6 | 7 | import { cn } from "@/lib/utils/utils" 8 | 9 | const Accordion = AccordionPrimitive.Root 10 | 11 | const AccordionItem = React.forwardRef< 12 | React.ElementRef, 13 | React.ComponentPropsWithoutRef 14 | >(({ className, ...props }, ref) => ( 15 | 20 | )) 21 | AccordionItem.displayName = "AccordionItem" 22 | 23 | const AccordionTrigger = React.forwardRef< 24 | React.ElementRef, 25 | React.ComponentPropsWithoutRef 26 | >(({ className, children, ...props }, ref) => ( 27 | 28 | svg]:rotate-180", 32 | className 33 | )} 34 | {...props} 35 | > 36 | {children} 37 | 38 | 39 | 40 | )) 41 | AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName 42 | 43 | const AccordionContent = React.forwardRef< 44 | React.ElementRef, 45 | React.ComponentPropsWithoutRef 46 | >(({ className, children, ...props }, ref) => ( 47 | 52 |
{children}
53 |
54 | )) 55 | AccordionContent.displayName = AccordionPrimitive.Content.displayName 56 | 57 | export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } 58 | -------------------------------------------------------------------------------- /src/components/ui/list/list.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils/utils' 2 | import { StackVertical } from '@/components/layout/layout-stack/layout-stack' 3 | import { monoFont } from '@/styles/fonts/fonts' 4 | interface ListProps { 5 | children: React.ReactNode; 6 | className?: string; 7 | type?: 'unordered' | 'ordered'; 8 | variant?: 'default' | 'compact'; 9 | marker?: 'disc' | 'circle' | 'square' | 'decimal' | 'none'; 10 | spacing?: 'tight' | 'normal' | 'relaxed'; 11 | fontSize?: 'xs' | 'sm' | 'md' | 'base' | 'lg' | 'xl' | '2xl'; 12 | paddingLeft?: 'sm' | 'md' | 'lg' | 'xs' | 'none'; 13 | } 14 | 15 | interface ListItemProps { 16 | children: React.ReactNode; 17 | className?: string; 18 | } 19 | 20 | const listFontClass = monoFont.className 21 | 22 | const listFontSize = { 23 | xs: 'text-[10px] sm:text-xs md:text-xs', // 10px -> 12px -> 12px 24 | sm: 'text-xs sm:text-sm md:text-sm', // 12px -> 14px -> 14px 25 | md: 'text-sm sm:text-base md:text-base', // 14px -> 16px -> 16px 26 | base: 'text-sm sm:text-base md:text-base', // 14px -> 16px -> 16px 27 | lg: 'text-base sm:text-lg md:text-lg', // 16px -> 18px -> 18px 28 | xl: 'text-lg sm:text-xl md:text-xl', // 18px -> 20px -> 20px 29 | '2xl': 'text-xl sm:text-2xl md:text-2xl' // 20px -> 24px -> 24px 30 | } 31 | 32 | const spacingStyles = { 33 | tight: 'space-y-0.5 sm:space-y-1', 34 | normal: 'space-y-1 sm:space-y-2', 35 | relaxed: 'space-y-2 sm:space-y-3' 36 | } 37 | 38 | const markerStyles = { 39 | disc: 'list-disc', 40 | circle: 'list-circle', 41 | square: 'list-square', 42 | decimal: 'list-decimal', 43 | none: 'list-none' 44 | } 45 | 46 | const paddingLeftStyles = { 47 | sm: 'pl-1 sm:pl-2', 48 | md: 'pl-2 sm:pl-4', 49 | lg: 'pl-4 sm:pl-6', 50 | xs: 'pl-0.5 sm:pl-1', 51 | none: 'pl-0' 52 | } 53 | 54 | export function List({ 55 | children, 56 | className, 57 | type = 'unordered', 58 | variant = 'default', 59 | marker = 'disc', 60 | spacing = 'normal', 61 | fontSize = 'sm', 62 | paddingLeft = 'md' 63 | }: ListProps) { 64 | const Component = type === 'ordered' ? 'ol' : 'ul' 65 | 66 | return ( 67 | 79 | {children} 80 | 81 | ) 82 | } 83 | 84 | export function ListItem({ children, className }: ListItemProps) { 85 | return ( 86 |
  • 92 | {children} 93 |
  • 94 | ) 95 | } 96 | 97 | // Example of a nested list component for better organization 98 | export function NestedList({ 99 | items 100 | }: { 101 | items: { 102 | content: React.ReactNode; 103 | subitems?: React.ReactNode[]; 104 | }[] 105 | }) { 106 | return ( 107 | 108 | {items.map((item, index) => ( 109 | 110 | {item.content} 111 | {item.subitems && ( 112 | 113 | {item.subitems.map((subitem, subIndex) => ( 114 | {subitem} 115 | ))} 116 | 117 | )} 118 | 119 | ))} 120 | 121 | ) 122 | } -------------------------------------------------------------------------------- /src/components/ui/math/math.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { useEffect, useRef } from 'react' 4 | import katex from 'katex' 5 | import 'katex/dist/katex.min.css' 6 | 7 | interface MathProps { 8 | math: string 9 | block?: boolean 10 | className?: string 11 | } 12 | 13 | export default function Math({ math, block = false, className = '' }: MathProps) { 14 | const mathRef = useRef(null) 15 | 16 | useEffect(() => { 17 | if (mathRef.current) { 18 | katex.render(math, mathRef.current, { 19 | displayMode: block, 20 | throwOnError: false, 21 | strict: false 22 | }) 23 | } 24 | }, [math, block]) 25 | 26 | return 27 | } -------------------------------------------------------------------------------- /src/components/ui/navbar/Navbar.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import Link from 'next/link' 4 | import { motion, AnimatePresence } from 'framer-motion' 5 | import { cn } from '@/lib/utils/utils' 6 | import { monoFont } from '@/styles/fonts/fonts' 7 | import { Menu, X } from 'lucide-react' 8 | import { useState, useEffect } from 'react' 9 | 10 | interface NavLinkProps { 11 | href: string; 12 | children: React.ReactNode; 13 | onClick?: () => void; 14 | } 15 | 16 | function NavLink({ href, children, onClick }: NavLinkProps) { 17 | return ( 18 | 28 | {children} 29 | 30 | ) 31 | } 32 | 33 | export function Navbar() { 34 | const [isMenuOpen, setIsMenuOpen] = useState(false) 35 | 36 | const links = [ 37 | { href: '/about', label: 'About' }, 38 | { href: '/blog', label: 'Blog' }, 39 | { href: '/learning', label: 'Learning' }, 40 | { href: '/notes', label: 'Notes' } 41 | ] 42 | 43 | // Close menu when clicking outside 44 | useEffect(() => { 45 | const handleClickOutside = (event: MouseEvent) => { 46 | const target = event.target as HTMLElement; 47 | if (isMenuOpen && !target.closest('.mobile-menu-container')) { 48 | setIsMenuOpen(false); 49 | } 50 | }; 51 | 52 | document.addEventListener('click', handleClickOutside); 53 | return () => document.removeEventListener('click', handleClickOutside); 54 | }, [isMenuOpen]); 55 | 56 | return ( 57 | 166 | ) 167 | } -------------------------------------------------------------------------------- /src/components/ui/primitives/breadcrumb.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import * as React from "react" 4 | import { Slot } from "@radix-ui/react-slot" 5 | import { ChevronRight, MoreHorizontal, Slash } from "lucide-react" 6 | import Link from "next/link" 7 | import { monoFont } from "@/styles/fonts/fonts" 8 | import { cn } from "@/lib/utils/utils" 9 | 10 | // Base Breadcrumb Components 11 | const Breadcrumb = React.forwardRef< 12 | HTMLElement, 13 | React.ComponentPropsWithoutRef<"nav"> & { 14 | separator?: React.ReactNode 15 | } 16 | >(({ ...props }, ref) =>