DEV Community

Cover image for Building Ekehi Sprint 3: Code, People, and the Journey So Far
Oluchi Okwuosa
Oluchi Okwuosa

Posted on

Building Ekehi Sprint 3: Code, People, and the Journey So Far

This week my task was refactoring the What We Offer section on the Ekehi landing page. The section existed already but used a static layout. The new design called for a two-column grid with a selectable list on the left and a static contextual image on the right, with the active list item highlighted in lavender.


The Task

This week's task had me refactoring someone else's code from the team and it was a whole new experience for me, having to read and understand the person's logic and idea and also looking at the new design to figure out what needs to change and what needs to remain.

The specific requirements were:

  • Two-column layout using CSS Grid
  • Four selectable items: Funding Database, Training Programmes, Business Tools, Mentorship Network
  • Active item gets a lavender highlight background
  • JavaScript click handlers so clicking an item activates it
  • Training Programmes selected by default on page load
  • Right column image stays static

Technical Decisions

  • Restructuring the HTML

The first step was getting the HTML structure right before touching any CSS. The existing markup did not follow BEM naming consistently and had unnecessary wrapper divs adding noise without purpose.

The final structure uses semantic HTML throughout. A <ul> with <li> items for the list since they are a collection of related items. Each <li> contains a <div> for the card rather than <article>. Article is for self-contained content that makes sense outside of its context, like a blog post. A feature item in a list does not meet that bar, so a plain div is more accurate.

The BEM naming across the section:

offerings (section)
  offerings__grid (two column wrapper)
    offerings__left (left column)
      offerings__title
      offerings__list (ul)
        offerings__item (li)
          offerings__card (div)
            offerings__card-title
            offerings__card-description
    offerings__right (right column)
      offerings__subtitle
      offerings__image
Enter fullscreen mode Exit fullscreen mode

  • CSS Grid for the Two Column Layout

The layout decision between Flexbox and CSS Grid came down to what the design needed. Flexbox handles one dimension, either a row or a column. CSS Grid handles two dimensions simultaneously. Since the two columns needed to be aware of each other vertically, Grid was the right choice.

.offerings__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-10);
  align-items: stretch;
}
Enter fullscreen mode Exit fullscreen mode

align-items: stretch makes both columns the same height, which is what allowed the image to fill the full height of the right column to match the Figma design.

Inside the left column, Flexbox handles the vertical stacking of the title and list since it is one dimension. This is the most common real world pattern: Grid for the macro layout, Flexbox for the micro layout inside it.


  • Styling the Active State
.offerings__card--active {
  background-color: var(--color-purple-50);
}

.offerings__card:hover {
  background-color: var(--color-primary-subtle);
  cursor: pointer;
  padding-inline: var(--space-4);
}
Enter fullscreen mode Exit fullscreen mode

No hardcoded colour values. Everything references the design system's CSS custom properties.


  • JavaScript Click Handlers

The interactivity required was straightforward. Clicking a card removes the active state from all cards and adds it to the clicked one. Training Programmes gets the active class in the HTML by default so it is highlighted on page load without JavaScript needing to do anything extra.

const cards = document.querySelectorAll('.offerings__card');

cards.forEach(card => {
  card.addEventListener('click', () => {
    cards.forEach(c => c.classList.remove('offerings__card--active'));
    card.classList.add('offerings__card--active');
  });
});
Enter fullscreen mode Exit fullscreen mode

The reason .offerings__card is targeted in the JS and not .offerings__item is because offerings__card--active is the class that controls the highlight and it lives on the div, not the li. You target what you need to add and remove the class on.


  • Responsive Styles
@media (max-width: 900px) {
  .offerings__grid {
    grid-template-columns: 1fr;
  }
  .offerings__image {
    aspect-ratio: 16 / 9;
  }
}

@media (max-width: 600px) {
  .offerings__image {
    aspect-ratio: 4 / 3;
    border-radius: var(--radius-2xl);
  }
}
Enter fullscreen mode Exit fullscreen mode

On tablet and below, the two columns stack into a single column. The image switches from a fixed height to an aspect ratio so it scales proportionally on smaller screens.


Bugs Encountered

The image height was the trickiest part. The original CSS had aspect-ratio: 1/1 applied to the wrong element. It was on the right column container which also holds the subtitle text, not just the image. This clipped the subtitle. Moving the aspect ratio and border radius to .offerings__image directly fixed it. The final approach removed the fixed aspect ratio entirely and used a fixed height instead, letting object-fit: cover handle the cropping.

CSS variable math was another small one. At one point the image height was written as:

height: var(--space-10) * 10;
Enter fullscreen mode Exit fullscreen mode

This is invalid CSS. Math outside of calc() does not work. The correct syntax is:

height: calc(var(--space-10) * 10);
Enter fullscreen mode Exit fullscreen mode

Or just a plain pixel value. Small syntax mistake that was pretty easy to miss.


Reflections

This is the first group project I have ever worked on and that alone made
it a different experience from anything I had done before.

Using GitHub Issues made task assignment straightforward. Every task had a
clear description, acceptance criteria, and an assignee. You knew exactly
what you were supposed to build and what done looked like. That structure
made it easy to pick up work and stay focused.

ClickUp was completely new to me. Setting it up, configuring the custom
fields, managing the board day to day, and keeping it updated across a team
of 15 people was a skill I picked up entirely on this project. I did not
expect project management tooling to be something I would learn here but it
turned out to be one of the more valuable things I walked away with.

Working as the People Manager gave me a different kind of insight. Managing
people is genuinely hard, especially when communication breaks down. When
team members do not turn in their tasks or go quiet, it does not just affect
their own work, it creates more workload for everyone waiting on them
downstream. That lesson about communication and accountability is one I will
carry into every team I work with going forward.

On the technical side, coming into this project as a beginner and working
through forking, upstream syncing, pull requests, merge conflicts, and ES
module imports across three sprints was a real growth arc. The git workflow
alone taught me more than I expected. Working within a design system with
defined CSS variables and utility classes was also new. Writing styles that
trace back to a single source of truth rather than hardcoding values
everywhere is a discipline that will transfer to any professional project.

What worked well was the tooling and the cooperation when it was there.
GitHub Issues, ClickUp, and the branching strategy kept the project
structured even when things got messy. The team leads showing up and keeping
things moving made the difference in the sprints where momentum could have
stalled.

If I could do anything differently, honestly nothing. Every part of this
was a learning experience I am grateful for. I got to try things I had never
done before, sharpened my communication, took on responsibility, and shipped
real work on a real project. That is what I came for.

Meet The Team

  • Frontend Track:

Marionbraide — marionbraideinfo@gmail.com

Osezele Iboi — ejemeniboi@gmail.com

Esther Orieji — oriejiesther@gmail.com

Iyobosa — omosiyobo@gmail.com

Oluchi Okwuosa — Okwuosaoluchi95@gmail.com

Victor Okoukoni — victorokoukoni@gmail.com

Florence Onwuegbuzie — florenceworkhub@gmail.com

Fatihat - @khaerie

  • UI/UX Track:

Michael Babjide Boluwatife

Fisayo Rotibi

Osuji Wisdom

  • Mobile Track:

Gabriel Abubakar — Contributing as QA

Jesse Nwaokolo — Contributing to frontend

  • Backend Track:

Olusegun Adeleke

Sodiq Semiu

TEE Foundation | Tabi Project | International Women's Day Initiative | March 2026

Top comments (0)