Markdown Converter
Agent skill for markdown-converter
Create a semantic HTML5 structure for CO2 emissions calculator:
Sign in to like and favorite skills
Create a semantic HTML5 structure for CO2 emissions calculator:
HEADER:
MAIN FORM (id="calculador-form):
RESULTS SECTIONS (all hidden by default with class="hidden"):
FOOTER:
AT THE END OF BODY (in thiss order):
<script src="js/routes-data.js"></script> <script src="js/config.js"></script> <script src="js/calculator.js"></script> <script src="js/ui.js"></script> <script src="js/app.js"></script>
REQUIREMENTS:
Create a modern CSS file (css/style.css) with:
CSS CUSTOM PROPERTIES at :root level:
BASE STYLE:
UTILITY CLASSES:
HEADER:
FROM STYLING (.calculator class):
TRANSPORT MODE GRID:
CHECKBOX:
BUTTON:
Add .spinner class for loading animation:
RESPONSIVE:
Create js/routes-data.js with a global object named RoutesDB containing:
A property 'routes' as an array of route objects with structure:
Include 30-40 popular Brazilian routes:
Add these methods to RoutesDB object:
getAllCities: function() { // Return unique sorted array of all city names from routes // Extract from both origin and destination // Remove duplicates and sort alphabetically } findDistance: function(origin, destination) { // Find route distance between two cities // Search in both directions (origin-destination and destination-origin) // Normalize input: trim whitespace and convert to lowercase for comparison // Return distance in Km if found, null if not found }
The entire file should define one global variable: RouteDB
Add comments explaining the structure
Create js/config.js that defines a global CONFIG object with:
EMISSION_FACTORS object (kg CO2 per km):
TRANSPORT_MODES object with metadata:
For each mode (bicycle, car, bus, truck):
label: Portuguese name (Bicicleta, Carro, Ônibus, Caminhão)
icon: emoji (🚲, 🚗, 🚌, 🚚)
color: hex color code for UI
CARBON_CREDIT object:
Add a method to CONFIG called:
populateDatalist: function() { // Get cities list from RoutesDB.getAllCities() // Get datalist element by id 'cities-list' // Create option elements for each city // Append to datalist }
Also add:
setupDistanceAutofill: function() { // Get origin and destination input elements // get distance input and manual checkbox // Add 'change' event listeners to both origin and destination inputs // On change: // - Get trimmed values from both inputs // - If both are filled, call RoutesDB.findDistance() // - If distance found: // - Fill distance input with value // - Make it readonly // - Show success message (change helper text color to green) // - If not found: // - Clear distance input // - Change helper text to suggest manual input // Add 'change' listener to manual checkbox: // - When checked: remove readonly from distance, allow manual entry // - When unchecked: try to find route again }
Everything should be in one global CONFIG object
Create js/calculator.js with a global Calculator object containing these methods:
calculateEmission: function(distanceKm, TranspotMode) { // Get emission factor from CONFIG_EMISSION_FACTORS using transportMode as key // Calculate: distance * factor // Return result rounded to 2 decimal places } calculateAllModes: function(distanceKm) { // Create array to store results // For each transport mode in CONFIG_EMISSION_FACTORS: // - Calculate emission for that mode // - Calculate car emission as baseline // - Calculate percentage vs var: (emissao/carEmission) * 100 // - Push object to array: {mode:'car', emission: 12.5, precentageVsCar: 100} // Sort array by emission (lowest first) // Return array } calculateSavings: function(emission, baselineEmission) { // Calculate saved kg: baseline - emission // Calculate percentage: (saved/baseline) * 100 // Return object: {saveKg: 5.5, percentage: 45} // Round numbers to 2 decimals } calculateCarbonCredits: function(emissionKg) { // Divide emission by CONFIG_CARBON_CAREDIT.KG_PER_CREDIT // Return rounded to 4 decimal places } estimateCreditPrice: function(credits) { // Calculate min: credits * PRICE_MIN_BRL // Calculate max: credits * PRICE_MAX_BRL // Calculate average: (min + max) / 2 // Return object: { min: 50.5, max: 150.5, average: 100.5 } // Round to 2 decimals }
Add comments explainning each calculation
The file defines one global variable: Calculator
Create js/ui.js with a global UI object containing:
UTILITY METHODS:
formatNumber: function(number, decimals){ // Use toFixed() for decimals // Add thousand separations using regex or toLocaleString('pt-BR') // Return formatted string } formatCurrency: function(value) { // Format as R$ with pt-BR locale // Return 'R$ 1.234,56' format } showElement: function(elementId){ // Get element by ID // Remove 'hidden' class } hideElement: function(elementId){ // Get element by ID // Add 'hidden' class } scrollToElement: function(elementId){ // Get element by ID // Use scrollIntoView with smooth behavior }
RENDERING METHODS:
renderResults: function(data){ // data object contains: origin, destination, distance, emission, mode, savings // Get mode metadata from CONFIG.TRANSPORT_MODES // Create HTML, string with template literals containing: // - Route card showing origin -> destination // - Distance card showing distance in km // - Emission card showing CO2 in kg with green leaf icon // - Transport card showing mode icon amd label // - If mode is not 'car' and savings exist: savings card showing kg saved and percentage // Return complete HTML string // Use div with class="results__card" for each card // Use BEM naming for internal elements } renderComparison: function(modeArray, selectedMode) { // ModesArray from Calculator.calculateAllModes() // Create HTML string for each mode: // - Container div with class='comparison__item" // - If mode === selectedMode, add class='comparison__item--selectd' // - Header with mode icon, label, and emission stats // - If selected, add badge with "Selecionado" text // - Stats showing emission and percentage vs car // - Progress bar with width based on emission (use max emission for 100% reference) // - Color-code bar: green(0-25%), yellow (25-75%), orange(75-100%), red(> 100%) // At the end, add tip box with helpful message // Return complete HTML string } renderCarbonoCredits: function(creditsData) { // creditsData contains: {credits, price: {min, max, average}} // Create HTML with: // - Grid with 2 cards // - Card 1: Credits needed (large number), helper text "1 crédito = 1000 kg CO2" // - Card 2: Estimated price (average), range showing min-max // - info box explaining what carbon credits are // - Button "[emoji shop car] Compensar Emissões" (can be non-functional for demo) // Return complete HTML string // Use formatNumber and formatCurrency for values } showLoading: function(buttonElement) { // Save original text in data attribute: buttonElement.dataset.originalText // Disable buttom // Change InnerHTML to show spinner and "Calculando..." text // Spinner: "<span class='spinner'></span>Calculando..." } hideLoading: function(buttonElement){ // Enable button // Restore original text from data atributte }
All methods should be part of the global UI object
Use clear comments explaining the HTML structure