From 1e8fb5ebb53968f1e039067c4c94ff051c64a778 Mon Sep 17 00:00:00 2001 From: Irozuku Date: Fri, 22 May 2026 18:15:00 -0400 Subject: [PATCH 01/14] feat: add brand assets (logo + isotype SVGs) --- public/images/dashai-isotype.svg | 4 ++++ public/images/dashai-logo.svg | 5 +++++ 2 files changed, 9 insertions(+) create mode 100644 public/images/dashai-isotype.svg create mode 100644 public/images/dashai-logo.svg diff --git a/public/images/dashai-isotype.svg b/public/images/dashai-isotype.svg new file mode 100644 index 0000000..37cf22b --- /dev/null +++ b/public/images/dashai-isotype.svg @@ -0,0 +1,4 @@ + + dash.AI isotipo + + diff --git a/public/images/dashai-logo.svg b/public/images/dashai-logo.svg new file mode 100644 index 0000000..c62f664 --- /dev/null +++ b/public/images/dashai-logo.svg @@ -0,0 +1,5 @@ + + + + + From e0aa15164596a6ea0933306ccaa92f1c9e9297a1 Mon Sep 17 00:00:00 2001 From: Irozuku Date: Fri, 22 May 2026 18:15:04 -0400 Subject: [PATCH 02/14] chore: update globals.css (hex vars, animations), package.json and tsconfig --- app/globals.css | 201 ++++++++++++++++++++++++++++++++---------------- package.json | 5 +- tsconfig.json | 25 ++++-- 3 files changed, 159 insertions(+), 72 deletions(-) diff --git a/app/globals.css b/app/globals.css index 1f0dab6..cbe3810 100644 --- a/app/globals.css +++ b/app/globals.css @@ -4,78 +4,88 @@ @custom-variant dark (&:is(.dark *)); :root { - --background: oklch(0.98 0 0); - --foreground: oklch(0.98 0 0); - --card: oklch(0.12 0 0); - --card-foreground: oklch(0.98 0 0); - --popover: oklch(0.12 0 0); - --popover-foreground: oklch(0.98 0 0); - --primary: oklch(0.75 0.18 195); - --primary-foreground: oklch(0.1 0 0); - --secondary: oklch(0.28 0 0); - --secondary-foreground: oklch(0.98 0 0); - --muted: oklch(0.22 0 0); - --muted-foreground: oklch(0.65 0 0); - --accent: oklch(0.65 0.18 45); - --accent-foreground: oklch(0.1 0 0); - --destructive: oklch(0.577 0.245 27.325); + /* ── DashAI Brand v2 · Neutral Dark (May 2026) ── */ + --background: #191817; + --foreground: #FEFEFF; + --card: #1F1E1D; + --card-foreground: #FEFEFF; + --popover: #1F1E1D; + --popover-foreground: #FEFEFF; + --primary: #2C7AFF; + --primary-foreground: #191817; + --secondary: #25231F; + --secondary-foreground: #FEFEFF; + --muted: #1B1A19; + --muted-foreground: #B5B0A8; + --accent: #FFA578; + --accent-foreground: #191817; + --destructive: oklch(0.577 0.245 27.325); --destructive-foreground: oklch(0.985 0 0); - --border: oklch(0.28 0 0); - --input: oklch(0.28 0 0); - --ring: oklch(0.75 0.18 195); - --chart-1: oklch(0.75 0.18 195); - --chart-2: oklch(0.65 0.18 45); - --chart-3: oklch(0.6 0.15 240); - --chart-4: oklch(0.7 0.15 280); - --chart-5: oklch(0.55 0.12 210); - --radius: 0.75rem; - --sidebar: oklch(0.985 0 0); - --sidebar-foreground: oklch(0.145 0 0); - --sidebar-primary: oklch(0.205 0 0); - --sidebar-primary-foreground: oklch(0.985 0 0); - --sidebar-accent: oklch(0.97 0 0); - --sidebar-accent-foreground: oklch(0.205 0 0); - --sidebar-border: oklch(0.922 0 0); - --sidebar-ring: oklch(0.708 0 0); + --border: #2E2C29; + --input: #2E2C29; + --ring: #2C7AFF; + --chart-1: #2C7AFF; + --chart-2: #FFA578; + --chart-3: #90F1C4; + --chart-4: #A54DA9; + --chart-5: #A7C7FF; + --radius: 0.375rem; + --sidebar: #131211; + --sidebar-foreground: #FEFEFF; + --sidebar-primary: #2C7AFF; + --sidebar-primary-foreground: #FEFEFF; + --sidebar-accent: #25231F; + --sidebar-accent-foreground: #FEFEFF; + --sidebar-border: #2E2C29; + --sidebar-ring: #2C7AFF; + + /* Module accent palette */ + --color-datasets: #FFA578; + --color-models: #2C7AFF; + --color-generative: #90F1C4; + --color-plugins: #A54DA9; + --brand-light: #A7C7FF; } .dark { - --background: oklch(0.08 0 0); - --foreground: oklch(0.98 0 0); - --card: oklch(0.12 0 0); - --card-foreground: oklch(0.98 0 0); - --popover: oklch(0.12 0 0); - --popover-foreground: oklch(0.98 0 0); - --primary: oklch(0.75 0.18 195); - --primary-foreground: oklch(0.1 0 0); - --secondary: oklch(0.28 0 0); - --secondary-foreground: oklch(0.98 0 0); - --muted: oklch(0.22 0 0); - --muted-foreground: oklch(0.65 0 0); - --accent: oklch(0.65 0.18 45); - --accent-foreground: oklch(0.1 0 0); - --destructive: oklch(0.577 0.245 27.325); - --destructive-foreground: oklch(0.985 0 0); - --border: oklch(0.28 0 0); - --input: oklch(0.28 0 0); - --ring: oklch(0.75 0.18 195); - --chart-1: oklch(0.75 0.18 195); - --chart-2: oklch(0.65 0.18 45); - --chart-3: oklch(0.6 0.15 240); - --chart-4: oklch(0.7 0.15 280); - --chart-5: oklch(0.55 0.12 210); - --sidebar: oklch(0.205 0 0); - --sidebar-foreground: oklch(0.985 0 0); - --sidebar-primary: oklch(0.488 0.243 264.376); - --sidebar-primary-foreground: oklch(0.985 0 0); - --sidebar-accent: oklch(0.269 0 0); - --sidebar-accent-foreground: oklch(0.985 0 0); - --sidebar-border: oklch(0.269 0 0); - --sidebar-ring: oklch(0.439 0 0); + /* same palette — site is always dark */ + --background: #191817; + --foreground: #FEFEFF; + --card: #1F1E1D; + --card-foreground: #FEFEFF; + --popover: #1F1E1D; + --popover-foreground: #FEFEFF; + --primary: #2C7AFF; + --primary-foreground: #191817; + --secondary: #25231F; + --secondary-foreground: #FEFEFF; + --muted: #1B1A19; + --muted-foreground: #B5B0A8; + --accent: #FFA578; + --accent-foreground: #191817; + --destructive: oklch(0.396 0.141 25.723); + --destructive-foreground: oklch(0.637 0.237 25.331); + --border: #2E2C29; + --input: #2E2C29; + --ring: #2C7AFF; + --chart-1: #2C7AFF; + --chart-2: #FFA578; + --chart-3: #90F1C4; + --chart-4: #A54DA9; + --chart-5: #A7C7FF; + --sidebar: #131211; + --sidebar-foreground: #FEFEFF; + --sidebar-primary: #2C7AFF; + --sidebar-primary-foreground: #FEFEFF; + --sidebar-accent: #25231F; + --sidebar-accent-foreground: #FEFEFF; + --sidebar-border: #2E2C29; + --sidebar-ring: #2C7AFF; } @theme inline { - /* optional: --font-sans, --font-serif, --font-mono if they are applied in the layout.tsx */ + --font-sans: 'Geist', 'Geist Fallback', ui-sans-serif, system-ui, sans-serif; + --font-mono: 'Geist Mono', 'Geist Mono Fallback', ui-monospace, Menlo, monospace; --color-background: var(--background); --color-foreground: var(--foreground); --color-card: var(--card); @@ -112,7 +122,65 @@ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); --color-sidebar-border: var(--sidebar-border); --color-sidebar-ring: var(--sidebar-ring); + + /* Module palette — usable as bg-datasets, text-generative, etc. */ + --color-datasets: var(--color-datasets); + --color-models: var(--color-models); + --color-generative: var(--color-generative); + --color-plugins: var(--color-plugins); + --color-brand-light: var(--brand-light); +} + +/* ── Light-section paper palette ── */ +:root { + --paper: #FEFEFF; + --paper-deep: #F4F4F2; + --paper-line: #E3E2DF; + --on-light: #191817; + --on-light-mute: #4A4744; + --on-light-faint: #6C685F; + --ink-deep: #131211; + --ink-line: #2E2C29; + --ease-out-bold: cubic-bezier(.16,1,.3,1); +} + +/* ── Marquee ── */ +@keyframes marquee-scroll { + from { transform: translateX(0); } + to { transform: translateX(-50%); } } +.marquee-track { + animation: marquee-scroll 32s linear infinite; + white-space: nowrap; + display: flex; + width: max-content; +} + +/* ── Subtle grid (hero bg) ── */ +.bg-grid-subtle { + background-image: + repeating-linear-gradient(90deg, transparent 0 80px, rgba(255,255,255,.022) 80px 81px), + repeating-linear-gradient(0deg, transparent 0 40px, rgba(255,255,255,.015) 40px 41px); + mask-image: linear-gradient(180deg, black 0%, black 74%, transparent 100%); + -webkit-mask-image: linear-gradient(180deg, black 0%, black 74%, transparent 100%); +} + +/* ── Hero visual entrance ── */ +@keyframes heroIn { + from { opacity: 0; transform: translateY(20px) scale(.98); } + to { opacity: 1; transform: translateY(0) scale(1); } +} +.hero-visual-in { + animation: heroIn 1s cubic-bezier(.16,1,.3,1) .15s both; +} + +/* ── Code syntax colors ── */ +.code-kw { color: #A7C7FF; } +.code-fn { color: #90F1C4; } +.code-str { color: #FFA578; } +.code-num { color: #FEE8FF; } +.code-com { color: #8C877F; font-style: italic; } +.code-cls { color: #FEE8FF; } @layer base { * { @@ -120,5 +188,8 @@ } body { @apply bg-background text-foreground; + font-feature-settings: "ss01","ss03","cv09","cv11"; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; } } diff --git a/package.json b/package.json index 732800f..c1e16b8 100644 --- a/package.json +++ b/package.json @@ -72,5 +72,6 @@ "tailwindcss": "^4.1.9", "tw-animate-css": "1.3.3", "typescript": "^5" - } -} \ No newline at end of file + }, + "packageManager": "pnpm@10.22.0+sha512.bf049efe995b28f527fd2b41ae0474ce29186f7edcb3bf545087bd61fbbebb2bf75362d1307fda09c2d288e1e499787ac12d4fcb617a974718a6051f2eee741c" +} diff --git a/tsconfig.json b/tsconfig.json index 4b2dc7b..b79e264 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,10 @@ { "compilerOptions": { - "lib": ["dom", "dom.iterable", "esnext"], + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], "allowJs": true, "target": "ES6", "skipLibCheck": true, @@ -11,7 +15,7 @@ "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, - "jsx": "preserve", + "jsx": "react-jsx", "incremental": true, "plugins": [ { @@ -19,9 +23,20 @@ } ], "paths": { - "@/*": ["./*"] + "@/*": [ + "./*" + ] } }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], - "exclude": ["node_modules"] + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + ".next\\dev/types/**/*.ts", + ".next\\dev/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] } From 8cc8d42cae760bcc309fc0d9ac57fbfa56f92f44 Mon Sep 17 00:00:00 2001 From: Irozuku Date: Fri, 22 May 2026 18:15:07 -0400 Subject: [PATCH 03/14] feat: update layout metadata and page section order --- app/layout.tsx | 17 ++++------------- app/page.tsx | 11 +++++++---- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/app/layout.tsx b/app/layout.tsx index 070369f..99accd4 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -8,22 +8,13 @@ const _geist = Geist({ subsets: ["latin"] }) const _geistMono = Geist_Mono({ subsets: ["latin"] }) export const metadata: Metadata = { - title: "DashAI - Plataforma Open Source de IA", + title: "dashAI - Full Open. Full Extensible.", description: - "Integra, experimenta y visualiza modelos de IA mediante una interfaz visual intuitiva. Democratizando el acceso al machine learning.", + "An open-source no-code Visual ML platform. No paywall, no closed components, no external API keys required.", generator: "v0.app", icons: { - icon: [ - { - url: "/icon-light-32x32.png", - media: "(prefers-color-scheme: light)", - }, - { - url: "/icon-dark-32x32.png", - media: "(prefers-color-scheme: dark)", - }, - ], - apple: "/apple-icon.png", + icon: "/images/dashai-isotype.svg", + apple: "/images/dashai-isotype.svg", }, } diff --git a/app/page.tsx b/app/page.tsx index 27d43db..5f8f82e 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -4,12 +4,13 @@ import { useEffect } from "react" import i18n from "i18next" import { Navbar } from "@/components/navbar" import { HeroSection } from "@/components/hero-section" +import { ManifestoSection } from "@/components/manifesto-section" import { FeaturesSection } from "@/components/features-section" -//import { ModulesCarousel } from "@/components/modules-carousel" +import { ShowcaseSection } from "@/components/showcase-section" +import { ExtensibleSection } from "@/components/extensible-section" import { DownloadSection } from "@/components/download-section" -import { SupportedBySection } from "@/components/supported-by-section" import { CommunitySection } from "@/components/community-section" -import { ContactSection } from "@/components/contact-section" +import { SupportedBySection } from "@/components/supported-by-section" import { Footer } from "@/components/footer" import "./i18n" @@ -26,11 +27,13 @@ export default function Home() {
+ + + -
) From 0feb03c70bc73a7ef8dae7c26d6d3a2096b15a82 Mon Sep 17 00:00:00 2001 From: Irozuku Date: Fri, 22 May 2026 18:15:11 -0400 Subject: [PATCH 04/14] feat(navbar): use i18n for nav links, add logo, clean up --- components/navbar.tsx | 289 +++++++++++++--------------------- public/locales/en/navbar.json | 11 +- public/locales/es/navbar.json | 11 +- 3 files changed, 121 insertions(+), 190 deletions(-) diff --git a/components/navbar.tsx b/components/navbar.tsx index 80b2969..30b9860 100644 --- a/components/navbar.tsx +++ b/components/navbar.tsx @@ -1,208 +1,141 @@ "use client" import { useState, useEffect } from "react" -import { Button } from "@/components/ui/button" -import { Download, Github, Menu, X, Globe, ChevronDown } from "lucide-react" -import Image from "next/image" import { cn } from "@/lib/utils" import { siteConfig } from "@/lib/config" import { useTranslation } from "react-i18next" -const LANGUAGES = [ - { code: "en", label: "English", flag: "🇺🇸" }, - { code: "es", label: "Español", flag: "🇨🇱" }, -] +export function Navbar() { + const [isScrolled, setIsScrolled] = useState(false) + const [mobileOpen, setMobileOpen] = useState(false) + const { i18n, t } = useTranslation("navbar") -function LanguageSwitcher() { - const { i18n } = useTranslation() - const [isOpen, setIsOpen] = useState(false) + const lang = i18n.language?.startsWith("es") ? "es" : "en" + const setLang = (l: string) => { i18n.changeLanguage(l); setMobileOpen(false) } - const currentLang = LANGUAGES.find((l) => l.code === i18n.language) ?? LANGUAGES[0] + useEffect(() => { + const h = () => setIsScrolled(window.scrollY > 10) + window.addEventListener("scroll", h) + return () => window.removeEventListener("scroll", h) + }, []) - const changeLanguage = (code: string) => { - i18n.changeLanguage(code) - setIsOpen(false) + const scrollTo = (id: string) => { + document.getElementById(id)?.scrollIntoView({ behavior: "smooth" }) + setMobileOpen(false) } - // Close on outside click - useEffect(() => { - if (!isOpen) return - const handler = (e: MouseEvent) => { - const target = e.target as HTMLElement - if (!target.closest("[data-lang-switcher]")) setIsOpen(false) - } - document.addEventListener("mousedown", handler) - return () => document.removeEventListener("mousedown", handler) - }, [isOpen]) + const navLinks = ["manifesto", "open", "showcase", "extensible", "download"] return ( -
- +