Skip to main content

Overview

The skills data structure powers the Skills & Services section of the portfolio. It’s defined in src/data/skills.ts and consumed by src/components/Skills.astro. This file exports three main arrays:
  • skills - Technology badges for the infinite marquee
  • technicalServices - Technical service offerings
  • operationalServices - Operational and leadership services

Skills Array

Structure

The skills array defines technology badges with visual styling:
export const skills = [
  { name: 'JavaScript', color: '#f7df1e', bg: '#1a1800', letter: 'JS' },
  { name: 'TypeScript', color: '#3178c6', bg: '#001428', letter: 'TS' },
  // ...
];

Field Reference

FieldTypeDescription
namestringFull technology name
colorstringHex color for text and border
bgstringHex color for badge background
letterstring1-2 character icon or emoji

Current Skills

JavaScript

Color: #f7df1e (yellow) Letter: JS

TypeScript

Color: #3178c6 (blue) Letter: TS

React

Color: #61dafb (cyan) Letter:

Next.js

Color: #e0e0e0 (light gray) Letter: N

Node.js

Color: #68a063 (green) Letter:

Tailwind

Color: #06b6d4 (cyan) Letter:

Astro

Color: #ff5d01 (orange) Letter: 🚀

Git

Color: #f05032 (red-orange) Letter:

Linux

Color: #fcc624 (yellow) Letter: 🐧

Complete Skills Data

export const skills = [
  { name: 'JavaScript', color: '#f7df1e', bg: '#1a1800', letter: 'JS' },
  { name: 'TypeScript', color: '#3178c6', bg: '#001428', letter: 'TS' },
  { name: 'React',      color: '#61dafb', bg: '#001219', letter: '⚛'  },
  { name: 'Next.js',    color: '#e0e0e0', bg: '#151515', letter: 'N'  },
  { name: 'Node.js',    color: '#68a063', bg: '#0b1a0b', letter: '⬡'  },
  { name: 'Tailwind',   color: '#06b6d4', bg: '#001417', letter: '≋'  },
  { name: 'Astro',      color: '#ff5d01', bg: '#1a0800', letter: '🚀' },
  { name: 'Git',        color: '#f05032', bg: '#1a0800', letter: '⎇'  },
  { name: 'Linux',      color: '#fcc624', bg: '#1a1400', letter: '🐧' },
];

Color Guidelines

1

Use brand colors

Match official brand colors for each technology (e.g., TypeScript blue, React cyan)
2

Dark backgrounds

Background colors should be very dark (#1a... range) to work with the dark theme
3

Sufficient contrast

Ensure the color value has good contrast against the bg value
4

Border transparency

The component applies ${skill.color}22 (8-bit alpha) for subtle borders

Technical Services

Structure

export const technicalServices = [
  {
    title: 'Web Development',
    items: ['React / Next.js SPAs', 'REST & GraphQL APIs', 'Performance optimization'],
  },
  // ...
];

Complete Data

export const technicalServices = [
  {
    title: 'Web Development',
    items: ['React / Next.js SPAs', 'REST & GraphQL APIs', 'Performance optimization'],
  },
  {
    title: 'Mobile Development',
    items: ['React Native cross-platform', 'iOS & Android deployment', 'Offline-first architecture'],
  },
  {
    title: 'UI/UX Design',
    items: ['Responsive design systems', 'Figma prototyping', 'Accessibility (WCAG 2.1)'],
  },
];

Web Development

React/Next.js SPAs, REST & GraphQL APIs, Performance optimization

Mobile Development

React Native cross-platform, iOS & Android deployment, Offline-first architecture

UI/UX Design

Responsive design systems, Figma prototyping, Accessibility (WCAG 2.1)

Operational Services

Structure

export const operationalServices = [
  {
    title: 'Operations Management',
    items: ['Distribution center processes', 'Documentation and training', 'Operational KPIs & reporting'],
  },
  // ...
];

Complete Data

export const operationalServices = [
  {
    title: 'Operations Management',
    items: ['Distribution center processes', 'Documentation and training', 'Operational KPIs & reporting'],
  },
  {
    title: 'Project Management',
    items: ['Sprint planning', 'Team coordination', 'Stakeholder communication'],
  },
  {
    title: 'Systems Thinking',
    items: ['Process mapping', 'Data-driven decision making', 'Cross-functional leadership'],
  },
];

Operations Management

Distribution center processes, Documentation and training, Operational KPIs & reporting

Project Management

Sprint planning, Team coordination, Stakeholder communication

Systems Thinking

Process mapping, Data-driven decision making, Cross-functional leadership

Adding New Skills

1

Find the brand color

Look up the official brand color for the technology (usually in their brand guidelines)
2

Calculate dark background

Create a very dark version by reducing RGB values dramatically
3

Choose a letter/symbol

Use initials, emoji, or Unicode symbols that represent the technology
4

Add to the array

{ name: 'PostgreSQL', color: '#336791', bg: '#001219', letter: '🐘' }
Skills appear twice in the marquee animation (duplicated array). Keep the array length reasonable (8-12 items) for smooth animation.

Adding New Services

For Technical Services

{
  title: 'Your Service Category',
  items: [
    'Specific skill or deliverable',
    'Another capability',
    'Third offering'
  ],
}

For Operational Services

{
  title: 'Leadership Category',
  items: [
    'Operational capability',
    'Management skill',
    'Strategic competency'
  ],
}
Each service category should have exactly 3 items for visual consistency.

Usage in Components

The skills data is consumed in src/components/Skills.astro:

Infinite Marquee

<div class="flex w-max gap-4 animate-marquee">
  {[...skills, ...skills].map((skill) => (
    <div class="flex items-center gap-2.5 bg-card border rounded-full py-2 pl-2 pr-5">
      <span
        class="w-8 h-8 rounded-full border flex items-center justify-center"
        style={`color:${skill.color};background:${skill.bg};border-color:${skill.color}22`}
      >
        {skill.letter}
      </span>
      <span class="text-sm font-medium">{skill.name}</span>
    </div>
  ))}
</div>

Array Duplication

Skills array is duplicated with [...skills, ...skills] to create seamless infinite scroll

Inline Styling

Colors are applied via style attribute for dynamic theming per skill

Service Cards

{technicalServices.map((service) => (
  <div class="rounded-lg border bg-card p-6">
    <h3 class="font-bold mb-4">{service.title}</h3>
    <ul class="space-y-3">
      {service.items.map((item) => (
        <li class="flex items-center gap-2.5">
          <span></span>
          {item}
        </li>
      ))}
    </ul>
  </div>
))}
The same pattern is used for operationalServices in the second column.

Styling Details

Marquee Animation

The infinite scroll is achieved with Tailwind’s animate-marquee custom animation:
@keyframes marquee {
  0% { transform: translateX(0); }
  100% { transform: translateX(-50%); }
}
The animation translates by -50% because the skills array is duplicated.

Hover States

Skill Badges

Translate up slightly on hover, pause the marquee animation

Service Cards

Translate up, brighten border, show top gradient line

Best Practices

Skill Count

Keep skills array between 8-12 items for optimal marquee performance

Service Balance

Maintain equal number of technical and operational service categories

Item Consistency

Each service should have exactly 3 items for visual harmony

Letter Variety

Mix text initials with Unicode symbols and emoji for visual interest

Color Reference

Here are the exact colors used for each skill badge:
TechnologyColorBackgroundSymbol
JavaScript#f7df1e#1a1800JS
TypeScript#3178c6#001428TS
React#61dafb#001219
Next.js#e0e0e0#151515N
Node.js#68a063#0b1a0b
Tailwind#06b6d4#001417
Astro#ff5d01#1a0800🚀
Git#f05032#1a0800
Linux#fcc624#1a1400🐧

Extending the Data

When adding new entries:
  1. Skills: Add to the end of the array for smooth marquee integration
  2. Services: Add new categories between existing ones or at the end
  3. Testing: Always preview in the browser to ensure colors work in dark mode
  4. Consistency: Follow the existing patterns for structure and naming