diff --git a/README.md b/README.md index 49a78ba4b..416f80233 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,8 @@ Transform your GitHub contribution history into a cinematic 3D monolith. | `lumos` | Void black & mint gold | `0a0a0a` | `fbbf24` | `a7f3d0` | | `tokyo_night` | Deep navy & soft pastel blue | `1a1b26` | `7aa2f7` | `c0caf5` | | `monokai` | Classic vibrant dark | `272822` | `a6e22e` | `f8f8f2` | +| `sakura` | Cherry blossom inspired | `1a1225` | `f472b6` | `f5e6f0` | +| `midnight_ember` | Warm campfire dark | `0c1222` | `e85d26` | `e8d5c4` | | `midnight_ocean` | Deep navy bioluminescent | `020c1b` | `0af5ff` | `ccd6f6` | | `india` | Saffron & India green | `0a0a0a` | `FF9933` | `ffffff` | | `ocean` | Deep sea teal & navy | `0a192f` | `64ffda` | `ccd6f6` | diff --git a/components/InteractiveViewer.tsx b/components/InteractiveViewer.tsx index ba6c65a49..0f29e9459 100644 --- a/components/InteractiveViewer.tsx +++ b/components/InteractiveViewer.tsx @@ -25,20 +25,23 @@ interface ParallaxParticle { * Deterministic math prevents random values from causing SSR/CSR mismatches. */ function buildParticles(): ParallaxParticle[] { const colors = ['#10b981', '#8b5cf6', '#06b6d4', '#3b82f6', '#f59e0b']; - return Array.from({ length: PARALLAX_PARTICLE_COUNT }, (_, i): ParallaxParticle => ({ - id: i, - // Spread particles across the container using prime-number strides - x: (i * 17 + 11) % 100, - y: (i * 23 + 7) % 100, - size: 4 + (i % 5) * 2, // range: 4–12 px - // Keep opacity low so particles never obscure the badge - opacity: 0.05 + (i % 4) * 0.025, // range: 0.05–0.125 - // Vary depth so each "layer" of particles shifts by a different amount, - // creating the illusion of 3-D depth. depth 0.1 = farthest; 0.7 = nearest. - depth: 0.1 + (i % 6) * 0.1, // range: 0.1–0.6 - color: colors[i % colors.length], - isCircle: i % 4 === 0, - })); + return Array.from( + { length: PARALLAX_PARTICLE_COUNT }, + (_, i): ParallaxParticle => ({ + id: i, + // Spread particles across the container using prime-number strides + x: (i * 17 + 11) % 100, + y: (i * 23 + 7) % 100, + size: 4 + (i % 5) * 2, // range: 4–12 px + // Keep opacity low so particles never obscure the badge + opacity: 0.05 + (i % 4) * 0.025, // range: 0.05–0.125 + // Vary depth so each "layer" of particles shifts by a different amount, + // creating the illusion of 3-D depth. depth 0.1 = farthest; 0.7 = nearest. + depth: 0.1 + (i % 6) * 0.1, // range: 0.1–0.6 + color: colors[i % colors.length], + isCircle: i % 4 === 0, + }) + ); } // How many pixels a depth-1.0 particle shifts when the cursor is at the @@ -399,29 +402,31 @@ export default function InteractiveViewer({ Each particle shifts by (parallaxX * depth, parallaxY * depth) px relative to its base position, so "closer" particles (higher depth) shift more — creating the impression of a multi-layered isometric space. */} - {particles.map((particle): ReactElement => ( -
- ))} + {particles.map( + (particle): ReactElement => ( + + ) + )} {/* ── Card content ────────────────────────────────────────────────────── diff --git a/components/burnout/BurnoutRiskTable.tsx b/components/burnout/BurnoutRiskTable.tsx index 4495276d9..c276cd649 100644 --- a/components/burnout/BurnoutRiskTable.tsx +++ b/components/burnout/BurnoutRiskTable.tsx @@ -34,7 +34,12 @@ interface BurnoutRiskTableProps { } type SortColumn = - 'username' | 'commitShare' | 'highIntensityWeeks' | 'restWeeks' | 'burnoutScore' | 'totalCommits'; + | 'username' + | 'commitShare' + | 'highIntensityWeeks' + | 'restWeeks' + | 'burnoutScore' + | 'totalCommits'; type SortDirection = 'asc' | 'desc'; // Custom Pure SVG Sparkline for visual performance diff --git a/docs/customization.md b/docs/customization.md index fcbf197fe..bc88a0253 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -59,44 +59,44 @@ URL Parameter > Theme Default > System Fallback > All parameters below are optional except `user`. Append them to the base URL as query string key-value pairs (e.g. `?user=YOUR_USERNAME&theme=neon&size=large`). Boolean parameters accept `true` or `false`. Hex color values are provided **without** the `#` prefix. -| Parameter | Description | Default | Allowed Values / Constraints | Example | +| Parameter | Description | Default | Allowed Values / Constraints | Example | | ----------------- | ----------------------------------------------------------------------------------------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | --- | ---------- | ----------------------------- | ------ | ------------------------------- | ---------------- | -| `user` | GitHub username to render (Required) | — | Any valid GitHub username | `?user=jhasourav07` | -| `theme` | Preset theme name | `dark` | `auto`, `dark`, `neon`, `dracula`, `github`, `light`, `gruvbox`, `random`, etc. | `?theme=dracula` | -| `bg` | Background color | Theme default | Hex color code (without `#`) | `?bg=0d1117` | -| `accent` | Tower & glow color | Theme default | Hex color code (without `#`) | `?accent=58a6ff` | -| `text` | Label & stat text color | Theme default | Hex color code (without `#`) | `?text=c9d1d9` | -| `radius` | Border corner radius in pixels | `8` | Numeric value | `?radius=16` | -| `border` | Custom stroke color around the SVG container | — | Hex color code (without `#`) | `?border=ff0000` | -| `speed` | Radar scan duration | `8s` | `2s`–`20s` | `?speed=4s` | -| `scale` | Tower height scaling | `linear` | `linear`, `log`, `sqrt` | `?scale=sqrt` | -| `size` | Badge dimensions | `medium` | `small`, `medium`, `large` | `?size=large` | -| `font` | Custom font for text | Default typography | Any valid Google Font name | `?font=Orbitron` | -| `refresh` | Bypass cache for real-time data | `false` | `true`, `false` | `?refresh=true` | -| `year` | Calendar year to render | Current year | `2023`, `2024`, etc. | `?year=2023` | -| `hide_title` | Hide GitHub username/title | `false` | `true`, `false` | `?hide_title=true` | -| `custom_title` | Custom header title text | — | Any text string (XML-escaped) | `?custom_title=My%20Pulse` | -| `custom_subtitle` | Custom subtitle text right below title | — | Any text string (XML-escaped) | `?custom_subtitle=Dev` | -| `hide_background` | Remove the background rect | `false` | `true`, `false` | `?hide_background=true` | -| `hide_stats` | Hide bottom row displaying stats | `false` | `true`, `false` | `?hide_stats=true` | -| `tz` | IANA timezone | `UTC` | Valid IANA timezone | `?tz=Asia/Kolkata` | -| `lang` | Language code for labels | `en` | `en`, `es`, `hi`, `fr`, `pt`, `ko`, `ja`, `de`, `zh` | `?lang=hi` | -| `view` | Rendering mode | `default` | `default`, `monthly`, `heatmap`, `pulse`, `skyline`, `languages`, `constellation`, `weekday`, `radar`, `doughnut`, `pie`, `activity_graph`, `commit_clock` | `?view=commit_clock` | | `entrance` | Entrance animation for towers | `rise` | `rise`, `fade`, `slide`, `none` | `?entrance=fade` | -| `delta_format` | Month-over-month delta format (`view=monthly`) | `percent` | `percent`, `absolute`, `both` | `?delta_format=absolute` | -| `width` | Custom width for SVG canvas (`view=monthly`, `pulse`, `skyline`) | `300` | Numeric value | `?width=400` | -| `height` | Custom height for SVG canvas (`view=monthly`, `pulse`, `skyline`) | `120` | Numeric value | `?height=150` | -| `grace` | Grace period in days before streak resets (see [Grace Period Examples](#grace-period-examples)) | `1` | `0`–`7` | `?grace=2` | -| `mode` | Base data rendering mode | `commits` | `commits`, `loc` | `?mode=loc` | -| `repo` | Render monolith for a specific repository | — | `owner/repo` | `?repo=vercel/next.js` | -| `org` | Organization name to generate a Mega-City for | — | Valid GitHub organization name | `?org=vercel` | -| `labels` | Render optional isometric month/weekday labels | `false` | `true`, `false` | `?labels=true` | -| `labelColor` | Custom text color for isometric labels | — | Hex color code (without `#`) | `?labelColor=ffffff` | -| `versus` | Compare against an opponent side-by-side | — | Any valid GitHub username | `?versus=octocat` | -| `shading` | Apply intensity-based opacity shading to tower faces | `false` | `true`, `false` | `?shading=true` | -| `dim_weekends` | Dim weekend towers (Saturdays and Sundays) | `false` | `true`, `false` | `?dim_weekends=true` | -| `opacity` | Global opacity scalar for tower fill | `1.0` | `0.1`–`1.0` | `?opacity=0.8` | -| `gradient` | Show volumetric gradients on the floor | `false` | `true`, `false` | `?gradient=true` | -| `minify` | Enable SVG minification and payload optimization | `true` | `true`, `false` | `?minify=false` | +| `user` | GitHub username to render (Required) | — | Any valid GitHub username | `?user=jhasourav07` | +| `theme` | Preset theme name | `dark` | `auto`, `dark`, `neon`, `dracula`, `github`, `light`, `gruvbox`, `random`, etc. | `?theme=dracula` | +| `bg` | Background color | Theme default | Hex color code (without `#`) | `?bg=0d1117` | +| `accent` | Tower & glow color | Theme default | Hex color code (without `#`) | `?accent=58a6ff` | +| `text` | Label & stat text color | Theme default | Hex color code (without `#`) | `?text=c9d1d9` | +| `radius` | Border corner radius in pixels | `8` | Numeric value | `?radius=16` | +| `border` | Custom stroke color around the SVG container | — | Hex color code (without `#`) | `?border=ff0000` | +| `speed` | Radar scan duration | `8s` | `2s`–`20s` | `?speed=4s` | +| `scale` | Tower height scaling | `linear` | `linear`, `log`, `sqrt` | `?scale=sqrt` | +| `size` | Badge dimensions | `medium` | `small`, `medium`, `large` | `?size=large` | +| `font` | Custom font for text | Default typography | Any valid Google Font name | `?font=Orbitron` | +| `refresh` | Bypass cache for real-time data | `false` | `true`, `false` | `?refresh=true` | +| `year` | Calendar year to render | Current year | `2023`, `2024`, etc. | `?year=2023` | +| `hide_title` | Hide GitHub username/title | `false` | `true`, `false` | `?hide_title=true` | +| `custom_title` | Custom header title text | — | Any text string (XML-escaped) | `?custom_title=My%20Pulse` | +| `custom_subtitle` | Custom subtitle text right below title | — | Any text string (XML-escaped) | `?custom_subtitle=Dev` | +| `hide_background` | Remove the background rect | `false` | `true`, `false` | `?hide_background=true` | +| `hide_stats` | Hide bottom row displaying stats | `false` | `true`, `false` | `?hide_stats=true` | +| `tz` | IANA timezone | `UTC` | Valid IANA timezone | `?tz=Asia/Kolkata` | +| `lang` | Language code for labels | `en` | `en`, `es`, `hi`, `fr`, `pt`, `ko`, `ja`, `de`, `zh` | `?lang=hi` | +| `view` | Rendering mode | `default` | `default`, `monthly`, `heatmap`, `pulse`, `skyline`, `languages`, `constellation`, `weekday`, `radar`, `doughnut`, `pie`, `activity_graph`, `commit_clock` | `?view=commit_clock` | | `entrance` | Entrance animation for towers | `rise` | `rise`, `fade`, `slide`, `none` | `?entrance=fade` | +| `delta_format` | Month-over-month delta format (`view=monthly`) | `percent` | `percent`, `absolute`, `both` | `?delta_format=absolute` | +| `width` | Custom width for SVG canvas (`view=monthly`, `pulse`, `skyline`) | `300` | Numeric value | `?width=400` | +| `height` | Custom height for SVG canvas (`view=monthly`, `pulse`, `skyline`) | `120` | Numeric value | `?height=150` | +| `grace` | Grace period in days before streak resets (see [Grace Period Examples](#grace-period-examples)) | `1` | `0`–`7` | `?grace=2` | +| `mode` | Base data rendering mode | `commits` | `commits`, `loc` | `?mode=loc` | +| `repo` | Render monolith for a specific repository | — | `owner/repo` | `?repo=vercel/next.js` | +| `org` | Organization name to generate a Mega-City for | — | Valid GitHub organization name | `?org=vercel` | +| `labels` | Render optional isometric month/weekday labels | `false` | `true`, `false` | `?labels=true` | +| `labelColor` | Custom text color for isometric labels | — | Hex color code (without `#`) | `?labelColor=ffffff` | +| `versus` | Compare against an opponent side-by-side | — | Any valid GitHub username | `?versus=octocat` | +| `shading` | Apply intensity-based opacity shading to tower faces | `false` | `true`, `false` | `?shading=true` | +| `dim_weekends` | Dim weekend towers (Saturdays and Sundays) | `false` | `true`, `false` | `?dim_weekends=true` | +| `opacity` | Global opacity scalar for tower fill | `1.0` | `0.1`–`1.0` | `?opacity=0.8` | +| `gradient` | Show volumetric gradients on the floor | `false` | `true`, `false` | `?gradient=true` | +| `minify` | Enable SVG minification and payload optimization | `true` | `true`, `false` | `?minify=false` | --- diff --git a/lib/svg/themes.test.ts b/lib/svg/themes.test.ts index 66b35c753..781e8640c 100644 --- a/lib/svg/themes.test.ts +++ b/lib/svg/themes.test.ts @@ -41,11 +41,11 @@ describe('themes object', () => { // ── Theme count ─────────────────────────────────────────────────────────────── describe('theme count', () => { - it('contains exactly 35 preset themes matching THEMES.md documentation', () => { + it('contains exactly 37 preset themes matching THEMES.md documentation', () => { // If this fails, either a theme was added to themes.ts without updating // THEMES.md, or a theme was removed without updating the docs. // Update this count when intentionally adding/removing themes. - expect(themeNames).toHaveLength(35); + expect(themeNames).toHaveLength(37); }); it('contains all expected theme keys', () => { @@ -79,6 +79,8 @@ describe('theme count', () => { 'cyberpunk_neon', 'tokyo_night', 'monokai', + 'sakura', + 'midnight_ember', 'midnight_ocean', 'india', 'catppuccin_mocha', diff --git a/lib/svg/themes.ts b/lib/svg/themes.ts index 2736fb70b..ca652c6bc 100644 --- a/lib/svg/themes.ts +++ b/lib/svg/themes.ts @@ -62,6 +62,8 @@ export const themes: Record