diff --git a/.astro/content.d.ts b/.astro/content.d.ts index 95d49b5..b031d0e 100644 --- a/.astro/content.d.ts +++ b/.astro/content.d.ts @@ -180,5 +180,5 @@ declare module 'astro:content' { type AnyEntryMap = ContentEntryMap & DataEntryMap; - export type ContentConfig = typeof import("./../src/content.config.js"); + export type ContentConfig = typeof import("../src/content.config.js"); } diff --git a/domain.code-workspace b/domain.code-workspace index e312ba8..5f04c3e 100644 --- a/domain.code-workspace +++ b/domain.code-workspace @@ -170,6 +170,7 @@ }, "zenMode.centerLayout": false, "cSpell.words": [ + "Boisu", "Poorna", "Socie", "withastro" @@ -195,6 +196,6 @@ "titleBar.inactiveBackground": "#01001099", "titleBar.inactiveForeground": "#e7e7e799", "tab.activeBorder": "#040043" - }, + } } } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index cf75da6..63ddaa9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,10 @@ "@astrojs/react": "4.1.2", "@astrojs/rss": "4.0.11", "@astrojs/tailwind": "5.1.4", + "@fontsource/orbitron": "5.2.8", "@fontsource/roboto": "5.1.0", + "@fontsource/sora": "5.2.8", + "@fontsource/space-grotesk": "5.2.10", "@radix-ui/react-slot": "1.1.1", "astro": "5.1.1", "astro-aws-amplify": "0.1.0", @@ -1248,12 +1251,39 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@fontsource/orbitron": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@fontsource/orbitron/-/orbitron-5.2.8.tgz", + "integrity": "sha512-ruzrDl5vnqNykk5DZWY0Ezj4aeFZSbCnwJTc/98ojNJHSsHhlhT2r7rwQrA5sptmF8JtB8TQTAvlfRvcV28RPw==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, "node_modules/@fontsource/roboto": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-5.1.0.tgz", "integrity": "sha512-cFRRC1s6RqPygeZ8Uw/acwVHqih8Czjt6Q0MwoUoDe9U3m4dH1HmNDRBZyqlMSFwgNAUKgFImncKdmDHyKpwdg==", "license": "Apache-2.0" }, + "node_modules/@fontsource/sora": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@fontsource/sora/-/sora-5.2.8.tgz", + "integrity": "sha512-1G6iTXUx8rcCKzi3mjaTQ1DE8PQz0OmW3Qnku+64S+bqRr1o/gGeiw8fxIQhhBU9ZP8ZofIqai7o00DNOPnlDw==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, + "node_modules/@fontsource/space-grotesk": { + "version": "5.2.10", + "resolved": "https://registry.npmjs.org/@fontsource/space-grotesk/-/space-grotesk-5.2.10.tgz", + "integrity": "sha512-XNXEbT74OIITPqw2H6HXwPDp85fy43uxfBwFR5PU+9sLnjuLj12KlhVM9nZVN6q6dlKjkuN8JisW/OBxwxgUew==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", diff --git a/package.json b/package.json index 21ae18b..570de51 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,10 @@ "@astrojs/react": "4.1.2", "@astrojs/rss": "4.0.11", "@astrojs/tailwind": "5.1.4", + "@fontsource/orbitron": "5.2.8", "@fontsource/roboto": "5.1.0", + "@fontsource/sora": "5.2.8", + "@fontsource/space-grotesk": "5.2.10", "@radix-ui/react-slot": "1.1.1", "astro": "5.1.1", "astro-aws-amplify": "0.1.0", @@ -102,4 +105,4 @@ "prettier-plugin-astro": "0.14.1", "prettier-plugin-tailwindcss": "0.6.8" } -} \ No newline at end of file +} diff --git a/public/assets/fonts/Boisu-Stroke.woff2 b/public/assets/fonts/Boisu-Stroke.woff2 new file mode 100644 index 0000000..c07832b Binary files /dev/null and b/public/assets/fonts/Boisu-Stroke.woff2 differ diff --git a/public/theme.js b/public/theme.js index 3578f4a..c84aa95 100644 --- a/public/theme.js +++ b/public/theme.js @@ -1,7 +1,7 @@ -(function () { - const savedTheme = localStorage.getItem("theme"); - console.log("Saved theme:", savedTheme); - if (savedTheme) { - document.documentElement.setAttribute("data-theme", savedTheme); - } -})(); +(function () { + const savedTheme = localStorage.getItem("theme"); + console.log("Saved theme:", savedTheme); + if (savedTheme) { + document.documentElement.setAttribute("data-theme", savedTheme); + } +})(); diff --git a/src/assets/fonts/Boisu-Stroke.otf b/src/assets/fonts/Boisu-Stroke.otf new file mode 100644 index 0000000..71b9051 Binary files /dev/null and b/src/assets/fonts/Boisu-Stroke.otf differ diff --git a/src/assets/images/fabric-ai.png b/src/assets/images/fabric-ai.png new file mode 100644 index 0000000..a0d3570 Binary files /dev/null and b/src/assets/images/fabric-ai.png differ diff --git a/src/assets/images/logo.png b/src/assets/images/logo.png new file mode 100644 index 0000000..5c7f213 Binary files /dev/null and b/src/assets/images/logo.png differ diff --git a/src/assets/projects/abcdkbd.png b/src/assets/projects/abcdkbd.png new file mode 100644 index 0000000..1024521 Binary files /dev/null and b/src/assets/projects/abcdkbd.png differ diff --git a/src/assets/projects/letter.png b/src/assets/projects/letter.png new file mode 100644 index 0000000..fc3e821 Binary files /dev/null and b/src/assets/projects/letter.png differ diff --git a/src/assets/projects/threadzip.png b/src/assets/projects/threadzip.png new file mode 100644 index 0000000..2ed86e2 Binary files /dev/null and b/src/assets/projects/threadzip.png differ diff --git a/src/assets/styles/card.css b/src/assets/styles/card.css index 254d778..560325e 100644 --- a/src/assets/styles/card.css +++ b/src/assets/styles/card.css @@ -2,42 +2,67 @@ list-style: none; display: flex; padding: 1px; - background-color: #23262d; - background-image: none; - background-size: 400%; - border-radius: 7px; - background-position: 100%; - transition: background-position 0.6s cubic-bezier(0.22, 1, 0.36, 1); - box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1); + + /* 🌗 Theme based background */ + background-color: hsl(var(--background)); + + border-radius: 8px; + overflow: hidden; + + /* subtle border effect */ + box-shadow: inset 0 0 0 1px hsl(var(--foreground) / 0.1); + + transition: all 0.3s ease; } .link-card > a { width: 100%; text-decoration: none; line-height: 1.4; + padding: calc(1.5rem - 1px); border-radius: 8px; - color: white; - background-color: #23262d; - opacity: 0.8; + + /* 🌗 Theme colors */ + background-color: hsl(var(--background)); + color: hsl(var(--foreground)); + + transition: all 0.3s ease; } -h2 { +/* Title */ +.link-card h2 { margin: 0; font-size: 1.25rem; - transition: color 0.6s cubic-bezier(0.22, 1, 0.36, 1); + font-weight: 600; + + color: hsl(var(--foreground)); + + transition: color 0.3s ease; } -p { +/* Description */ +.link-card p { margin-top: 0.5rem; margin-bottom: 0; -} -.link-card:is(:hover, :focus-within) { - background-position: 0; - background-image: var(--accent-gradient); + color: hsl(var(--foreground) / 0.7); + font-size: 0.95rem; + line-height: 1.6; } -.link-card:is(:hover, :focus-within) h2 { - color: rgb(var(--accent-light)); +/* Hover effect */ +.link-card:hover, +.link-card:focus-within { + transform: translateY(-4px); + + /* subtle highlight */ + box-shadow: + inset 0 0 0 1px hsl(var(--foreground) / 0.15), + 0 10px 30px -10px hsl(var(--foreground) / 0.2); } + +/* Hover title color */ +.link-card:hover h2 { + color: rgb(var(--accent)); +} \ No newline at end of file diff --git a/src/assets/styles/career.css b/src/assets/styles/career.css index f9d7ddb..8d3b0db 100644 --- a/src/assets/styles/career.css +++ b/src/assets/styles/career.css @@ -121,4 +121,4 @@ .careers__container { padding: 0 2rem; } -} \ No newline at end of file +} diff --git a/src/assets/styles/custom-font.css b/src/assets/styles/custom-font.css index 51fd085..fbd5a7a 100644 --- a/src/assets/styles/custom-font.css +++ b/src/assets/styles/custom-font.css @@ -1,7 +1,9 @@ /* src/styles/custom-font.css */ + + @font-face { - font-family: "Mudra"; - src: url("/assets/fonts/MudraMohta-Regular.ttf") format("truetype"); + font-family: "Boisu"; + src: url("../assets/fonts/Boisu-Stroke.woff2") format("woff2"); font-weight: normal; font-style: normal; -} +} \ No newline at end of file diff --git a/src/assets/styles/globals.css b/src/assets/styles/globals.css index d1326e7..967578f 100644 --- a/src/assets/styles/globals.css +++ b/src/assets/styles/globals.css @@ -1,22 +1,31 @@ -/*@import "./custom-font.css";*/ @tailwind base; @tailwind components; @tailwind utilities; @layer base { :root { - --font-size-min: 16; --font-size-max: 20; --font-ratio-min: 1.2; --font-ratio-max: 1.33; --font-width-min: 375; --font-width-max: 1500; + + /* 🎨 LIGHT THEME */ + --background: 0 0% 100%; + --foreground: 222 47% 11%; + --accent: 136, 58, 234; --accent-light: 224, 204, 250; --accent-dark: 49, 10, 101; } - + + /* 🌙 DARK THEME */ + .dark { + --background: 222 47% 11%; + --foreground: 0 0% 100%; + } + html { color-scheme: light dark; height: 100%; @@ -39,28 +48,38 @@ overflow-x: hidden; display: block; font-family: "Roboto", "SF Pro Text", "Helvetica Neue", Arial, sans-serif; - transition: background-color 0.3s ease; - + + background: hsl(var(--background)); + color: hsl(var(--foreground)); + + transition: background-color 0.3s ease, color 0.3s ease; } - /* Grid Background */ + /* ❌ LIGHT MODE → NO GRID */ body::before { - --size: 45px; - --line: rgba(255, 255, 255, 0.06); + display: none; + } + + /* ✅ DARK MODE → GRID */ + .dark body::before { content: ""; position: fixed; inset: 0; width: 100%; height: 100%; - background: - linear-gradient(90deg, var(--line) 1px, transparent 1px), + + --size: 45px; + --line: rgba(255, 255, 255, 0.06); + + background: linear-gradient(90deg, var(--line) 1px, transparent 1px), linear-gradient(var(--line) 1px, transparent 1px); + background-size: var(--size) var(--size); + pointer-events: none; z-index: -1; } - /* MAIN FIX */ main { display: block !important; width: 100% !important; @@ -90,16 +109,6 @@ resize: none; } - .whiteBg { - background: #ffffff; - color: #111111; - } - - .darkBg { - background: #050505; - color: #ffffff; - } - .yellowBtnHover:hover { background-color: #d4a900; } diff --git a/src/assets/styles/markdown-content.css b/src/assets/styles/markdown-content.css index d67602a..2141c51 100644 --- a/src/assets/styles/markdown-content.css +++ b/src/assets/styles/markdown-content.css @@ -1,105 +1,120 @@ .markdown-content { font-size: 1.125rem; line-height: 1.75; - color: rgb(229, 231, 235); - background-color: rgba(0, 0, 0, 0.5); - padding: 3rem 6rem; - border-radius: 1rem; + color: inherit; + background-color: transparent; + padding: 0; + border-radius: 0; } +/* Headings */ .markdown-content h1 { margin-bottom: 2rem; font-size: 2.25rem; - font-weight: bold; + font-weight: 700; letter-spacing: -0.025em; - background: linear-gradient(120deg, #75aac3, #8fb5b9); - -webkit-background-clip: text; - background-clip: text; - color: transparent; - text-shadow: 0 2px 10px rgba(139, 92, 246, 0.2); + color: inherit; } .markdown-content h2 { - margin-bottom: 1.5rem; margin-top: 3rem; - font-size: 1.5rem; - font-weight: 600; - background: linear-gradient(120deg, #75aac3, #8fb5b9); - -webkit-background-clip: text; - background-clip: text; - color: transparent; - text-shadow: 0 2px 8px rgba(167, 139, 250, 0.2); + margin-bottom: 1.5rem; + font-size: 1.75rem; + font-weight: 700; + color: inherit; } .markdown-content h3 { - margin-bottom: 1rem; margin-top: 2rem; - font-size: 1.25rem; + margin-bottom: 1rem; + font-size: 1.35rem; font-weight: 600; - background: linear-gradient(120deg, #75aac3, #8fb5b9); - -webkit-background-clip: text; - background-clip: text; - color: transparent; - text-shadow: 0 2px 6px rgba(196, 181, 253, 0.2); + color: inherit; } +/* Paragraphs */ .markdown-content p { margin-bottom: 1.5rem; - line-height: 1.75; - color: rgb(209, 213, 219); + line-height: 1.9; + color: inherit; } -.markdown-content ul { - margin-bottom: 1.5rem; - list-style-type: disc; +/* Lists */ +.markdown-content ul, +.markdown-content ol { + margin: 1.5rem 0; padding-left: 1.5rem; } +.markdown-content ul { + list-style: disc; +} + .markdown-content ol { - margin-bottom: 1.5rem; - list-style-type: decimal; - padding-left: 1.5rem; + list-style: decimal; } .markdown-content li { margin-bottom: 0.5rem; } +/* Links */ .markdown-content a { - color: rgb(96, 165, 250); - text-decoration: underline; + color: #06b6d4; + text-decoration: none; + font-weight: 500; } .markdown-content a:hover { - color: rgb(147, 197, 253); + text-decoration: underline; } +/* Images */ .markdown-content img { - margin-top: 2rem; - margin-bottom: 2rem; - border-radius: 0.5rem; - box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); + margin: 2rem 0; + border-radius: 1rem; } +/* Code block */ .markdown-content pre { - margin-top: 1.5rem; - margin-bottom: 1.5rem; + margin: 1.5rem 0; overflow-x: auto; - border-radius: 0.75rem; - background-color: rgba(31, 41, 55, 0.5); + border-radius: 1rem; padding: 1rem; + background: rgba(100, 100, 100, 0.08); } +/* Inline code */ .markdown-content code { - border-radius: 0.25rem; - padding: 0.125rem 0.375rem; - font-size: 0.875rem; - color: rgb(229, 231, 235); + border-radius: 0.35rem; + padding: 0.15rem 0.4rem; + font-size: 0.9rem; } +/* Quote */ .markdown-content blockquote { - border-left: 4px solid rgb(75, 85, 99); + border-left: 4px solid #06b6d4; padding-left: 1rem; + margin: 1.5rem 0; font-style: italic; - color: rgb(156, 163, 175); + opacity: 0.8; } + +/* Mobile */ +@media (max-width: 768px) { + .markdown-content { + font-size: 1rem; + } + + .markdown-content h1 { + font-size: 2rem; + } + + .markdown-content h2 { + font-size: 1.5rem; + } + + .markdown-content h3 { + font-size: 1.25rem; + } +} \ No newline at end of file diff --git a/src/assets/styles/menu.css b/src/assets/styles/menu.css index 459d9d4..df26ea1 100644 --- a/src/assets/styles/menu.css +++ b/src/assets/styles/menu.css @@ -8,25 +8,27 @@ --header-height: 80px; --sidebar-width: 16ch; --timing: 0.42s; - --ease: linear(0 0%, - 0.0036 9.62%, - 0.0185 16.66%, - 0.0489 23.03%, - 0.0962 28.86%, - 0.1705 34.93%, - 0.269 40.66%, - 0.3867 45.89%, - 0.5833 52.95%, - 0.683 57.05%, - 0.7829 62.14%, - 0.8621 67.46%, - 0.8991 70.68%, - 0.9299 74.03%, - 0.9545 77.52%, - 0.9735 81.21%, - 0.9865 85%, - 0.9949 89.15%, - 1 100%); + --ease: linear( + 0 0%, + 0.0036 9.62%, + 0.0185 16.66%, + 0.0489 23.03%, + 0.0962 28.86%, + 0.1705 34.93%, + 0.269 40.66%, + 0.3867 45.89%, + 0.5833 52.95%, + 0.683 57.05%, + 0.7829 62.14%, + 0.8621 67.46%, + 0.8991 70.68%, + 0.9299 74.03%, + 0.9545 77.52%, + 0.9735 81.21%, + 0.9865 85%, + 0.9949 89.15%, + 1 100% + ); } .layout { @@ -339,7 +341,6 @@ } } - [data-theme="system"] .theme-toggle use[href="#icon-system"], [data-theme="light"] .theme-toggle use[href="#icon-sun"], [data-theme="dark"] .theme-toggle use[href="#icon-moon"] { @@ -369,8 +370,6 @@ display: none; } - - [data-theme="light"] .placement-toggle, [data-theme="system"] .placement-toggle { color: black; @@ -383,4 +382,4 @@ [data-debug="false"] .debug-toggle g:first-of-type { display: block; } -} \ No newline at end of file +} diff --git a/src/assets/styles/theme.css b/src/assets/styles/theme.css index f79d78a..3482627 100644 --- a/src/assets/styles/theme.css +++ b/src/assets/styles/theme.css @@ -1,70 +1,67 @@ -@layer normalize, base, demo, inversion; - -@layer inversion { - - /* ::before === clouds, ::after === stars */ - @media (prefers-color-scheme: light) { - - [data-invert='true']::after, - [data-invert='false']::before { - opacity: 1; - } - - [data-invert='true']::before, - [data-invert='false']::after { - opacity: 0.1; - } - } - - @media (prefers-color-scheme: dark) { - - [data-invert='true']::before, - [data-invert='false']::after { - opacity: 1; - background-position: 0% 50%; - } - - [data-invert='true']::after, - [data-invert='false']::before { - opacity: 0; - } - } - - [data-invert='true'][data-theme='light']::before { - opacity: 0.1; - background-position: 50% 50%; - } - - [data-invert='true'][data-theme='dark']::before { - opacity: 1; - background-position: 0% 50%; - } - - [data-invert='true'][data-theme='light']::after, - [data-invert='false'][data-theme='dark']::after { - opacity: 1; - } - - [data-invert='false'][data-theme='light']::after, - [data-invert='true'][data-theme='dark']::after { - opacity: 0; - } - - [data-invert='false'][data-theme='light']::before { - opacity: 1; - background-position: 50% 50%; - } - - [data-invert='false'][data-theme='dark']::before { - opacity: 0.1; - background-position: 0% 50%; - } - - [data-invert='true'] { - background: light-dark(#01022e, #34d0ff); - } - - [data-invert='false'] { - background: light-dark(#34d0ff, #01022e); - } -} \ No newline at end of file +@layer normalize, base, demo, inversion; + +@layer inversion { + /* ::before === clouds, ::after === stars */ + @media (prefers-color-scheme: light) { + [data-invert="true"]::after, + [data-invert="false"]::before { + opacity: 1; + } + + [data-invert="true"]::before, + [data-invert="false"]::after { + opacity: 0.1; + } + } + + @media (prefers-color-scheme: dark) { + [data-invert="true"]::before, + [data-invert="false"]::after { + opacity: 1; + background-position: 0% 50%; + } + + [data-invert="true"]::after, + [data-invert="false"]::before { + opacity: 0; + } + } + + [data-invert="true"][data-theme="light"]::before { + opacity: 0.1; + background-position: 50% 50%; + } + + [data-invert="true"][data-theme="dark"]::before { + opacity: 1; + background-position: 0% 50%; + } + + [data-invert="true"][data-theme="light"]::after, + [data-invert="false"][data-theme="dark"]::after { + opacity: 1; + } + + [data-invert="false"][data-theme="light"]::after, + [data-invert="true"][data-theme="dark"]::after { + opacity: 0; + } + + [data-invert="false"][data-theme="light"]::before { + opacity: 1; + background-position: 50% 50%; + } + + [data-invert="false"][data-theme="dark"]::before { + opacity: 0.1; + background-position: 0% 50%; + } + + [data-invert="true"] { + background: light-dark(#01022e, #34d0ff); + } + + [data-invert="false"] { + background: light-dark(#34d0ff, #01022e); + } +} diff --git a/src/components/AboutSection.astro b/src/components/AboutSection.astro index c00809e..6c28d5c 100644 --- a/src/components/AboutSection.astro +++ b/src/components/AboutSection.astro @@ -3,9 +3,8 @@ import image from "@/assets/images/about.jpg"; import { Image } from "astro:assets"; --- -
+
-
@@ -20,7 +19,7 @@ import { Image } from "astro:assets"; Drive Results. -

+

Recursive Zero crafts high-performance web apps, internal tools, and scalable digital solutions that simplify operations and accelerate business growth. @@ -28,23 +27,26 @@ import { Image } from "astro:assets";

-
+
✓ Fast Delivery ✓ Scalable ✓ Client-Focused @@ -54,16 +56,16 @@ import { Image } from "astro:assets";
+
Dashboard Preview
-
\ No newline at end of file diff --git a/src/components/AppsSimplifySection.astro b/src/components/AppsSimplifySection.astro index f64704d..ad73127 100644 --- a/src/components/AppsSimplifySection.astro +++ b/src/components/AppsSimplifySection.astro @@ -1,63 +1,12 @@ - - - --- import workplace from "@/assets/images/workplace.jpg"; import { Image } from "astro:assets"; --- -
+
-
- +

@@ -69,39 +18,40 @@ import { Image } from "astro:assets"; with handy mini apps -

- Based in Bengaluru, Recursive Zero creates compact yet powerful apps - designed to streamline your workflow, improve storage efficiency, - and enhance everyday productivity. +

+ Based in Bengaluru, Recursive Zero creates compact yet powerful apps designed to streamline your workflow, + improve storage efficiency, and enhance everyday productivity.

-

- Our solutions combine simplicity with smart technology, helping - users and businesses achieve more with less effort. +

+ Our solutions combine simplicity with smart technology, helping users and businesses achieve more with less + effort.

-
-

Fast & Lightweight

-

+ +

+

Fast & Lightweight

+

Built for speed and smooth performance.

-
-

Easy to Use

-

+

+

Easy to Use

+

Clean UI focused on user productivity.

+
Explore Apps → @@ -110,7 +60,7 @@ import { Image } from "astro:assets";
-
+
-
\ No newline at end of file diff --git a/src/components/BlogCard.astro b/src/components/BlogCard.astro index a083d57..83f3c18 100644 --- a/src/components/BlogCard.astro +++ b/src/components/BlogCard.astro @@ -1,33 +1,39 @@ --- -interface Props { - url: string; - title: string; - description?: string; - image: string; - author?: string; - date?: string; -} +const props = Astro.props; -const { - url, - title, - description, - image, - author, - date -} = Astro.props; - -const imageUrl = image; +const url = props.url; +const title = props.title; +const description = props.description; +const image = props.image; +const author = props.author; +const date = props.date; +const tags = props.tags ?? []; ---
- -
+ +
-
+
{title}
-

+ +
+ {tags.slice(0, 2).map((tag: string) => ( + + #{tag} + + ))} +
+ + +

{title}

+ { description && ( -

+

{description}

) } -
+
+ + - {author ? `By ${author}` : "Recursive Zero"} + { + url.startsWith("http") ? ( + + {new URL(url).origin} + + ) : ( + + {author + ? `By ${author}` + : "Recursive Zero"} + + ) + } - {date && } + + {date && ( + + )}
diff --git a/src/components/BlogsSection.astro b/src/components/BlogsSection.astro index a5cc05b..d8d314c 100644 --- a/src/components/BlogsSection.astro +++ b/src/components/BlogsSection.astro @@ -3,21 +3,18 @@ import { getCollection } from "astro:content"; import BlogCard from "./BlogCard.astro"; const posts = await getCollection("blog"); + const slicedPosts = posts.slice(0, 3); --- -
+
-
\ No newline at end of file +
diff --git a/src/components/ContactSection.astro b/src/components/ContactSection.astro index 04af3aa..a210b40 100644 --- a/src/components/ContactSection.astro +++ b/src/components/ContactSection.astro @@ -3,14 +3,13 @@ import contactUs from "@/assets/images/contact-us.jpeg"; import { Image } from "astro:assets"; --- -
+
\ No newline at end of file diff --git a/src/components/Footer.astro b/src/components/Footer.astro index ed341dd..d0fbb15 100644 --- a/src/components/Footer.astro +++ b/src/components/Footer.astro @@ -1,15 +1,12 @@ - - - --- import GitHubIcon from "@/assets/icons/github.svg"; import MailIcon from "@/assets/icons/mail.svg"; import TwitterIcon from "@/assets/icons/x.svg"; --- -
-
- -

- © 2025 Recursive Zero Private Limited. All rights reserved. +

+

+ © 2025 Recursive Zero Private Limited. + All rights reserved.

-
- - + \ No newline at end of file diff --git a/src/components/Header.astro b/src/components/Header.astro index ba65742..0e465ad 100644 --- a/src/components/Header.astro +++ b/src/components/Header.astro @@ -1,6 +1,8 @@ --- import { Picture } from "astro:assets"; -import logoImage from "/public/assets/images/RecursiveZero-White.jpg"; +import "../assets/styles/custom-font.css"; + +import logoImage from "@/assets/images/logo.png"; const currentPath = Astro.url.pathname; @@ -13,41 +15,50 @@ const navLinks = [ ]; const isActive = (path: string) => { - return currentPath === path; + if (path === "/") { + return currentPath === "/"; + } + + return currentPath.startsWith(path); }; --- -
-
+ - - +
+
+ + - - RECURSIVE ZERO - + RECURSIVE ZERO - -
- -
- - - -
-
- -

Our Mission

- -

- Our mission is to deliver exceptional value through innovative - solutions and outstanding service, helping businesses grow faster. -

- -
-
- - - -
-
- -

- Ready to build something amazing? -

- -

- Let’s turn your ideas into reality. -

+ +
+
+

+ Ready to build something amazing? +

- - Contact Us → - +

+ Let’s turn your ideas into reality. +

-
-
+ + Contact Us + + → + + +
+
\ No newline at end of file diff --git a/src/pages/blogs/[...slug].astro b/src/pages/blogs/[...slug].astro index 2590e6b..f0f2be2 100644 --- a/src/pages/blogs/[...slug].astro +++ b/src/pages/blogs/[...slug].astro @@ -3,51 +3,201 @@ import CalendarIcon from "@/assets/icons/calendar.svg"; import ProfileIcon from "@/assets/icons/profile.svg"; import MarkdownContent from "@/components/MarkdownContent.astro"; import BaseLayout from "@/layouts/BaseLayout"; -import { type CollectionEntry, getCollection, render } from "astro:content"; + +import { + type CollectionEntry, + getCollection, + render +} from "astro:content"; + export const prerender = true; export async function getStaticPaths() { const posts = await getCollection("blog"); + return posts.map((blog) => ({ params: { slug: blog.slug }, props: blog })); } + type Props = CollectionEntry<"blog">; const blog = Astro.props; + +// BLOG NOT FOUND REDIRECT +if (!Astro.props?.id) { + return Astro.redirect( + "/blogs/tag?error=notfound" + ); +} + const { Content } = await render(blog); -const { title, description, date, author, image } = blog.data; + +const { + title, + description, + date, + author, + image, + tags +} = blog.data; if (!Content) { - throw new Error(`Content could not be rendered for blog: ${blog.id}`); + throw new Error( + `Content could not be rendered for blog: ${blog.id}` + ); } --- - -
-

{title}

- {description &&

{description}

} -
+ +
+ + +
+ + +

+ Blog Article +

+ + +

+ {title} +

+ + { - author && ( - - - {author} - + description && ( +

+ {description} +

) } + + +
+ + { + author && ( + + + + + + {author} + + ) + } + + { + date && ( + + + + + + + + ) + } + +
+ + { - date && ( - - - - + tags?.length > 0 && ( +
+ + { + tags.map((tag) => ( + + #{tag} + + )) + } + +
) } -
- - - -
-
+ +
+ + +
+ +
+ +
+ +
+
+
+ +
+ + + \ No newline at end of file diff --git a/src/pages/blogs/index.astro b/src/pages/blogs/index.astro index ff1a17c..6445b95 100644 --- a/src/pages/blogs/index.astro +++ b/src/pages/blogs/index.astro @@ -3,29 +3,89 @@ import BlogCard from "@/components/BlogCard.astro"; import BaseLayout from "@/layouts/BaseLayout"; import { getCollection } from "astro:content"; + const posts = await getCollection("blog"); + +/* ALL UNIQUE TAGS */ +const allTags = [ + ...new Set( + posts.flatMap( + (post) => post.data.tags || [] + ) + ) +]; --- - -
-
-

Blog Articles

-

Discover our latest blog and updates

-
- -
- { - posts.map((post) => ( - - )) - } -
+ +
+ + +
+ +
+ + +

+ Recursive Zero Blogs +

+ + +

+ Blog Articles +

+ + +

+ Discover our latest blogs, development insights, + tutorials, product updates and engineering stories. +

+ + +
+ + { + allTags.slice(0, 3).map((tag) => ( + + #{tag} + + )) + } + + + + More Tags → + + +
+ +
+ + +
+ + { + posts.map((post) => ( + + )) + } + +
+ +
+
-
+ \ No newline at end of file diff --git a/src/pages/blogs/tag/[tag].astro b/src/pages/blogs/tag/[tag].astro new file mode 100644 index 0000000..ff90c41 --- /dev/null +++ b/src/pages/blogs/tag/[tag].astro @@ -0,0 +1,70 @@ +--- +import BlogCard from "@/components/BlogCard.astro"; +import BaseLayout from "@/layouts/BaseLayout"; +import { getCollection } from "astro:content"; + +export const prerender = true; + +export async function getStaticPaths() { + const blogs = await getCollection("blog"); + + const allTags = [...new Set(blogs.flatMap((blog) => blog.data.tags || []))]; + + return allTags.map((tag) => ({ + params: { tag } + })); +} + +const { tag } = Astro.params; + +const blogs = await getCollection("blog"); + +const filteredBlogs = blogs.filter((blog) => blog.data.tags?.includes(tag!)); +--- + + +
+
+ +
+

Filtered Blogs

+ +

+ #{tag} +

+ +

+ Showing blogs related to + + #{tag} + +

+
+ + +
+ { + filteredBlogs.length > 0 ? ( + filteredBlogs.map((blog) => ( + + )) + ) : ( +

No blogs found for this tag.

+ ) + } +
+
+
+
diff --git a/src/pages/blogs/tag/index.astro b/src/pages/blogs/tag/index.astro new file mode 100644 index 0000000..00dc0af --- /dev/null +++ b/src/pages/blogs/tag/index.astro @@ -0,0 +1,72 @@ +--- +import BaseLayout from "@/layouts/BaseLayout"; +import { getCollection } from "astro:content"; + +const posts = await getCollection("blog"); + +// ALL UNIQUE TAGS +const tags = [ + ...new Set( + posts.flatMap( + (post) => post.data.tags || [] + ) + ) +]; + +// ERROR MESSAGE +const showError = + Astro.url.searchParams.get("error") + === "notfound"; +--- + + +
+ +
+ + +
+ +

+ Explore Blogs +

+ +

+ Browse by Tags +

+ +

+ Select a tag to explore related blogs. +

+ +
+ + + { + showError && ( +
+ Blog does not exist +
+ ) + } + + +
+ + { + tags.map((tag) => ( + + #{tag} + + )) + } + +
+ +
+ +
+
\ No newline at end of file diff --git a/src/pages/career.astro b/src/pages/career.astro index 7fcc792..7250118 100644 --- a/src/pages/career.astro +++ b/src/pages/career.astro @@ -4,75 +4,209 @@ import "../assets/styles/career.css"; --- -
-
-

Join Our Team

-

Build the future with us

-
- -
-
-

Current Openings

- -
-
-

MBA Interns

-

- We're looking for an MBA Interns who can help us to do Field work and Demos of our product and user - onboarding, preferred candidate from Surat, Gujarat. -

-
- Remote - Full-time +
+ + +
+ +
+

+ Careers +

+ +

+ Join Our Team +

+ +

+ Build the future with us and work on modern digital products + with a talented remote-first team. +

+
+ + +
+ + +
+

+ Current Openings +

+ +
+ + +
+

+ MBA Interns +

+ +

+ We're looking for MBA Interns who can help us with + field work, product demos and user onboarding. + Preferred candidates from Surat, Gujarat. +

+ +
+ + Remote + + + + Full-time + +
-
-
-

Frontend Developer

-

We're looking for an experienced frontend developer to join our team.

-
- Remote - Full-time + + +
+

+ Frontend Developer +

+ +

+ We're looking for an experienced frontend developer + to join our team and build modern interfaces. +

+ +
+ + Remote + + + + Full-time + +
-
-
-

Backend Engineer

-

- Join us in building scalable backend solutions, experienced with nodejs based backend technologies. -

-
- Hybrid - Full-time + +
+

+ Backend Engineer +

+ +

+ Join us in building scalable backend solutions using + Node.js and modern backend technologies. +

+ +
+ + Hybrid + + + + Full-time + +
+
-
-
- -
-

Why Join RecursiveZero?

-
-
-

Remote First

-

Work from anywhere in the world

-
-
-

Learning & Growth

-

Continuous learning opportunities

-
-
-

Great Benefits

-

Competitive salary and benefits package

+
+ + +
+

+ Why Join RecursiveZero? +

+ +
+ +
+

+ Remote First +

+ +

+ Work from anywhere in the world. +

+
+ +
+

+ Learning & Growth +

+ +

+ Continuous learning opportunities and mentorship. +

+
+ +
+

+ Great Benefits +

+ +

+ Competitive salary and exciting benefits package. +

+
+
-
-
- -
-

How to Apply

-

- Send your resume and a brief cover letter to - hello@recursivezero.com -

-
-
+
+ + +
+

+ How to Apply +

+ +

+ Send your resume and a brief cover letter to + + + hello@recursivezero.com + +

+
+ +
+ +
-
+ \ No newline at end of file diff --git a/src/pages/contact.astro b/src/pages/contact.astro index 08ecad6..fa8e2c5 100644 --- a/src/pages/contact.astro +++ b/src/pages/contact.astro @@ -4,9 +4,7 @@ import ContactSection from "@/components/ContactSection.astro"; --- - - - - -
+ +
- - \ No newline at end of file + diff --git a/src/pages/privacy.astro b/src/pages/privacy.astro index e4b91f8..6245f9e 100644 --- a/src/pages/privacy.astro +++ b/src/pages/privacy.astro @@ -1,12 +1,62 @@ --- import MarkdownContent from "@/components/MarkdownContent.astro"; - import { Content } from "@/content/article/privacy.md"; import BaseLayout from "@/layouts/BaseLayout"; --- - - - - - + +
+ + +
+
+ + +

+ Legal +

+ + +

+ Privacy Policy +

+ + +

+ Your privacy matters to us. This page explains how + Recursive Zero collects, uses, and protects your + information while using our products and services. +

+ + +

+ Last Updated: July 2025 +

+ +
+
+ + +
+ +
+ +
+ + + +
+
+ +
+ +
+
\ No newline at end of file diff --git a/src/pages/rss.xml.ts b/src/pages/rss.xml.ts index 366b7cc..484f051 100644 --- a/src/pages/rss.xml.ts +++ b/src/pages/rss.xml.ts @@ -1,19 +1,19 @@ -import { siteConfig } from "@/site-config"; - -import rss from "@astrojs/rss"; -import { getCollection } from "astro:content"; -const posts = await getCollection("blog"); - -export const GET = async () => { - return rss({ - title: siteConfig.title, - description: siteConfig.description, - site: import.meta.env.SITE, - items: posts.map((post) => ({ - title: post.data.title, - description: post.data.description, - pubDate: post.data.date, - link: `posts/${post.slug}` - })) - }); -}; +import { siteConfig } from "@/site-config"; + +import rss from "@astrojs/rss"; +import { getCollection } from "astro:content"; +const posts = await getCollection("blog"); + +export const GET = async () => { + return rss({ + title: siteConfig.title, + description: siteConfig.description, + site: import.meta.env.SITE, + items: posts.map((post) => ({ + title: post.data.title, + description: post.data.description, + pubDate: post.data.date, + link: `posts/${post.slug}` + })) + }); +}; diff --git a/src/pages/terms.astro b/src/pages/terms.astro index 7f25977..b23d805 100644 --- a/src/pages/terms.astro +++ b/src/pages/terms.astro @@ -4,8 +4,60 @@ import { Content } from "@/content/article/terms.md"; import BaseLayout from "@/layouts/BaseLayout"; --- - - - - - + +
+ + +
+
+ + +

+ Legal +

+ + +

+ Terms & Conditions +

+ + +

+ Please read these terms carefully before using + Recursive Zero products, services, and platforms. + By accessing our services, you agree to comply + with these terms. +

+ + +

+ Last Updated: July 2025 +

+ +
+
+ + +
+ +
+ +
+ + + +
+
+ +
+ +
+
\ No newline at end of file diff --git a/src/pages/work.astro b/src/pages/work.astro index 063f863..4a7c6b2 100644 --- a/src/pages/work.astro +++ b/src/pages/work.astro @@ -1,53 +1,104 @@ --- +import fabricAI from "@/assets/images/fabric-ai.png"; import BlogCard from "@/components/BlogCard.astro"; -import Card from "@/components/Card.astro"; import BaseLayout from "@/layouts/BaseLayout"; -const pages = import.meta.glob("./work/*.astro", { eager: true }); - -// Extract frontmatter and routes -const pageList = Object.entries(pages).map(([path, module]) => { - const { frontmatter } = module as any; - const route = path.replace("./work", "/work").replace(".astro", ""); - return { - title: frontmatter.title || "Untitled", - description: frontmatter.description || "No description available.", - image: frontmatter.image || "", - route - }; +const pages = import.meta.glob("./work/*.astro", { + eager: true }); + +// Dynamic pages +const pageList = Object.entries(pages) + .map(([path, module]) => { + const { frontmatter } = module as any; + + const route = path.replace("./work", "/work").replace(".astro", ""); + + return { + title: frontmatter.title || "Page Title", + description: frontmatter.description || "Page description.", + image: frontmatter.image || "No Image", + route + }; + }) + .filter((item) => item.title.toLowerCase() !== "interactive letter"); + +// External work cards +const externalProjects = [ + { + url: "https://abcdkbd.com", + title: "ABCDKBD", + description: "An interactive kids learning platform.", + image: "https://github.com/recursivezero/abcd/blob/main/public/assets/images/512x512.png?raw=true" + }, + { + url: "https://threadzip.com/", + title: "Threadzip", + description: "A digital textile sourcing and business platform connecting manufacturers, suppliers, and buyers.", + image: "https://threadzip.com/images/icon-circle.svg" + }, + { + url: "https://lab.threadzip.com", + title: "ThreadZip Lab", + description: "A python tool that uses computer vision to identify and generate fabric patterns.", + image: "https://lab.threadzip.com/media/4506a1f4769fb57c54b53e6189d5b405971d3595e689f77360792546.jpg" + }, + { + url: "https://rzro.link/", + title: "RZRO Link", + description: "A modern smart link and URL shortening platform by Recursive Zero.", + image: "https://rzro.link/static/og-image.jpg" + }, + { + url: "https://pro.threadzip.com/", + title: "FabricAI", + description: "An AI-powered platform for fabric intelligence and textile analysis.", + image: fabricAI.src + }, + { + url: "https://app.threadzip.com", + title: "ThreadzipApp", + description: "A B2B marketplace for textile raw material businesses.", + image: "https://app.threadzip.com/threadzip_logo_white.png" + } +]; --- - -
-
-

Our Work

-

Discover our latest work and Projects

-
- -
- { - pageList.map(({ title, description, image, route }) => ( - - )) - } - - - -
+ +
+ +
+
+

Portfolio

+ +

Our Work

+ +

+ Explore our latest projects, products, platforms and engineering solutions crafted by Recursive Zero. +

+
+ + +
+ + { + pageList.map(({ title, description, image, route }) => ( + + )) + } + + + { + externalProjects.map(({ url, title, description, image }) => ( + + )) + } +
+
diff --git a/tailwind.config.mjs b/tailwind.config.mjs index c5f0b56..daf74a5 100644 --- a/tailwind.config.mjs +++ b/tailwind.config.mjs @@ -1,8 +1,12 @@ /** @type {import('tailwindcss').Config} */ export default { - content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"], + darkMode: "class", // 👈 MUST + + content: ["./src/**/*.{astro,html,js,jsx,ts,tsx}"], + theme: { - extend: {} + extend: {}, }, - plugins: [] -}; + + plugins: [], +}; \ No newline at end of file