Files
code-crispies/README.md
Michael Czechowski bf20e9d39e
Some checks failed
CI / ci (push) Failing after 1s
Deploy / deploy (push) Failing after 1s
ci: update runner-image + repo path to public/ namespace
Repos moved to public/ on Gitea: public/runner-image (CI image)
and public/code-crispies (this repo). Updates workflow image refs,
spec hyperlinks, README, and compose tags.
2026-04-30 11:54:06 +02:00

9.3 KiB

Code Crispies Logo

Code Crispies

An interactive platform for learning HTML, CSS, and Tailwind CSS through practical challenges.

📚 Overview

Code Crispies is a web-based learning platform designed to help users master HTML, CSS, and Tailwind CSS through hands-on exercises. The application presents a series of progressive challenges organized into themed modules, allowing learners to build their skills step by step while receiving immediate feedback.

Key Features

  • Interactive Lessons: Learn HTML, CSS, and Tailwind concepts through practical, hands-on challenges
  • Multiple Learning Paths: CSS fundamentals, HTML semantics, and Tailwind CSS utilities
  • Progressive Difficulty: Modules are structured to build skills gradually from basic to advanced
  • Real-Time Feedback: Get immediate validation on your code solutions with comprehensive feedback
  • Progress Tracking: Your learning progress is automatically saved in the browser
  • Visual Preview: See the results of your code in real-time with live preview
  • Comprehensive Modules: Cover various CSS and Tailwind topics in organized learning paths
  • Schema-Validated Lessons: All lessons follow a strict JSON schema for consistency

🛠️ Technical Stack

  • Pure JavaScript (ES Modules)
  • HTML5 & CSS3
  • Vite for bundling and development
  • Vitest for testing with coverage reporting
  • JSON Schema validation for lesson structure
  • Local Storage for progress persistence
  • whatwg-fetch polyfill for compatibility

🚀 Getting Started

Prerequisites

  • Node.js (v18 or higher recommended)
  • npm (v8 or higher recommended)

Installation

  1. NVM (optional)

    nvm use
    
  2. Clone the repository:

    git clone https://git.librete.ch/public/code-crispies.git
    cd code-crispies
    
  3. Install dependencies:

    npm i
    
  4. Start the development server:

    npm start
    
  5. Open your browser and navigate to:

    http://localhost:1312
    

Available Scripts

  • npm start - Start the development server (alias for npm run dev)
  • npm run dev - Start the development server with host binding
  • npm run build - Build for production
  • npm run preview - Preview the production build locally with debug mode
  • npm run test - Run tests once
  • npm run test.watch - Run tests in watch mode
  • npm run test.coverage - Run tests with coverage report
  • npm run format - Format source code with Prettier (includes config files)
  • npm run format.lessons - Format lesson JSON files with Prettier

📖 Usage Guide

How to Use Code Crispies

  1. Select a Module: Choose a learning module from the available options
  2. Choose Mode: Select between CSS or Tailwind CSS learning mode (if applicable)
  3. Read the Challenge: Each lesson includes a description, task instructions, and learning objectives
  4. Write Code: Enter your CSS or Tailwind solution in the editor
  5. Run Your Code: Click the "Run" button (or press Ctrl+Enter) to test your solution
  6. Review Feedback: Get comprehensive feedback with validation messages
  7. Progress: Move to the next lesson once your solution passes all validations

Keyboard Shortcuts

  • Ctrl+Enter - Run your code
  • Tab - Insert appropriate indentation

🧩 Project Structure

code-crispies/
├── coverage/          # Test coverage reports
├── docs/              # Documentation files (multilingual)
├── lessons/           # JSON lesson definitions
├── public/            # Static assets and PWA manifests
├── schemas/           # JSON Schema definitions
│   └── code-crispies-module-schema.json
├── src/
│   ├── config/        # Configuration files
│   │   └── lessons.js # Module and lesson loading logic
│   ├── helpers/       # Helper utilities
│   │   ├── renderer.js # UI rendering functions
│   │   └── validator.js # Code validation logic
│   ├── impl/
│   │   └── LessonEngine.js # Core lesson processing logic
│   ├── app.js         # Main application entry point
│   ├── index.html     # Main HTML template
│   └── main.css       # Global styles
├── tests/             # Test files
│   ├── setup.js       # Test configuration
│   └── unit/          # Unit tests
├── vite.config.js     # Vite configuration
└── vitest.config.js   # Vitest configuration

📝 Adding New Lessons

Lessons are defined in JSON format following the schema in schemas/code-crispies-module-schema.json. Each module includes comprehensive lesson definitions with validation rules.

Module Structure

{
  "id": "unique-module-id",
  "title": "Module Title",
  "description": "Detailed description of module content and purpose",
  "mode": "css", // or "tailwind"
  "difficulty": "beginner", // "intermediate" or "advanced"
  "lessons": [
    // Lesson objects...
  ]
}

Lesson Structure

{
  "id": "unique-lesson-id",
  "title": "Lesson Title",
  "description": "Detailed lesson description and concepts",
  "mode": "css", // Optional override for module mode
  "task": "Specific task instructions for the student",
  "previewHTML": "<div>HTML for preview</div>",
  "previewBaseCSS": "/* Base styles for preview */",
  "sandboxCSS": "/* Additional sandbox styles */",
  "initialCode": "/* Starting code for student */",
  "solution": "/* Optional solution code */",
  "previewContainer": "container-id",
  "validations": [
    {
      "type": "contains", // "contains_class", "not_contains", "regex", "property_value", "syntax", "custom"
      "value": "expected-content",
      "message": "Feedback message for validation failure",
      "options": {
        "caseSensitive": false
      }
    }
  ]
}

Validation Types

  • contains: Check if code contains specific text
  • contains_class: Check if HTML contains specific CSS class
  • not_contains: Ensure code doesn't contain specific text
  • regex: Validate against regular expression pattern
  • property_value: Validate specific CSS property values
  • syntax: Check for valid CSS syntax
  • custom: Custom validation logic

🧪 Testing

The project uses Vitest for comprehensive testing with coverage reporting. Tests are organized in the tests/unit/ directory.

Run tests:

npm run test

Run tests in watch mode:

npm run test.watch

Generate coverage report:

npm run test.coverage

Coverage reports are generated in the coverage/ directory with detailed HTML reports.

🚢 Deployment

Static build

npm run build

Outputs to dist/. Deployable to any static web server.

For GitHub Pages, base path /code-crispies/ is preconfigured.

npm run preview   # local prod preview

Docker (Netcup VPS)

This repo is the deployable unit for cc.cloud.librete.ch on the Netcup VPS — sibling to caddy, immich, mp, umami (see libretech/netcup). Multi-stage Dockerfile builds the static bundle and serves it via nginx; compose.yaml joins the external edge network so Caddy reverse-proxies to it.

# from a workstation
git push
ssh netcup
cd /srv/cc
git pull
docker compose build
docker compose up -d

First-time setup on the server

ssh netcup
git clone ssh://tengo@git.librete.ch:41240/public/code-crispies.git /srv/cc
cd /srv/cc
cp .env.example .env
$EDITOR .env   # fill VITE_SUPABASE_URL + VITE_SUPABASE_ANON_KEY
chmod 600 .env
docker compose build
docker compose up -d

# Verify
docker compose ps
docker compose exec -T cc wget -qO- http://127.0.0.1/health
curl -sS https://cc.cloud.librete.ch/   # via caddy

The nginx config inside the image rewrites unknown paths to index.html so client-side routing keeps working. VITE_SUPABASE_* are baked into the bundle at docker compose build, so a rebuild is needed when they change.

🌐 Internationalization

The project supports multiple languages:

Localized Lessons

Lessons are available in the lessons/ directory with language-specific subdirectories:

  • English (default): lessons/*.json
  • Arabic: lessons/ar/
  • German: lessons/de/
  • Spanish: lessons/es/
  • Polish: lessons/pl/
  • Ukrainian: lessons/uk/

Documentation

Multilingual documentation in the docs/ directory:

  • English documentation (en-*.md)
  • German documentation (de-*.md)

🤝 Contributing

Contributions are welcome! Please ensure all lessons follow the JSON schema validation.

  1. Fork the repository
  2. Create your feature branch (git switch -c feature/amazing-feature)
  3. Add/modify lessons following the schema in schemas/code-crispies-module-schema.json
  4. Format your code: npm run format and npm run format.lessons
  5. Run tests: npm run test
  6. Commit your changes (git commit -m 'Add some amazing feature')
  7. Push to the branch (git push origin feature/amazing-feature)
  8. Open a Pull Request

Adding New Lessons

When adding new lessons:

  1. Create or modify JSON files in the lessons/ directory
  2. Ensure they validate against the schema
  3. Test thoroughly with various validation scenarios
  4. Update documentation if needed

📄 License

This project is released into the public domain under the Unlicense. You are free to copy, modify, publish, use, compile, sell, or distribute this software for any purpose.