diff --git a/Cargo.lock b/Cargo.lock index d4cec1f..38facaf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -2312,9 +2312,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.34" +version = "0.3.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +checksum = "ef89ece63debf11bc32d1ed8d078ac870cbeb44da02afb02a9ff135ae7ca0582" dependencies = [ "deranged", "itoa", @@ -2335,9 +2335,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ "num-conv", "time-core", diff --git a/Dockerfile b/Dockerfile index caac2e7..eb1050d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,8 +21,10 @@ RUN mkdir -p /app WORKDIR /app COPY . . -# Install nodejs -RUN apt-get update && apt-get install -y nodejs npm +# Install Node.js (>=18) for Sass +RUN apt-get update && apt-get install -y curl ca-certificates +RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - +RUN apt-get install -y nodejs # Install sass RUN npm install -g sass @@ -32,8 +34,8 @@ RUN cargo install wasm-server-runner RUN cargo install -f wasm-bindgen-cli RUN cargo update -p wasm-bindgen -# Build the app -RUN cargo leptos build --release -vv +# Build the app (with backtrace for clearer errors) +RUN RUST_BACKTRACE=full cargo leptos build --release -vv FROM rustlang/rust:nightly-bullseye as runner # Copy the server binary to the /app directory diff --git a/resume-master-base.md b/resume-master-base.md new file mode 100644 index 0000000..c2f349a --- /dev/null +++ b/resume-master-base.md @@ -0,0 +1,107 @@ +# Alex Ramirez + +Medellín, Colombia +alexander.ramirez@gmail.com +https://ramirezalex.com +https://github.com/RamirezAlex +https://x.com/RamirezAlex_ + +## Professional Summary + +Senior engineer with deep experience across backend systems, product engineering, Rust, TypeScript, AI-powered products, and Solana since 2021. I build technically strong systems that are also usable in the real world, from on-chain programs and crypto products to full-stack applications and internal tooling. Strongest in backend architecture, protocol and smart contract logic, and turning ambiguous ideas into shipped products. + +## Core Skills + +- Solana, Rust, Anchor, smart contracts, on-chain program design +- Backend architecture, API design, distributed systems, PostgreSQL, Prisma +- TypeScript, React, Next.js, Node.js, Vite +- AI-native product design, agent workflows, LLM integrations, moderation systems +- Product thinking, startup execution, technical leadership, rapid prototyping + +## Experience + +### Dare Market — Senior Engineer / Product Engineer +**Current** · Remote + +Web3-powered challenge marketplace on Solana where users create, fund, participate in, and win crypto-backed dares. + +- Played an important role across product, architecture, and the Solana program side. +- Worked across the core product stack spanning Solana contracts, the main Next.js application, and backend workflows. +- Contributed to contract-side design and implementation for a real-money, user-facing product built on Solana. +- Helped shape a system that combines on-chain game/challenge mechanics with off-chain product, moderation, and payout flows. +- Worked in a stack including Solana, Rust/Anchor, TypeScript, Next.js, PostgreSQL, Prisma, Privy, and AI moderation services. + +### Mootrack — Co-founder / Lead Engineer +**Current** · LATAM / Colombia + +Solana-powered cattle traceability and farm management platform for ranchers in LATAM, evolving into an AI-native operating system for livestock farms. + +- Leading the product and technical direction for a platform that combines farm software, AI, and on-chain animal identity. +- Built the technical foundation for digitizing livestock records, operations, and traceability in a real-world industry with poor software penetration. +- Worked on the product vision for using Solana as infrastructure for verifiable animal identity, traceability, ownership history, and future financing rails. +- Helped secure pilot farms and shaped the MVP around real operational ranch workflows instead of speculative crypto use cases. +- Driving the AI assistant direction for Mootrack, focused on personalized farm copilots and tool-based operational workflows. + +### BAXUS — Senior Engineer +Remote + +Consumer crypto product with real users and strong brand recognition in the Solana ecosystem. + +- Built product and engineering systems in a live crypto environment with real customer-facing impact. +- Worked across backend, product, and blockchain-facing functionality rather than staying boxed into a single layer. +- Contributed to shipping polished user experiences on top of technically complex crypto infrastructure. + +### PrintXD / Print World — Senior Rust Engineer +Remote + +- Worked as a senior Rust engineer on production systems. +- Focused on backend and systems-level engineering with strong ownership over implementation quality. +- Strengthened expertise in Rust as part of a broader systems and product engineering toolkit. + +### 10Pearls — Senior / Lead Full-Stack Engineer +Remote + +- Built and shipped client-facing software products across backend and frontend layers. +- Worked closely with product direction, delivery, and implementation in startup-style environments. +- Developed strong range across architecture, execution, and shipping under real-world constraints. + +## Selected Projects + +### PushFlip +Crypto-native push-your-luck card game on Solana with token mechanics, AI opponent flows, and ZK-based deck verification. + +- Designed to showcase advanced Solana engineering, on-chain game logic, and provable fairness patterns. +- Combines Rust, Solana programs, backend services, and zero-knowledge infrastructure. + +### SOLClaw +Agent runtime and protocol concept for putting AI agents on-chain on Solana. + +- Explored agent identity, memory anchoring, task execution, and payment rails as protocol primitives. +- Combined product thinking with Solana-native systems design and AI infrastructure ideas. + +## Solana / Web3 Highlights + +- Building on Solana since **2021**. +- Production experience with Solana programs, crypto products, and wallet-connected applications. +- Experience spanning smart contracts, backend systems, consumer product engineering, and AI-native crypto applications. +- Strong preference for blockchain used as infrastructure for real products, not just speculation. + +## Hackathons / Ecosystem + +- Participated in Solana ecosystem hackathons and startup programs. +- Breakout / Colosseum-related participation. +- Active builder around Solana, AI, and product experimentation. + +## Education / Additional + +- Languages: English, Spanish +- Based in Medellín, Colombia + +## Notes for Tailored Versions + +This is the master base version. Tailored variants should be created from this source for: + +1. AI / Agents / Backend +2. Solana / Rust / Crypto Infra +3. Senior Full-Stack / Product Engineer +4. Founding Engineer / Startup CTO diff --git a/rust-toolchain.toml b/rust-toolchain.toml index e9743fb..02ba681 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly" +channel = "nightly-2024-05-01" diff --git a/src/app.rs b/src/app.rs index 2677f1e..d49ec05 100644 --- a/src/app.rs +++ b/src/app.rs @@ -17,7 +17,7 @@ pub fn App() -> impl IntoView { // sets the document title - + <Title text="Alex Ramirez | Software Engineer"/> // content for this welcome page <Router fallback=|| { diff --git a/src/components/footer.rs b/src/components/footer.rs index f87b58b..feac0cc 100644 --- a/src/components/footer.rs +++ b/src/components/footer.rs @@ -4,15 +4,16 @@ use leptos_meta::Script; #[component] pub fn Footer() -> impl IntoView { view! { - <footer> + <footer class="site-footer"> <Script async_="true" src="https://www.googletagmanager.com/gtag/js?id=G-LMD9JFSZTB"></Script> <Script>{r#" window.dataLayer = window.dataLayer || []; - function gtag(){dataLayer.push(arguments);} - gtag('js', new Date()); - gtag('config', 'G-LMD9JFSZTB'); + function gtag(){dataLayer.push(arguments);} + gtag('js', new Date()); + gtag('config', 'G-LMD9JFSZTB'); "#}</Script> - RamirezAlex - 2026 + <span>"© 2026 Alex Ramirez"</span> + <span>"Medellín, Colombia · Built with Rust & Leptos"</span> </footer> } } diff --git a/src/components/layout.rs b/src/components/layout.rs index 51c4238..197c744 100644 --- a/src/components/layout.rs +++ b/src/components/layout.rs @@ -1,19 +1,18 @@ use crate::components::footer::Footer; -use crate::components::header::Header; use crate::components::nav::Nav; use leptos::*; #[component] pub fn Layout(children: Children) -> impl IntoView { - let (mode, set_mode) = create_signal(String::from("dark-mode")); + let (dark, set_dark) = create_signal(false); + let class = move || if dark.get() { "layout dark" } else { "layout" }; view! { - <div class=mode> - <Nav setter=set_mode /> - <div> - <Header/>{children()} <Footer/> - </div> + <div class=class> + <Nav dark=dark set_dark=set_dark /> + {children()} + <Footer /> </div> } } diff --git a/src/components/nav.rs b/src/components/nav.rs index 8a530d1..84986a8 100644 --- a/src/components/nav.rs +++ b/src/components/nav.rs @@ -4,34 +4,30 @@ use leptos_icons::Icon; use leptos_router::A; #[component] -pub fn Nav(setter: WriteSignal<String>) -> impl IntoView { - let (icon_mode, set_icon_mode) = create_signal(i::BsSun); - let (mode_label, set_mode_label) = create_signal("on"); - let handle_click = move |_| { - set_icon_mode.update(move |mode| { - if *mode == i::BsMoonStars { - *mode = i::BsSun; - set_mode_label("on"); - setter.set(String::from("dark-mode")); - } else { - *mode = i::BsMoonStars; - set_mode_label("off"); - setter.set(String::from("light-mode")); - } - }) - }; +pub fn Nav(dark: ReadSignal<bool>, set_dark: WriteSignal<bool>) -> impl IntoView { + let icon = Signal::derive(move || if dark.get() { i::BsSun } else { i::BsMoonStars }); view! { - <nav> - <div class="main-menu"> - <A href="/">Home</A> - <A href="/blog">Blog</A> - </div> - <div class="mode-menu"> - <button on:click=handle_click> - Turn {mode_label} the light + <nav class="site-nav"> + <A class="nav-logo" href="/">"AR"</A> + <div class="nav-links"> + <A class="nav-link" href="/blog">"Blog"</A> + <a + class="nav-link" + href="https://github.com/RamirezAlex" + target="_blank" + rel="noreferrer" + > + "GitHub" + </a> + <button + class="mode-toggle" + on:click=move |_| set_dark.update(|d| *d = !*d) + aria-label="Toggle dark mode" + > + <Icon icon=icon width="16px" height="16px" /> </button> - <Icon icon=icon_mode width="1em" height="1em" style="padding-left: 10px; vertical-align: middle"/> + <a class="nav-cta" href="mailto:alexander.ramirez@gmail.com">"Let's talk"</a> </div> </nav> } diff --git a/src/pages/home.rs b/src/pages/home.rs index da1332e..6cbd277 100644 --- a/src/pages/home.rs +++ b/src/pages/home.rs @@ -1,60 +1,208 @@ use crate::components::layout::Layout; -use icondata as i; use leptos::*; -use leptos_icons::Icon; #[component] pub fn Home() -> impl IntoView { view! { <Layout> - <div id="content"> - <header> - <div class="half-block"> - <h1>Alex Ramirez</h1> - <h2>Software Engineer</h2> - </div> - <div class="half-block"> - <picture class="profile-image"></picture> - </div> - </header> - <section id="info"> - <p> - Software Engineer * JavaScript Lover * Python Enthusiastic<br /> - Go Learner * Blockchain Padawan * Rust Apprentice<br /> - co-organizer of <a target="_blank" rel="noreferrer" href="https://twitter.com/rustmedellin">@RustMedellin</a> and - <a target="_blank" rel="noreferrer" href="https://twitter.com/medellinjs">@MedellinJS</a> + // ── Hero ────────────────────────────────────────────────── + <section class="hero"> + <div class="hero-left"> + <div class="eyebrow"> + <span class="eyebrow-dot eyebrow-dot-purple"></span> + "Medellín, Colombia · Available for work" + </div> + <div class="hero-headline"> + <span>"Senior Engineer."</span> + <span class="hl-accent">"Rust. Solana."</span> + <span>"Products that ship."</span> + </div> + <p class="hero-tagline"> + "I build technically strong systems that work in the real world — from Solana + smart contracts to full-stack applications. Based in Medellín, shipping globally." </p> - </section> - <section id="social-media"> - <ul> - <li class="twitter"> - <a target="_blank" rel="noreferrer" aria-label="Twitter - @RamirezAlex_" href="https://twitter.com/RamirezAlex_"> - <Icon icon=i::BsTwitterX class="fab" /> - </a> - </li> - <li class="github"> - <a target="_blank" rel="noreferrer" aria-label="Github - @RamirezAlex" href="https://github.com/RamirezAlex"> - <Icon icon=i::FaGithubBrands class="fab" /> - </a> - </li> - <li class="linkedin"> - <a target="_blank" rel="noreferrer" aria-label="LinkedIn - @ramirezalex1" href="https://www.linkedin.com/in/ramirezalex1/"> - <Icon icon=i::FaLinkedinBrands class="fab" /> - </a> - </li> - <li class="instagram"> - <a target="_blank" rel="noreferrer" aria-label="Instagram - @_ramirezalex" href="https://www.instagram.com/_ramirezalex/"> - <Icon icon=i::FaInstagramBrands class="fab" /> - </a> - </li> - <li class="facebook"> - <a target="_blank" rel="noreferrer" aria-label="Facebook - @ramirezalex4" href="https://www.facebook.com/ramirezalex4"> - <Icon icon=i::FaFacebookBrands class="fab" /> + <div class="hero-ctas"> + <a class="btn-primary" href="/blog">"Read the blog"</a> + <a + class="btn-secondary" + href="https://github.com/RamirezAlex" + target="_blank" + rel="noreferrer" + > + "View GitHub" </a> - </li> - </ul> - </section> - </div> + </div> + </div> + <div class="hero-right"> + <div class="terminal-card"> + <div class="terminal-bar"> + <span class="terminal-dot red"></span> + <span class="terminal-dot yellow"></span> + <span class="terminal-dot green"></span> + <span class="terminal-bar-title">"alex@ramirezalex ~ "</span> + </div> + <div class="terminal-body"> + <p class="t-line cmd">"$ whoami"</p> + <p class="t-line out">"Senior Engineer — Rust · TypeScript · Solana"</p> + <p class="t-line cmd">"$ cat stack.txt"</p> + <p class="t-line muted">"Rust / Anchor / Solana / TypeScript / Next.js"</p> + <p class="t-line muted">"Node.js / PostgreSQL / Prisma / Axum / Leptos"</p> + <p class="t-line cmd">"$ cat now.txt"</p> + <p class="t-line cyan">"Dare Market · Mootrack · PushFlip · SOLClaw"</p> + <p class="t-line green">"$ building since 2021 on Solana ▊"</p> + </div> + </div> + </div> + </section> + + <div class="section-divider"></div> + + // ── Skills ──────────────────────────────────────────────── + <section class="skills-section"> + <div class="section-header"> + <div class="section-eyebrow"> + <span class="eyebrow-dot eyebrow-dot-cyan"></span> + "What I build" + </div> + <h2 class="section-title">"Deep expertise." <br/> "Multiple layers."</h2> + </div> + <div class="skills-grid"> + <div class="skill-card"> + <span class="skill-num">"01"</span> + <strong class="skill-title">"Solana Programs"</strong> + <p class="skill-desc"> + "Smart contracts, on-chain game logic, token mechanics, and verifiable + computation. Building since 2021." + </p> + </div> + <div class="skill-card"> + <span class="skill-num">"02"</span> + <strong class="skill-title">"Backend Systems"</strong> + <p class="skill-desc"> + "API design, distributed systems, PostgreSQL, Prisma. From Axum in Rust + to Node.js at scale." + </p> + </div> + <div class="skill-card"> + <span class="skill-num">"03"</span> + <strong class="skill-title">"Product Engineering"</strong> + <p class="skill-desc"> + "Full-stack execution from ambiguous idea to shipped product. + TypeScript, React, Next.js, rapid prototyping." + </p> + </div> + <div class="skill-card"> + <span class="skill-num">"04"</span> + <strong class="skill-title">"AI-Native Products"</strong> + <p class="skill-desc"> + "Agent workflows, LLM integrations, farm copilots, moderation systems. + AI as real product leverage." + </p> + </div> + </div> + </section> + + <div class="section-divider"></div> + + // ── Projects ────────────────────────────────────────────── + <section class="projects-section"> + <div class="section-header"> + <div class="section-eyebrow"> + <span class="eyebrow-dot eyebrow-dot-pink"></span> + "Selected work" + </div> + <h2 class="section-title">"Real products." <br/> "Real users."</h2> + </div> + <div class="proj-grid"> + <div class="proj-row"> + <div class="proj-card"> + <div class="proj-tags"> + <span class="proj-tag purple">"Solana"</span> + <span class="proj-tag cyan">"Rust"</span> + <span class="proj-tag muted">"TypeScript"</span> + </div> + <h3 class="proj-title">"Dare Market"</h3> + <p class="proj-desc"> + "Web3-powered challenge marketplace on Solana. Users create, fund, and win + crypto-backed dares. Built across Solana contracts, Next.js, PostgreSQL, + and AI moderation." + </p> + <span class="proj-role purple">"Role: Senior Engineer / Product Engineer"</span> + </div> + <div class="proj-card"> + <div class="proj-tags"> + <span class="proj-tag purple">"Solana"</span> + <span class="proj-tag cyan">"AI"</span> + <span class="proj-tag muted">"LATAM"</span> + </div> + <h3 class="proj-title">"Mootrack"</h3> + <p class="proj-desc"> + "Solana-powered cattle traceability and farm management platform. + AI-native operating system for livestock farms. On-chain animal identity, + ownership, and financing rails." + </p> + <span class="proj-role pink">"Role: Co-founder / Lead Engineer"</span> + </div> + </div> + <div class="proj-row"> + <div class="proj-card featured-purple"> + <div class="proj-tags"> + <span class="proj-tag purple">"Solana"</span> + <span class="proj-tag cyan">"ZK Proofs"</span> + <span class="proj-tag muted">"Game"</span> + </div> + <h3 class="proj-title">"PushFlip"</h3> + <p class="proj-desc"> + "Crypto-native push-your-luck card game on Solana. Token mechanics, AI + opponent flows, and ZK-based deck verification for provable fairness." + </p> + <span class="proj-badge purple">"Selected Project"</span> + </div> + <div class="proj-card featured-cyan"> + <div class="proj-tags"> + <span class="proj-tag purple">"Solana"</span> + <span class="proj-tag cyan">"AI Agents"</span> + <span class="proj-tag muted">"Protocol"</span> + </div> + <h3 class="proj-title">"SOLClaw"</h3> + <p class="proj-desc"> + "Agent runtime and protocol for putting AI agents on-chain on Solana. + Agent identity, memory anchoring, task execution, and payment rails as + protocol primitives." + </p> + <span class="proj-badge cyan">"Selected Project"</span> + </div> + </div> + </div> + </section> + + <div class="section-divider"></div> + + // ── CTA ─────────────────────────────────────────────────── + <section class="cta-section"> + <div class="section-eyebrow"> + <span class="eyebrow-dot eyebrow-dot-purple"></span> + "Open to opportunities" + </div> + <h2 class="cta-headline">"Let's build something" <br/> "that ships."</h2> + <p class="cta-sub"> + "Whether it's a Solana program, a backend system, or a full product — I bring + technical depth and product thinking to every engagement." + </p> + <div class="cta-buttons"> + <a class="btn-primary" href="mailto:alexander.ramirez@gmail.com"> + "alexander.ramirez@gmail.com" + </a> + <a + class="btn-secondary" + href="https://x.com/RamirezAlex_" + target="_blank" + rel="noreferrer" + > + "x.com/RamirezAlex_" + </a> + </div> + </section> </Layout> } } diff --git a/style/main.scss b/style/main.scss index 91552d0..754c392 100644 --- a/style/main.scss +++ b/style/main.scss @@ -1,203 +1,534 @@ -@font-face { - font-family: NotoSansMono; - src: url(../fonts/NotoSansMono-Thin.ttf); - font-weight: lighter; +@import url('https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&family=Geist+Mono:wght@400;500;600&family=Inter:ital,opsz,wght@0,14..32,400;0,14..32,500;0,14..32,600;1,14..32,400&display=swap'); + +/* ── Tokens: light (default) ──────────────────────────────────── */ + +:root { + --bg: #FFFFFF; + --bg-soft: #FAFAFA; + --bg-card: #F4F4F5; + --bg-featured: #F0F0F5; + --text: #09090B; + --text-muted: #71717A; + --text-muted2: #52525B; + --border: #E4E4E7; + --accent: #A855F7; + --accent-cyan: #06B6D4; + --accent-pink: #EC4899; } +/* ── Tokens: dark ─────────────────────────────────────────────── */ -@font-face { - font-family: NotoSansMono; - src: url(../fonts/NotoSansMono-Regular.ttf); +.dark { + --bg: #0A0A0A; + --bg-soft: #0A0A0A; + --bg-card: #111111; + --bg-featured: #0D0D0D; + --text: #FFFFFF; + --text-muted: #A1A1AA; + --text-muted2: #A1A1AA; + --border: #1A1A1A; } -@font-face { - font-family: NotoSansMono; - src: url(../fonts/NotoSansMono-SemiBold.ttf); - font-weight: bold; +/* ── Base reset ───────────────────────────────────────────────── */ + +*, *::before, *::after { + box-sizing: border-box; + margin: 0; + padding: 0; } html, body { height: 100%; - margin: 0 auto; - min-height: 100%; } body { - color: rgb(54, 50, 50); - font-family: NotoSansMono; - line-height: 1.5em; - text-align: center; + font-family: 'Inter', ui-sans-serif, system-ui, sans-serif; + line-height: 1.6; + -webkit-font-smoothing: antialiased; } a { - color: #e75f04ee; + color: inherit; + text-decoration: none; } -nav { - background-color: #e75f04ee; +/* ── Layout wrapper ───────────────────────────────────────────── */ + +.layout { + min-height: 100vh; + background: var(--bg); + color: var(--text); + transition: background 0.2s, color 0.2s; +} + +/* ── Nav ──────────────────────────────────────────────────────── */ + +nav.site-nav { display: flex; + align-items: center; justify-content: space-between; - padding: 15px 50px; + height: 68px; + padding: 0 60px; + background: var(--bg); + border-bottom: 1px solid var(--border); + position: sticky; + top: 0; + z-index: 100; + transition: background 0.2s, border-color 0.2s; +} - a { - color: rgb(54, 50, 50); - text-decoration: none; - margin: 0 10px; - } +.nav-logo { + font-family: 'Geist', 'Inter', sans-serif; + font-size: 18px; + font-weight: 600; + color: var(--text); +} - button { - background: none; - border: none; - cursor: pointer; - font-family: NotoSansMono; - font-size: 16px; - margin-top: 7px; - padding: 0; +.nav-links { + display: flex; + align-items: center; + gap: 32px; +} - &:focus { - outline: 0; - } - } +.nav-link { + font-size: 14px; + color: var(--text-muted2); + transition: color 0.15s; +} - svg { - color: rgb(54, 50, 50); - } +.nav-link:hover { color: var(--text); } + +.mode-toggle { + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + background: none; + border: 1px solid var(--border); + border-radius: 6px; + cursor: pointer; + color: var(--text-muted2); + transition: color 0.15s, background 0.15s, border-color 0.2s; +} + +.mode-toggle:hover { + color: var(--text); + background: var(--bg-card); } -main { - min-height: 100%; +.nav-cta { + padding: 10px 20px; + background: var(--accent); + color: #FFFFFF; + font-size: 14px; + font-weight: 600; + border-radius: 4px; + transition: opacity 0.15s; } -#content { - min-height: calc(100vh - 120px); +.nav-cta:hover { opacity: 0.88; color: #FFFFFF; } + +/* ── Shared utilities ─────────────────────────────────────────── */ + +.section-divider { + height: 1px; + background: var(--border); + width: 100%; + transition: background 0.2s; +} + +.eyebrow-dot { + display: inline-block; + width: 8px; + height: 8px; + border-radius: 50%; + flex-shrink: 0; +} + +.eyebrow-dot-purple { background: var(--accent); } +.eyebrow-dot-cyan { background: var(--accent-cyan); } +.eyebrow-dot-pink { background: var(--accent-pink); } + +.section-header { + display: flex; + flex-direction: column; + gap: 20px; } -header, section { - padding: 50px 30px; +.section-eyebrow { + display: flex; + align-items: center; + gap: 8px; + font-family: 'Geist Mono', ui-monospace, monospace; + font-size: 13px; + color: var(--text-muted); + letter-spacing: 1px; } -article { - text-align: left; +.section-title { + font-family: 'Geist', 'Inter', sans-serif; + font-size: clamp(36px, 4vw, 56px); + font-weight: 700; + color: var(--text); + line-height: 1.1; } -.half-block { +.btn-primary { display: inline-block; - vertical-align: middle; - margin: 0 24px + padding: 14px 28px; + background: var(--accent); + color: #FFFFFF; + font-size: 15px; + font-weight: 600; + border-radius: 4px; + transition: opacity 0.15s; } -.profile-image { - min-height: 260px; - min-width: 260px; - background: url("../images/ramirezalex-white.png") no-repeat center; - background-size: cover; +.btn-primary:hover { opacity: 0.88; color: #FFFFFF; } + +.btn-secondary { display: inline-block; - border-radius: 50%; + padding: 14px 28px; + background: var(--bg-card); + color: var(--text-muted2); + font-size: 15px; + font-weight: 600; + border-radius: 4px; + border: 1px solid var(--border); + transition: background 0.15s, border-color 0.2s; } -.profile-image:hover { - background: url("../images/ramirezalex-color.jpg") no-repeat center; - background-size: cover; - filter: grayscale(65%); +.btn-secondary:hover { color: var(--text-muted2); filter: brightness(0.97); } + +/* ── Hero ─────────────────────────────────────────────────────── */ + +.hero { + display: flex; + align-items: center; + gap: 60px; + padding: 80px 60px; + min-height: 680px; + transition: background 0.2s; } -.dark-mode .profile-image { - filter: invert(1); +.hero-left { + flex: 1; + display: flex; + flex-direction: column; + gap: 28px; + min-width: 0; } -.dark-mode .profile-image:hover { - filter: invert(0) grayscale(65%); +.eyebrow { + display: flex; + align-items: center; + gap: 8px; + font-family: 'Geist Mono', ui-monospace, monospace; + font-size: 13px; + color: var(--text-muted); + letter-spacing: 1px; +} + +.hero-headline { + display: flex; + flex-direction: column; } -.dark-mode #content { - background-color: rgb(12, 16, 32); - color: rgb(255, 255, 255); +.hero-headline span { + font-family: 'Geist', 'Inter', sans-serif; + font-size: clamp(48px, 5vw, 72px); + font-weight: 700; + line-height: 1.05; + color: var(--text); } -.dark-mode nav svg, .dark-mode nav button, .dark-mode nav a { - color: rgb(255, 255, 255); +.hero-headline .hl-accent { + color: var(--accent); } -picture { +.hero-tagline { + font-size: 17px; + color: var(--text-muted); + line-height: 1.6; + max-width: 560px; +} + +.hero-ctas { display: flex; align-items: center; + gap: 16px; + flex-wrap: wrap; } -#bio .profile-biok-image, #bio p { - vertical-align: top; +.hero-right { + width: 460px; + flex-shrink: 0; } -#bio .profile-biok-image { - height: 50px; - width: 50px; - background-size: cover; - display: inline-block; +/* ── Terminal card (intentionally stays dark in both modes) ───── */ + +.terminal-card { + width: 100%; + background: #111111; + border-radius: 12px; + border: 1px solid #1A1A1A; + overflow: hidden; +} + +.terminal-bar { + display: flex; + align-items: center; + gap: 8px; + height: 40px; + padding: 0 16px; + background: #161616; +} + +.terminal-dot { + width: 10px; + height: 10px; border-radius: 50%; - margin-right: 20px; - vertical-align: middle; + flex-shrink: 0; } -#bio p { - width: 85%; - display: inline-block; - text-align: justify; +.terminal-dot.red { background: #EF4444; } +.terminal-dot.yellow { background: #F59E0B; } +.terminal-dot.green { background: #22C55E; } + +.terminal-bar-title { + flex: 1; + text-align: center; + font-family: 'Geist Mono', ui-monospace, monospace; + font-size: 12px; + color: #A1A1AA; } -.dark-mode .profile-biok-image { - filter: invert(1); +.terminal-body { + padding: 20px; + display: flex; + flex-direction: column; + gap: 6px; } -h1 { - font-size: 48px; - font-weight: 300; - color: #4b84ee; - line-height: 3.5rem; +.t-line { + font-family: 'Geist Mono', ui-monospace, monospace; + font-size: 14px; + line-height: 1.5; } -h2 { - font-size: 36px; - font-weight: 300; - line-height: 1rem; +.t-line.cmd { color: #A855F7; } +.t-line.out { color: #FFFFFF; } +.t-line.muted { color: #A1A1AA; } +.t-line.cyan { color: #06B6D4; } +.t-line.green { color: #22C55E; } + +/* ── Skills ───────────────────────────────────────────────────── */ + +.skills-section { + display: flex; + flex-direction: column; + gap: 56px; + padding: 80px 60px; + background: var(--bg-soft); + transition: background 0.2s; } -#info { - font-size: 24px; - line-height: 48px; +.skills-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 2px; } -#info, .blog-article { - border-top: solid 1px #f3d299; - border-bottom: solid 1px #f3d299; +.skill-card { + display: flex; + flex-direction: column; + gap: 20px; + padding: 32px 28px; + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 8px; + transition: background 0.2s, border-color 0.2s; } -.blog-article img { - display: block; - max-width: 60%; - margin: 20px auto; - height: auto; +.skill-num { + font-family: 'Geist Mono', ui-monospace, monospace; + font-size: 40px; + font-weight: 700; + color: var(--accent); } -#social-media ul { - list-style: none; +.skill-title { + font-family: 'Geist', 'Inter', sans-serif; + font-size: 22px; + font-weight: 700; + color: var(--text); } -#social-media ul li { - display: inline-block +.skill-desc { + font-size: 14px; + color: var(--text-muted); + line-height: 1.6; } -#social-media ul li .fab { - font-size: 64px; - color: #4b84ee; - margin: 0 15px; +/* ── Projects ─────────────────────────────────────────────────── */ + +.projects-section { + display: flex; + flex-direction: column; + gap: 48px; + padding: 80px 60px; + transition: background 0.2s; } -footer { - bottom: 0px; - color: rgb(255, 255, 255); - background-color: black; - padding: 20px; +.proj-grid { + display: flex; + flex-direction: column; + gap: 20px; +} + +.proj-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 20px; +} + +.proj-card { + display: flex; + flex-direction: column; + gap: 24px; + padding: 32px 28px; + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 12px; + transition: background 0.2s, border-color 0.2s; +} + +.proj-card.featured-purple { + background: var(--bg-featured); + border-color: rgba(168, 85, 247, 0.3); } +.proj-card.featured-cyan { + background: var(--bg-featured); + border-color: rgba(6, 182, 212, 0.3); +} + +.proj-tags { + display: flex; + gap: 8px; + flex-wrap: wrap; +} + +.proj-tag { + padding: 5px 12px; + background: var(--border); + border-radius: 4px; + font-family: 'Geist Mono', ui-monospace, monospace; + font-size: 12px; + transition: background 0.2s; +} + +.proj-tag.purple { color: var(--accent); } +.proj-tag.cyan { color: var(--accent-cyan); } +.proj-tag.muted { color: var(--text-muted2); } + +.proj-title { + font-family: 'Geist', 'Inter', sans-serif; + font-size: 28px; + font-weight: 700; + color: var(--text); +} + +.proj-desc { + font-size: 14px; + color: var(--text-muted); + line-height: 1.6; +} + +.proj-role { + font-family: 'Geist Mono', ui-monospace, monospace; + font-size: 12px; +} + +.proj-role.purple { color: var(--accent); } +.proj-role.pink { color: var(--accent-pink); } + +.proj-badge { + display: inline-block; + padding: 5px 12px; + border-radius: 4px; + font-family: 'Geist Mono', ui-monospace, monospace; + font-size: 12px; + align-self: flex-start; +} + +.proj-badge.purple { + color: var(--accent); + background: rgba(168, 85, 247, 0.08); + border: 1px solid rgba(168, 85, 247, 0.25); +} + +.proj-badge.cyan { + color: var(--accent-cyan); + background: rgba(6, 182, 212, 0.08); + border: 1px solid rgba(6, 182, 212, 0.25); +} + +/* ── CTA ──────────────────────────────────────────────────────── */ + +.cta-section { + display: flex; + flex-direction: column; + align-items: center; + gap: 32px; + padding: 100px 60px; + background: var(--bg-soft); + text-align: center; + transition: background 0.2s; +} + +.cta-headline { + font-family: 'Geist', 'Inter', sans-serif; + font-size: clamp(36px, 5vw, 64px); + font-weight: 700; + color: var(--text); + line-height: 1.05; + max-width: 900px; +} + +.cta-sub { + font-size: 17px; + color: var(--text-muted); + line-height: 1.6; + max-width: 600px; +} + +.cta-buttons { + display: flex; + align-items: center; + gap: 16px; + flex-wrap: wrap; + justify-content: center; +} + +/* ── Footer ───────────────────────────────────────────────────── */ + +footer.site-footer { + display: flex; + align-items: center; + justify-content: space-between; + height: 64px; + padding: 0 60px; + background: var(--bg); + border-top: 1px solid var(--border); + font-size: 13px; + color: var(--text-muted); + transition: background 0.2s, border-color 0.2s; +} + +/* ── Blog styles (preserved) ──────────────────────────────────── */ + .page-blog-index { display: flex; flex-wrap: wrap; @@ -205,10 +536,9 @@ footer { padding: 50px; list-style: none; justify-content: center; - text-decoration: none; li { - color: rgb(255, 255, 255); + color: #FFFFFF; padding: 0; margin: 20px; width: 460px; @@ -217,7 +547,7 @@ footer { border-radius: 10px; a { - color: rgb(255, 255, 255); + color: #FFFFFF; text-decoration: none; } @@ -253,7 +583,7 @@ footer { } .page-blog nav { - padding: 10px 0px; + padding: 10px 0; } .page-blog nav ul { @@ -266,45 +596,67 @@ footer { } .page-blog nav a { - color: black; + color: var(--text); } -.dark-mode .page-blog nav a { - color: white; +/* ── Responsive ───────────────────────────────────────────────── */ + +@media (max-width: 1024px) { + .skills-grid { + grid-template-columns: repeat(2, 1fr); + } } -@media screen and (max-width: 480px) { - .main-menu { - margin-top: 5px; +@media (max-width: 768px) { + nav.site-nav { + padding: 0 24px; + height: 60px; + } + + .nav-links { + gap: 16px; + } + + .hero { + flex-direction: column; + padding: 48px 24px; + min-height: unset; + gap: 40px; + } + + .hero-right { + width: 100%; } - - h2 { - line-height: 1.4em; + + .skills-section, + .projects-section, + .cta-section { + padding: 60px 24px; } - #social-media ul li .fab { - font-size: 32px; + + .skills-grid { + grid-template-columns: 1fr; + gap: 12px; + } + + .proj-row { + grid-template-columns: 1fr; + } + + footer.site-footer { + flex-direction: column; + height: auto; + gap: 8px; + padding: 20px 24px; + text-align: center; } } -/* Color styles */ -.hh1 { color: #FF79C6; } /* attribute - Pink */ -.hh2 { color: #BD93F9; } /* constant - Purple */ -.hh3 { color: #50FA7B; } /* function.builtin - Green */ -.hh4 { color: #50FA7B; } /* function - Green */ -.hh5 { color: #FF79C6; } /* keyword - Pink */ -.hh6 { color: #F1FA8C; } /* operator - Light Yellow */ -.hh7 { color: #BD93F9; } /* property - Purple */ -.hh8 { color: #F8F8F2; } /* punctuation - Light Foreground */ -.hh9 { color: #F8F8F2; } /* punctuation.bracket - Light Foreground */ -.hh10 { color: #F8F8F2; } /* punctuation.delimiter - Light Foreground */ -.hh11 { color: #F1FA8C; } /* string - Light Yellow */ -.hh12 { color: #F1FA8C; } /* string.special - Light Yellow */ -.hh13 { color: #F8F8F2; } /* tag - Light Foreground */ -.hh14 { color: #8BE9FD; } /* type - Cyan */ -.hh15 { color: #8BE9FD; } /* type.builtin - Cyan */ -.hh16 { color: #50FA7B; } /* variable - Green */ -.hh17 { color: #FFB86C; } /* variable.builtin - Orange */ -.hh18 { color: #FFB86C; } /* variable.parameter - Orange */ -.hh19 { color: #6272A4; } /* comment - Comment Grey */ -.hh20 { color: #FFB86C; } /* macro - Orange */ -.hh21 { color: #FF5555; } /* label - Red */ +@media (max-width: 480px) { + .hero-ctas, + .cta-buttons { + flex-direction: column; + align-items: stretch; + text-align: center; + } +}