Portifolio
About Me
Portifolio
Contact

Ridgeline Slope Recommender

Building a Ski Run Recommendations App with Replit

CONTEXT:

I was working weekends at a ski rental shop in Big Sky, MT, and customers would often ask for run recommendations. Big Sky is huge, and the right run depends on many factors: a skier’s ability, current snow conditions, and personal preferences for terrain or what they want to avoid.

Having spent the past few years designing ML-powered products at Attentive, I wondered if a ski recommendation app existed. While there are plenty of trail maps and guides, I couldn’t find a tool that generated run recommendations based on a skier’s inputs

Replit was the perfect AI tool to bring this idea to life. It allowed me to quickly prototype the concept and build a simple system that could translate skier preferences into personalized run recommendations. As a product designer (and intermediate skier), I got to work.

DISCOVERY & USER INSIGHT:

I started with competitive research to understand the current landscape. Most existing apps focus on maps, conditions, or performance tracking, rather than recommending runs based on skier preferences.

  • Slopes: Ski performance tracking
  • Ski Tracks: GPS run tracking
  • PistePal: Interactive ski resort maps
  • AllTrails: Interactive ski resort maps
  • Resort Maps: Trail discovery for hiking

Next, I identified where the product gaps were, and what users still needed to choose the right run.

1. No personalized run recommendations

Most ski apps provide maps or performance tracking, but none recommend specific runs based on a skier’s ability level, preferences, or goals.

2. Static trail maps are hard to interpret

Ski maps are often difficult to interpret, especially for beginners or skiers unfamiliar with a resort.

3. Run choice depends on conditions and local knowledge

Snow conditions, grooming, crowds, and time of day all affect which runs are best, so skiers often rely on instructors or friends for recommendations. This expertise is valuable, but not scalable.

4. Resorts are too large to navigate easily

At large resorts with hundreds of runs, skiers often repeat the same terrain, miss out on runs that would be great for their level, or accidentally end up on terrain beyond their ability.

PRODUCT EXECUTION:

I built a minimum viable product (MVP) to test whether skier preferences could translate into useful run recommendations. The goal was to quickly validate the core idea, gather feedback, and lay the groundwork for future development.

Building the framework

I used ChatGPT to generate a product requirements document (PRD) outlining the app’s goals, features, and design requirements. I then uploaded this document into Replit to guide the development process.

# Product Requirements Document (PRD)

## Product Name (Working)
Ridgeline

## Overview
Ridgeline is a SaaS application that provides personalized ski run recommendations based on a skier’s skill level, preferences, location, and trip plans. Unlike traditional green/blue/black classifications, Ridgeline evaluates runs using richer, more nuanced data (terrain, pitch, grooming, exposure, crowding, conditions) to help beginners, intermediate, and advanced skiers choose runs they can confidently prepare for and enjoy.

The app supports both real-time discovery at a resort (via location sharing) and global search for trip planning.

## Problem Statement
Skiers often struggle to pick runs that match their true ability:
- Trail color alone is too coarse and inconsistent across resorts
- Beginners accidentally end up on intimidating terrain
- Intermediate skiers plateau because they don’t know which runs push them safely
- Advanced skiers want specifics (steepness, exposure, moguls, trees, groomed vs ungroomed)

Existing ski apps focus on maps or tracking, not intelligent, skill-aware recommendations.

## Goals & Success Metrics

### Goals
- Help skiers choose runs they can ski safely and confidently
- Enable skill progression through informed recommendations
- Make trip planning easier and more personalized

### Success Metrics
- % of users who follow recommended runs
- User-reported satisfaction with recommendations
- Retention across multiple ski days or trips
- Reduction in “wrong run” feedback (too hard / too easy)

## Target Users

### Primary Personas
1. Beginner Skier
   - New to skiing or early-stage
   - Wants confidence and safety
   - Needs reassurance beyond trail color

2. Intermediate Skier
   - Comfortable on blues, some blacks
   - Wants to progress without fear
   - Needs help understanding what makes a run harder

3. Advanced Skier
   - Seeks specific terrain types
   - Cares about pitch, exposure, moguls, trees, grooming
   - Wants efficient discovery at new resorts

## Key Use Cases

1. **On-Mountain Discovery**
   - User allows location access
   - App detects current resort
   - Shows nearby recommended runs ranked by fit

2. **Trip Planning**
   - User searches a resort anywhere in the world
   - Filters runs by skill level, terrain preferences, conditions
   - Saves runs to a trip plan

3. **Skill Progression**
   - User indicates goals (e.g. “get comfortable with steeper blues”)
   - App recommends stepping-stone runs

## Core Features

### 1. User Profile & Skill Modeling
- Self-assessed skill level (Beginner / Intermediate / Advanced)
- Optional onboarding quiz:
  - Comfort with steepness
  - Experience with moguls, trees, ice, powder
  - Speed preference
- Skill model updates over time (optional future enhancement)

### 2. Location & Search
- Location-based resort detection (opt-in)
- Global resort and run search
- Map and list views

### 3. Run Recommendation Engine
Runs are evaluated beyond color using multiple attributes:
- **Average & max pitch (steepness)**
- **Run length**
- **Width**
- **Grooming frequency**
- **Terrain type** (groomed, moguls, trees, bowls)
- **Exposure** (cliffs, narrow sections)
- **Typical crowd level**
- **Icy / variable condition likelihood**

Each run receives a **Difficulty Profile** and a **Skill Fit Score** per user.

In addition, the engine supports **dynamic and history-based recommendations**:
- Users can mark runs as completed
- The system learns which difficulty attributes the user succeeds on and enjoys
- Completed runs are clustered by terrain profile
- The app recommends **similar runs**:
  - At the same resort (next-step progression)
  - At different resorts (trip planning)

Example: “You handled long, moderately steep groomed blues well → try these runs with similar pitch but more variable snow.”

### 4. Run Detail Pages
Each run includes:
- Trail map highlight
- Difficulty breakdown (why it’s challenging)
- “Why this run is / isn’t right for you”
- Prep tips (e.g. technique, mindset, conditions to avoid)

### 5. Filters & Preferences
- Terrain preferences
- Avoidances (e.g. moguls, narrow runs)
- Desired challenge level (comfort vs stretch)

### 6. Dynamic Learning & Personalization
- Run history stored per user
- Explicit feedback options (Loved it / Too hard / Too easy)
- Progressive adjustment of Skill Fit Scores
- Cross-resort similarity matching based on terrain profiles
- Ability to reset or lock skill level manually

### 7. Safety & Transparency
- Clear disclaimers
- Highlight conditions where a run becomes harder
- Confidence indicators instead of guarantees

## Non-Goals (V1)
- Real-time snow condition prediction
- Live crowd tracking
- Ski tracking or performance analytics
- Social features

## Technical Considerations (Replit-Friendly)

### Architecture
- Frontend: React or Next.js
- Backend: Node.js / Python API
- Database: Postgres or Supabase
- Third-party data:
  - Resort & run data providers
  - Elevation and terrain APIs

### Recommendation Logic (V1)
- Rule-based scoring system
- Weighted attributes per skill level
- Configurable via admin dashboard

### Future Enhancements
- Machine learning personalization
- Integration with weather and snow reports
- User feedback loop (“too hard / too easy”)

## Risks & Mitigations

- **Inconsistent trail ratings across resorts** → Normalize using objective metrics
- **Liability concerns** → Clear disclaimers and conservative recommendations
- **Data gaps** → Start with major resorts, expand gradually

## Open Questions
- Which resort data provider to use?
- How much personalization in onboarding vs friction?
- Monetization model (subscription, trip packs, B2B partnerships?)

---

This PRD defines the foundation for building Ridgeline as a smart, confidence-first ski run recommendation platform.


```

Designing the app

I created wireframes and defined colors and UI patterns, which helped when prompting Replit to implement the visual experience.

When iterating, I would address one functionality at a time. I would give Replit expectations for the output, and how the sections should appear aesthetically.

By default, Ridegeline strategically uses a dark mode UI so that the app is readable during "bluebird" ski days that are bright and sunny. Users can switch to light mode if that's more readable for them.

User flow:

  • Find resorts near them via location accuracy, or search for a resort
  • Input skill level and preferences
  • View run recommendations for each resort

Loading in data

I downloaded and converted lists of ski runs for Big Sky and Bridger Bowl, since I could validate the data quality based on my own experience.

ChatGPT helped me match runs to the correct ski lift, and then score the runs based on difficulty. This score combined the official trail map rating with terrain characteristics such as steepness or terrain type. The runs were then stored in a structured JSON format so they could be filtered and recommended programmatically based on a skier’s skill level.

{
  "name": "Liberty Bowl",
  "difficulty": "advanced",
  "lift": "Powder Seeker",
  "terrain": ["bowl"],
  "exposure": "high"
}

An inference script was then written to recommend runs based on the skier’s ability level by filtering the dataset for runs at or below the user’s skill level.

function recommendRuns(userLevel) {
  return runs.filter(run => {
    if (userLevel === "expert") return true
    if (userLevel === "advanced") return run.difficulty !== "expert"
    if (userLevel === "intermediate") return run.difficulty === "intermediate"
    return run.difficulty === "beginner"
  })
}

This allowed the model to dynamically recommend appropriate ski runs while filtering out terrain that would be unsafe or too difficult for the user.

We’re live! While I’m currently working to load in more resort data, you can check out recs for Bozeman, Montana at ridgeline-ski.com.

IMPACT

This results section is a little different – I would love to hear any feedback you have after checking out Ridgeline. That can be bugs you caught, gaps, or ideas that would make this product more useful.

Thank you! Your submission has been received.
Oops! Something went wrong while submitting the form.

Next Project
LinkedIn
Resume
Email