| <!DOCTYPE html> |
| <html lang="en"> |
|
|
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Fertilizer Recommender & Usage Requirement Estimator</title> |
| <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet"> |
| <script src="https://cdn.plot.ly/plotly-latest.min.js"></script> |
| <link rel="preconnect" href="https://fonts.googleapis.com"> |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> |
| <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap" rel="stylesheet"> |
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css"> |
| |
| <style> |
| :root { |
| --color-primary: #1a5d3a; |
| --color-primary-light: #2d7a52; |
| --color-primary-dark: #143d2e; |
| --color-accent: #198754; |
| --color-accent-light: #28a745; |
| --bg-light: #eaf6ee; |
| --bg-gradient-start: #f0fdf4; |
| --bg-gradient-end: #dcfce7; |
| --surface: #ffffff; |
| --text: #1f2937; |
| --text-light: #6b7280; |
| --border: #143d2e; |
| --border-light: rgba(20, 61, 46, 0.2); |
| |
| --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.04); |
| --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.08); |
| --shadow-lg: 0 10px 40px rgba(0, 0, 0, 0.12); |
| --shadow-xl: 0 20px 60px rgba(0, 0, 0, 0.15); |
| |
| --radius-sm: 8px; |
| --radius-md: 12px; |
| --radius-lg: 20px; |
| --radius-xl: 24px; |
| |
| --space-xs: 0.5rem; |
| --space-sm: 1rem; |
| --space-md: 1.5rem; |
| --space-lg: 2rem; |
| --space-xl: 3rem; |
| --space-2xl: 4rem; |
| } |
| * { |
| box-sizing: border-box; |
| margin: 0; |
| padding: 0; |
| } |
| body { |
| background: linear-gradient(135deg, var(--bg-gradient-start) 0%, var(--bg-gradient-end) 100%); |
| font-family: 'Outfit', sans-serif; |
| color: var(--text); |
| min-height: 100vh; |
| line-height: 1.6; |
| } |
| .main-container { |
| max-width: 1400px; |
| margin: 0 auto; |
| padding: 0 var(--space-md); |
| } |
| .heading { |
| background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-light) 100%); |
| color: white; |
| padding: var(--space-2xl) var(--space-md); |
| text-align: center; |
| position: relative; |
| overflow: hidden; |
| margin: 0 0 var(--space-xl) 0; |
| border-radius: 0 0 var(--radius-xl) var(--radius-xl); |
| } |
| .heading::before { |
| content: ''; |
| position: absolute; |
| top: 0; |
| left: 0; |
| right: 0; |
| bottom: 0; |
| background: |
| radial-gradient(circle at 20% 50%, rgba(255,255,255,0.1) 0%, transparent 50%), |
| radial-gradient(circle at 80% 80%, rgba(255,255,255,0.08) 0%, transparent 50%); |
| pointer-events: none; |
| } |
| .heading i { |
| font-size: 3rem; |
| margin-bottom: var(--space-sm); |
| display: block; |
| opacity: 0.9; |
| } |
| .heading h1 { |
| font-size: 2.5rem; |
| font-weight: 700; |
| letter-spacing: -0.5px; |
| position: relative; |
| z-index: 1; |
| text-shadow: 0 2px 10px rgba(0,0,0,0.1); |
| margin: 0; |
| } |
| .heading p { |
| font-size: 1.1rem; |
| margin-top: var(--space-sm); |
| opacity: 0.95; |
| font-weight: 300; |
| } |
| .input-container { |
| background: var(--bg-light); |
| border-radius: 20px; |
| padding: var(--space-2xl); |
| box-shadow: var(--shadow-xl); |
| margin-bottom: var(--space-xl); |
| position: relative; |
| z-index: 10; |
| border: 2px solid var(--border); |
| transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); |
| } |
| .input-container:hover { |
| transform: translateY(-4px); |
| box-shadow: 0 25px 70px rgba(0, 0, 0, 0.18); |
| } |
| .input-container::before { |
| content: ''; |
| position: absolute; |
| top: 0; |
| left: 0; |
| right: 0; |
| height: 4px; |
| background: linear-gradient(90deg, var(--color-primary) 0%, var(--color-accent) 100%); |
| border-radius: var(--radius-xl) var(--radius-xl) 0 0; |
| } |
| .form-group { |
| margin-bottom: var(--space-md); |
| } |
| .form-group label { |
| display: flex; |
| align-items: center; |
| gap: var(--space-xs); |
| font-weight: 600; |
| color: var(--text); |
| margin-bottom: var(--space-xs); |
| font-size: 0.95rem; |
| } |
| .form-group label i { |
| font-size: 1.1rem; |
| color: var(--color-accent); |
| } |
| .form-control { |
| background: var(--bg-light); |
| border: 2px solid transparent; |
| border-radius: var(--radius-md); |
| font-family: 'Outfit', sans-serif; |
| font-size: 1rem; |
| color: var(--text); |
| width: 100%; |
| transition: all 0.3s ease; |
| box-shadow: var(--shadow-sm); |
| } |
| .form-control:hover { |
| border-color: var(--border-light); |
| } |
| .form-control:focus { |
| background: var(--surface); |
| outline: none; |
| border-color: var(--color-accent); |
| box-shadow: 0 0 0 4px rgba(25, 135, 84, 0.1), var(--shadow-md); |
| transform: translateY(-1px); |
| } |
| .predict-btn { |
| background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-accent) 100%); |
| color: white; |
| border: none; |
| border-radius: var(--radius-md); |
| padding: 1rem 2rem; |
| font-family: 'Outfit', sans-serif; |
| font-weight: 600; |
| font-size: 1.1rem; |
| cursor: pointer; |
| width: 100%; |
| margin-top: var(--space-md); |
| position: relative; |
| overflow: hidden; |
| transition: all 0.3s ease; |
| box-shadow: 0 4px 15px rgba(26, 93, 58, 0.3); |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| gap: 10px; |
| } |
| .predict-btn:hover { |
| transform: translateY(-2px); |
| box-shadow: 0 6px 25px rgba(26, 93, 58, 0.4); |
| } |
| |
| |
| #loader-overlay { |
| position: fixed; |
| top: 0; |
| left: 0; |
| width: 100%; |
| height: 100%; |
| background: rgba(255, 255, 255, 0.85); |
| backdrop-filter: blur(8px); |
| display: none; |
| justify-content: center; |
| align-items: center; |
| flex-direction: column; |
| z-index: 9999; |
| } |
| .loader-spinner { |
| width: 80px; |
| height: 80px; |
| border: 6px solid var(--bg-light); |
| border-top: 6px solid var(--color-primary); |
| border-radius: 50%; |
| animation: spin 1s linear infinite; |
| margin-bottom: 20px; |
| box-shadow: var(--shadow-md); |
| } |
| .loader-text { |
| font-weight: 600; |
| color: var(--color-primary); |
| font-size: 1.2rem; |
| letter-spacing: 1px; |
| animation: pulse 1.5s ease-in-out infinite; |
| } |
| @keyframes spin { |
| 0% { transform: rotate(0deg); } |
| 100% { transform: rotate(360deg); } |
| } |
| @keyframes pulse { |
| 0%, 100% { opacity: 1; transform: scale(1); } |
| 50% { opacity: 0.6; transform: scale(1.05); } |
| } |
| |
| |
| .result-container { |
| display: grid; |
| grid-template-columns: 1fr 1fr; |
| gap: var(--space-xl); |
| margin-top: var(--space-xl); |
| margin-bottom: var(--space-2xl); |
| animation: fadeInUp 0.6s ease-out; |
| } |
| @media (max-width: 968px) { |
| .result-container { |
| grid-template-columns: 1fr; |
| } |
| } |
| .left-container, |
| .right-container { |
| background: var(--surface); |
| border: 1px solid var(--border-light); |
| border-radius: var(--radius-lg); |
| padding: var(--space-xl); |
| box-shadow: var(--shadow-lg); |
| transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); |
| position: relative; |
| overflow: hidden; |
| } |
| .left-container::before, |
| .right-container::before { |
| content: ''; |
| position: absolute; |
| top: 0; |
| left: 0; |
| right: 0; |
| height: 3px; |
| background: linear-gradient(90deg, var(--color-primary) 0%, var(--color-accent) 100%); |
| } |
| .fertilizer-name { |
| background: linear-gradient(135deg, rgba(26, 93, 58, 0.08) 0%, rgba(25, 135, 84, 0.08) 100%); |
| color: var(--color-primary); |
| font-weight: 700; |
| font-size: 2rem; |
| text-align: center; |
| padding: var(--space-md); |
| border-radius: var(--radius-md); |
| border-left: 5px solid var(--color-accent); |
| margin: var(--space-md) 0; |
| box-shadow: var(--shadow-sm); |
| } |
| .fertilizer-info { |
| background: var(--bg-light); |
| padding: var(--space-lg); |
| border-radius: var(--radius-md); |
| border: 1px solid var(--border-light); |
| margin-top: var(--space-md); |
| line-height: 1.8; |
| color: var(--text); |
| font-size: 1.05rem; |
| } |
| .section-heading { |
| color: var(--color-primary); |
| font-weight: 600; |
| text-align: center; |
| margin-bottom: var(--space-lg); |
| font-size: 1.5rem; |
| } |
| .form-row { |
| display: grid; |
| grid-template-columns: 1fr 1fr; |
| gap: var(--space-md); |
| margin-bottom: 0; |
| } |
| @media (max-width: 768px) { |
| .form-row { |
| grid-template-columns: 1fr; |
| } |
| } |
| @keyframes fadeInUp { |
| from { opacity: 0; transform: translateY(30px); } |
| to { opacity: 1; transform: translateY(0); } |
| } |
| </style> |
| </head> |
|
|
| <body> |
| |
| <div id="loader-overlay"> |
| <div class="loader-spinner"></div> |
| <div class="loader-text">Analyzing Soil Conditions...</div> |
| </div> |
|
|
| <div class="heading"> |
| <i class="bi bi-flower2"></i> |
| <h1>Fertilizer Recommender & Usage Requirement Estimator</h1> |
| <p>Get intelligent fertilizer recommendations based on your soil and crop conditions</p> |
| </div> |
|
|
| <div class="main-container"> |
| |
| <form method="post" id="predictionForm" class="input-container"> |
| <div class="form-row"> |
| <div class="form-group"> |
| <label for="temperature"><i class="bi bi-thermometer-half"></i> Temperature (°C)</label> |
| <input type="number" class="form-control" id="temperature" name="temperature" placeholder="Enter temperature" step="0.1" required> |
| </div> |
| <div class="form-group"> |
| <label for="humidity"><i class="bi bi-droplet-half"></i> Humidity (%)</label> |
| <input type="number" class="form-control" id="humidity" name="humidity" placeholder="Enter humidity" step="0.1" min="0" max="100" required> |
| </div> |
| </div> |
| |
| <div class="form-row"> |
| <div class="form-group"> |
| <label for="moisture"><i class="bi bi-moisture"></i> Soil Moisture (%)</label> |
| <input type="number" class="form-control" id="moisture" name="moisture" placeholder="Enter soil moisture" step="0.1" min="0" max="100" required> |
| </div> |
| <div class="form-group"> |
| <label for="soil_type"><i class="bi bi-layers-fill"></i> Soil Type</label> |
| <select class="form-control" id="soil_type" name="soil_type" required> |
| <option value="" disabled selected>Select soil type</option> |
| <option value="Black">Black</option> |
| <option value="Sandy">Sandy</option> |
| <option value="Loamy">Loamy</option> |
| <option value="Clayey">Clayey</option> |
| <option value="Red">Red</option> |
| </select> |
| </div> |
| </div> |
| |
| <div class="form-row"> |
| <div class="form-group"> |
| <label for="crop_type"><i class="bi bi-flower3"></i> Crop Type</label> |
| <select class="form-control" id="crop_type" name="crop_type" required> |
| <option value="" disabled selected>Select crop type</option> |
| <option value="Barley">Barley</option> |
| <option value="Coffee">Coffee</option> |
| <option value="Cotton">Cotton</option> |
| <option value="Ground Nuts">Ground Nuts</option> |
| <option value="Maize">Maize</option> |
| <option value="Millets">Millets</option> |
| <option value="Oil seeds">Oil seeds</option> |
| <option value="Paddy">Paddy</option> |
| <option value="Pulses">Pulses</option> |
| <option value="Rice">Rice</option> |
| <option value="Sugarcane">Sugarcane</option> |
| <option value="Tobacco">Tobacco</option> |
| <option value="Wheat">Wheat</option> |
| <option value="Other Variety">Other Variety</option> |
| </select> |
| </div> |
| <div class="form-group"> |
| <label for="nitrogen"><i class="bi bi-circle-fill" style="color: #4169E1;"></i> Nitrogen (N)</label> |
| <input type="number" class="form-control" id="nitrogen" name="nitrogen" placeholder="Enter nitrogen level" step="0.1" min="0" required> |
| </div> |
| </div> |
| |
| <div class="form-row"> |
| <div class="form-group"> |
| <label for="potassium"><i class="bi bi-circle-fill" style="color: #FF6347;"></i> Potassium (K)</label> |
| <input type="number" class="form-control" id="potassium" name="potassium" placeholder="Enter potassium level" step="0.1" min="0" required> |
| </div> |
| <div class="form-group"> |
| <label for="phosphorous"><i class="bi bi-circle-fill" style="color: #FFD700;"></i> Phosphorous (P)</label> |
| <input type="number" class="form-control" id="phosphorous" name="phosphorous" placeholder="Enter phosphorous level" step="0.1" min="0" required> |
| </div> |
| </div> |
| |
| <button type="submit" class="predict-btn"> |
| <i class="bi bi-search"></i> Recommend Fertilizer |
| </button> |
| </form> |
|
|
| {% if prediction %} |
| <div class="result-container"> |
| <div class="left-container"> |
| <h3 class="section-heading">Recommended Fertilizer</h3> |
| <div class="fertilizer-name">{{ fertilizer_name }}</div> |
| {% if pred_info %} |
| <div class="fertilizer-info">{{ pred_info|safe }}</div> |
| {% endif %} |
| </div> |
| |
| <div class="right-container"> |
| <h3 class="section-heading">Optimal Fertilizer Usage (kg/Acres)</h3> |
| <div class="gauge-container" style="display: flex; justify-content: center;"> |
| <div id="gauge"></div> |
| </div> |
| <script> |
| var optimalUsage = {{ optimal_usage }}; |
| var gaugeData = [{ |
| type: 'indicator', |
| mode: 'gauge+number', |
| value: optimalUsage, |
| gauge: { |
| axis: { range: [0, 100], tickwidth: 2, tickcolor: "#1a5d3a" }, |
| bar: { color: "#198754" }, |
| bgcolor: "white", |
| borderwidth: 2, |
| steps: [ |
| { range: [0, 33], color: "#e8f5e9" }, |
| { range: [33, 66], color: "#a5d6a7" }, |
| { range: [66, 100], color: "#66bb6a" } |
| ] |
| } |
| }]; |
| var layout = { |
| width: 350, height: 250, |
| margin: { t: 25, b: 25, l: 25, r: 25 }, |
| paper_bgcolor: 'rgba(0,0,0,0)', |
| font: { family: 'Outfit, sans-serif', color: '#1f2937' } |
| }; |
| Plotly.newPlot('gauge', gaugeData, layout, {responsive: true, displayModeBar: false}); |
| </script> |
| </div> |
| </div> |
| {% endif %} |
| </div> |
|
|
| |
| <script> |
| document.getElementById('predictionForm').addEventListener('submit', function() { |
| |
| document.getElementById('loader-overlay').style.display = 'flex'; |
| |
| |
| const btn = this.querySelector('.predict-btn'); |
| btn.disabled = true; |
| btn.innerHTML = '<i class="bi bi-hourglass-split"></i> Processing...'; |
| }); |
| </script> |
| </body> |
|
|
| </html> |