Portfolio Moderno is a single-page application (SPA) built by Nicolas Grajales Hoyos. The browser loads a singleDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/nicolasgrajaleshoyos/portafolio/llms.txt
Use this file to discover all available pages before exploring further.
index.html entry point, which bootstraps a Vite-powered development server and build pipeline. At runtime, React mounts the entire application into the #root div via src/main.tsx, hydrating the component tree from a single root <App /> component. Because all navigation stays on one page, section transitions are handled through smooth-scroll anchor links rather than a client-side router.
Application Entry Point
App.tsx is the root of the React component tree. It owns the only piece of shared UI state — the active color theme — and passes it down to Header. Every other component is self-contained and renders its own section of the page.
State Management
Portfolio Moderno uses no external state library (no Redux, Zustand, or Context API). The only shared state is thetheme value ('light' | 'dark'), managed entirely by the custom useTheme hook that lives inside App.tsx. The hook returns a [theme, toggleTheme] tuple. theme is forwarded as a prop to Header so it can render the correct icon in the theme-toggle button; all other components are stateless with respect to global state and manage only their own local animation flags.
Custom Hooks
useTheme()
Defined in App.tsx. Manages dark/light mode persistence and synchronisation with the DOM.
localStorage value → OS prefers-color-scheme → default 'light'.
useTypingEffect(words, typeSpeed?, deleteSpeed?, delay?)
Defined in Hero.tsx. Produces an animated typing illusion that cycles through an array of strings. Returns the currently-visible substring so the component can render it alongside a blinking cursor.
| Parameter | Type | Signature default | Call-site value (Hero.tsx) | Description |
|---|---|---|---|---|
words | string[] | — | (required) | Array of phrases to cycle through |
typeSpeed | number | 150 | 100 | Milliseconds per character when typing |
deleteSpeed | number | 100 | 50 | Milliseconds per character when deleting |
delay | number | 1000 | 2000 | Pause in ms after a word is fully typed before deletion begins |
TypeScript Interfaces
Both shared data-shape contracts are defined insrc/types.ts and imported wherever needed.
Project
Used by the Projects component and its ProjectCard sub-component to type each portfolio entry.
Skill
Used by the About component to type each entry in the skills grid. The icon field accepts any React functional component that takes an optional className prop, allowing both custom SVG icons and third-party icon-library components to be used interchangeably.
Build Pipeline
Vite is configured invite.config.ts with the following settings:
| Setting | Value | Effect |
|---|---|---|
| Dev server port | 3000 | Local dev available at http://localhost:3000 |
Path alias @/ | src/ | All imports use @/components/… instead of relative paths |
| React plugin | @vitejs/plugin-react | Babel-powered HMR with Fast Refresh |
| CSS processor | PostCSS + Tailwind | Utility class generation and purging |