Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"format": "prettier --write .",
"db:generate": "drizzle-kit generate --config=drizzle.config.ts",
"db:migrate": "drizzle-kit migrate --config=drizzle.config.ts",
"db:push": "drizzle-kit push:pg --config=drizzle.config.ts"
"db:push": "drizzle-kit push --config=drizzle.config.ts"
},
"dependencies": {
"@evowizz/material-color-utilities-canary": "0.4.0-canary.1",
Expand Down
26 changes: 4 additions & 22 deletions src/app/(home)/_components/sections/work.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,9 @@ import { SectionTitle } from '../section-title'
import { Reveal } from '@/components/ui/reveal'
import { CountUp } from '../count-up'

const SENTENCES: Record<string, string> = {
Inware: 'An Android app I have been building since 2018 to answer one question: what is actually inside your phone?',
'Personal Website': 'The page you are reading, built with Next.js and open source from front to back.',
Cosmose: 'A small demo gallery of Jetpack Compose components and animations.',
Common: 'A Kotlin library of the utilities and extensions I kept rewriting for Android.',
'De-Gmojify': 'A Chrome extension that swaps Google emojis for the ones your system already ships.',
Actio: 'A Figma plugin that resizes frames to an aspect ratio, so nobody does the math by hand.',
}

const STAT_LABELS: Record<string, string> = {
downloads: 'Downloads',
rating: 'Rating, about 2,000 reviews',
}

const lead = projects.find((project) => project.spotlight)
const rest = projects.filter((project) => !project.spotlight && !project.deprecated)

const sentenceFor = (project: Project) => SENTENCES[project.title] ?? project.description

const statValue = (stat: { value: string; label: string }) => (stat.label === 'rating' ? `${stat.value}/5` : stat.value)

/** Counts "500k+" up. Leaves non-integer values like "4.7/5" static. */
const StatValue = ({ value }: { value: string }) => {
const match = /^(\d+)(\D*)$/.exec(value)
Expand Down Expand Up @@ -69,7 +51,7 @@ const Lead = ({ project }: { project: Project }) => (

<div className="flex flex-col gap-8">
<div className="flex flex-col items-start gap-5">
<p className="max-w-xl text-lg leading-relaxed opacity-80 md:text-xl">{sentenceFor(project)}</p>
<p className="max-w-xl text-lg leading-relaxed opacity-80 md:text-xl">{project.description}</p>

<div className="flex flex-wrap items-center gap-x-5 gap-y-2">
{project.links[0] && (
Expand Down Expand Up @@ -107,9 +89,9 @@ const Lead = ({ project }: { project: Project }) => (
<dl className="flex flex-wrap gap-x-10 gap-y-5">
{project.spotlightStats?.map((stat) => (
<div key={stat.label} className="flex flex-col-reverse gap-1.5">
<dt className="text-sm font-medium opacity-80">{STAT_LABELS[stat.label] ?? stat.label}</dt>
<dt className="text-sm font-medium opacity-80">{stat.label}</dt>
<dd className="variation-sans text-[clamp(2.5rem,4.5vw,3.25rem)] leading-none font-bold tracking-tight tabular-nums">
<StatValue value={statValue(stat)} />
<StatValue value={stat.value} />
</dd>
</div>
))}
Expand All @@ -131,7 +113,7 @@ const Row = ({ project }: { project: Project }) => {
<h3 className="variation-sans text-on-surface shrink-0 text-xl font-medium tracking-tight md:w-56 md:text-2xl">
{project.title}
</h3>
<p className="text-on-surface-variant flex-1 text-base leading-relaxed">{sentenceFor(project)}</p>
<p className="text-on-surface-variant flex-1 text-base leading-relaxed">{project.description}</p>
{link ? (
<MaterialSymbol
name="arrow_outward"
Expand Down
36 changes: 11 additions & 25 deletions src/app/(home)/_data/projects.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
export type CaseStudyLink = {
type CaseStudyLink = {
slug: string
label: string
}

export type ProjectLink = {
type ProjectLink = {
url: string
label: string
}
Expand All @@ -18,12 +18,12 @@ const playStoreLink = (packageName: string): ProjectLink => ({
label: 'Google Play',
})

export type SpotlightStat = {
type SpotlightStat = {
value: string
label: string
}

export type ProjectImage = {
type ProjectImage = {
path: string
alt: string
}
Expand All @@ -33,8 +33,6 @@ export type Project = {
description: string
image?: ProjectImage
techStack: string[]
openSource: boolean
featured?: boolean
spotlight?: boolean // Rendered as the oversized lead block in Selected Work
spotlightStats?: SpotlightStat[]
deprecated?: boolean
Expand All @@ -46,18 +44,16 @@ export const projects: Project[] = [
{
title: 'Inware',
description:
"An Android app I've been building since 2018 to answer one question: what is actually inside your phone? It digs into the hardware and software (CPU, display, sensors, camera, battery) and themes itself to your wallpaper with Material You.",
'An Android app I have been building since 2018 to answer one question: what is actually inside your phone?',
image: {
path: '/content/projects/inware-promo.png',
alt: 'Screens from the Inware app on Android',
},
techStack: ['Kotlin', 'Jetpack Compose', 'Android'],
openSource: false,
featured: true,
spotlight: true,
spotlightStats: [
{ value: '500k+', label: 'downloads' },
{ value: '4.7', label: 'rating' },
{ value: '500k+', label: 'Downloads' },
{ value: '4.7/5', label: 'Rating, about 2,000 reviews' },
],
caseStudies: [{ slug: 'inware', label: 'Case Study' }],
links: [playStoreLink('com.evo.inware')],
Expand All @@ -66,47 +62,37 @@ export const projects: Project[] = [
title: 'Personal Website',
description: "You're looking at it! Built with Next.js and Tailwind CSS.",
techStack: ['Next.js', 'TypeScript', 'Tailwind CSS'],
openSource: true,
featured: false,
links: [githubLink('evowizz/evowizz.dev')],
},
{
title: 'Cosmose',
description: 'A simple Jetpack Compose demo gallery showcasing various UI components and animations.',
description: 'A small demo gallery of Jetpack Compose components and animations.',
techStack: ['Kotlin', 'Jetpack Compose', 'Android'],
openSource: true,
links: [githubLink('evowizz/cosmose')],
},
{
title: 'Common',
description:
'A Kotlin library providing common utilities and extensions for Android development, including helpers for views, networking, and data processing.',
description: 'A Kotlin library of the utilities and extensions I kept rewriting for Android.',
techStack: ['Kotlin', 'Android'],
openSource: true,
links: [githubLink('evowizz/common')],
},
{
title: 'De-Gmojify',
description:
'A Chrome extension that replaces Google emojis with standard system emojis for a more consistent browsing experience.',
description: 'A Chrome extension that removes the emoji reaction button in Gmail™.',
techStack: ['JavaScript', 'Chrome Extension'],
openSource: true,
links: [githubLink('evowizz/De-Gmojify')],
},
{
title: 'Actio',
description:
'A small Figma plugin for resizing frames and rectangles based on aspect ratios with the purpose of eliminating manual dimension calculations.',
description: 'A Figma plugin that resizes frames to an aspect ratio, so nobody does the math by hand.',
techStack: ['TypeScript', 'Figma Plugin API'],
openSource: false,
links: [],
},
{
title: 'Compose to Edge',
description:
'Edge-to-edge display implementation for Android apps using Jetpack Compose, providing a modern full-screen experience.',
techStack: ['Kotlin', 'Jetpack Compose', 'Android'],
openSource: true,
deprecated: true,
links: [githubLink('evowizz/compose-to-edge')],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Image from 'next/image'
import { Label } from '@/components/ui/typography'
import { Reveal } from '@/components/ui/reveal'

export type CaseStudyMeta = {
type CaseStudyMeta = {
title: string
overview: string
stack: string[]
Expand Down
5 changes: 2 additions & 3 deletions src/components/debug/selection.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type SelectedEntry = {
type SelectedEntry = {
element: Element
selector: string
}
Expand All @@ -12,8 +12,7 @@ export type RegionBounds = {
}

export type Selection =
| ({ kind: 'element' } & SelectedEntry)
| ({ kind: 'region'; elements: SelectedEntry[] } & RegionBounds)
({ kind: 'element' } & SelectedEntry) | ({ kind: 'region'; elements: SelectedEntry[] } & RegionBounds)

export const isDevtoolNode = (element: Element) =>
element.closest('[data-devbar]') !== null ||
Expand Down
2 changes: 0 additions & 2 deletions src/components/ui/video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,5 +155,3 @@ const DimButton = forwardRef<HTMLButtonElement, DimButtonProps>(({ className, ac
})

DimButton.displayName = 'DimButton'

export { PlayPauseButton, DimButton }
2 changes: 1 addition & 1 deletion src/lib/mcu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const COLOR_REGEX = /^#?([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i

const STANDARD_TONES = [5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 95]

export type TonalPaletteName = (typeof TARGETS)[number]
type TonalPaletteName = (typeof TARGETS)[number]

export type PaletteRequest = {
base: string
Expand Down
2 changes: 1 addition & 1 deletion src/theme/material.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {

export { Hct, Variant, argbFromHex, argbFromRgb, hexFromArgb, redFromArgb, greenFromArgb, blueFromArgb }

export type SpecVersion = '2021' | '2025'
type SpecVersion = '2021' | '2025'

export type Theme = {
source: number
Expand Down
Loading