Upload files to "/"
This commit is contained in:
commit
76eb07896c
41
README.md
Normal file
41
README.md
Normal file
@ -0,0 +1,41 @@
|
||||
# AOU GPA Calculator
|
||||
|
||||
Visit the site here: [AOU GPA Calculator](https://aougpa.netlify.app/)
|
||||
|
||||
## Overview
|
||||
|
||||
The AOU GPA Calculator is a web-based tool designed to assist students at the Arab Open University (AOU) in calculating their Grade Point Average (GPA) based on the university's grading system. This calculator provides a user-friendly interface for students to input their grades and study hours, offering a quick and accurate assessment of their academic performance.
|
||||
|
||||
|
||||
![لقطة شاشة 2024-10-24 040541](https://github.com/user-attachments/assets/1a5d73ac-6167-4503-a07f-ed8d0f0286f9)
|
||||
## Features
|
||||
|
||||
- **Dynamic Subject Input**:
|
||||
Easily add subjects with individual grade and study hour inputs. Remove specific subjects to tailor your GPA calculation.
|
||||
|
||||
- **Intuitive User Interface**:
|
||||
Clear and straightforward design for efficient use. Responsive layout for a seamless experience on various devices.
|
||||
|
||||
- **AOU Grading System**:
|
||||
Follows the AOU grading system, providing accurate GPA calculations. Corresponding grades include A, B+, B, C+, C, D, and F.
|
||||
|
||||
## How to Use
|
||||
|
||||
1. **Add Subjects**: Click the "Add Subject" button to input your grades and study hours for each subject.
|
||||
|
||||
2. **Calculate GPA**: Use the "Calculate GPA" button to obtain your GPA based on the entered subjects.
|
||||
|
||||
3. **Remove Subjects**: Click the "Remove All" button to clear all subjects and start fresh.
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! If you have ideas for improvements, bug fixes, or additional features, feel free to open an issue or submit a pull request.
|
||||
|
||||
## Author
|
||||
|
||||
This GPA Calculator was created by **Mohammed Nuseirat**. Connect with me on [LinkedIn](https://www.linkedin.com/in/mohammednuseirat/) and [X](https://x.com/MohaNuseirat).
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
||||
|
35
Update2.0.md
Normal file
35
Update2.0.md
Normal file
@ -0,0 +1,35 @@
|
||||
## Update 2.0 - AOU GPA Calculator
|
||||
|
||||
### Overview
|
||||
In this update, I have introduced several new features and enhancements to improve the user experience of the AOU GPA Calculator.
|
||||
The primary goal of this release is to provide users with a more intuitive interface and streamline the process of calculating GPA.
|
||||
|
||||
|
||||
## New
|
||||
![لقطة شاشة 2024-10-24 040541](https://github.com/user-attachments/assets/1a5d73ac-6167-4503-a07f-ed8d0f0286f9)
|
||||
|
||||
## Old
|
||||
![لقطة شاشة 2024-10-23 215500](https://github.com/user-attachments/assets/3a695d15-9d73-4d18-b15b-aae9b42d4891)
|
||||
|
||||
### New Features
|
||||
- **Dynamic Subject Input**: Users can now add multiple subjects dynamically, allowing for a more personalized and flexible GPA calculation experience. Each subject can be easily added and removed as needed.
|
||||
|
||||
- **Enhanced Button Functionality**:
|
||||
- **Calculate GPA**: A dedicated button for calculating GPA has been implemented, making it easier for users to perform calculations with a single click.
|
||||
- **Remove All Subjects**: Users can now clear all subject inputs with a single button click, providing a quick way to reset the form.
|
||||
|
||||
- **Improved User Interface**:
|
||||
- The overall design has been refined with better spacing, layout adjustments, and a more modern aesthetic.
|
||||
- The input fields have been styled for improved accessibility and usability, including focused states for better user feedback.
|
||||
|
||||
- **Responsive Design**: The application has been optimized for mobile devices, ensuring a seamless experience across various screen sizes.
|
||||
|
||||
### Visual Updates
|
||||
- The logo and overall color scheme have been updated to enhance visual appeal and align with modern design trends.
|
||||
- Buttons have been styled with hover effects to provide interactive feedback.
|
||||
|
||||
### Author
|
||||
This update was developed by **Mohammed Nuseirat**.
|
||||
|
||||
### Future Plans
|
||||
I am committed to continuously improving the AOU GPA Calculator. In future updates, I plan to explore additional features such as GPA history tracking, a dark mode option, and more detailed grading scales.
|
121
index.html
Normal file
121
index.html
Normal file
@ -0,0 +1,121 @@
|
||||
<!-- Created by Mohammed Nuseirat -->
|
||||
<!DOCTYPE html>
|
||||
<!-- Setting language to English -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- Character encoding for Unicode support -->
|
||||
<meta charset="UTF-8">
|
||||
<!-- Responsive viewport settings for mobile devices -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<!-- Page title showing app name and institution -->
|
||||
<title>GPA Calculator | AOU</title>
|
||||
<!-- Link to custom CSS stylesheet -->
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<!-- Font Awesome icons library -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<!-- Main container wrapper -->
|
||||
<main class="container">
|
||||
<!-- Logo section with glass effect -->
|
||||
<div class="logo-container glass-effect">
|
||||
<!-- University logo image -->
|
||||
<img src="https://www.arabou.edu.sa/assets/common/images/logo-footer-ar.png" alt="AOU Logo" class="logo">
|
||||
</div>
|
||||
|
||||
<!-- Main calculator container with glass effect -->
|
||||
<div class="calculator-container glass-effect">
|
||||
<!-- Arabic title for GPA calculator -->
|
||||
<h1>حساب المعدل التراكمي للجامعة العربية المفتوحة</h1>
|
||||
|
||||
<!-- Previous GPA input section -->
|
||||
<div class="previous-gpa-section">
|
||||
<div class="input-group">
|
||||
<!-- Previous GPA input field -->
|
||||
<div class="input-wrapper">
|
||||
<label for="prev-gpa"></label>
|
||||
<input type="number"
|
||||
id="prev-gpa"
|
||||
step="0.01"
|
||||
min="0"
|
||||
max="4"
|
||||
placeholder="Enter previous GPA / المعدل السابق">
|
||||
</div>
|
||||
<!-- Previous hours input field -->
|
||||
<div class="input-wrapper">
|
||||
<label for="prev-hours"></label>
|
||||
<input type="number"
|
||||
id="prev-hours"
|
||||
min="0"
|
||||
placeholder="Enter previous hours / الساعات السابقة">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Container for dynamically added subjects -->
|
||||
<div id="subjects-container" class="subjects-container">
|
||||
<!-- Subjects will be added here dynamically via JavaScript -->
|
||||
</div>
|
||||
|
||||
<!-- Action buttons group -->
|
||||
<div class="button-group">
|
||||
<!-- Add subject button -->
|
||||
<button class="btn btn-primary" onclick="addSubject()">
|
||||
<i class="fas fa-plus"></i>
|
||||
Add Subject
|
||||
</button>
|
||||
<!-- Calculate GPA button -->
|
||||
<button class="btn btn-success" onclick="calculateGPA()">
|
||||
<i class="fas fa-calculator"></i>
|
||||
Calculate
|
||||
</button>
|
||||
<!-- Clear all inputs button -->
|
||||
<button class="btn btn-danger" onclick="clearAll()">
|
||||
<i class="fas fa-trash"></i>
|
||||
Clear All
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Results container (hidden by default) -->
|
||||
<div id="result" class="result glass-effect hidden">
|
||||
<!-- Results will be displayed here via JavaScript -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer section -->
|
||||
<footer class="footer glass-effect">
|
||||
<div class="footer-content">
|
||||
<!-- Developer credit -->
|
||||
<p class="footer-text">Developed by Mohammed Nuseirat
|
||||
<br>• v2.0</p>
|
||||
<!-- Social media links -->
|
||||
<div class="social-links">
|
||||
<!-- GitHub profile link -->
|
||||
<a href="https://github.com/nuseirat" target="_blank" class="social-link">
|
||||
<i class="fab fa-github fa-2x"></i>
|
||||
</a>
|
||||
<!-- LinkedIn profile link -->
|
||||
<a href="https://linkedin.com/in/mohammednuseirat" target="_blank" class="social-link">
|
||||
<i class="fab fa-linkedin fa-2x"></i>
|
||||
</a>
|
||||
<!-- Twitter/X profile link -->
|
||||
<a href="https://x.com/mohanuseirat" target="_blank" class="social-link">
|
||||
<i class="fa-brands fa-x-twitter fa-2x"></i>
|
||||
<!-- Website link -->
|
||||
<a href="https://nuseirat.github.io/" target="_blank" class="social-link">
|
||||
<i class="fas fa-globe fa-2x"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</main>
|
||||
|
||||
<!-- JavaScript libraries and scripts -->
|
||||
<!-- GSAP animation library -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
|
||||
<!-- Custom JavaScript file -->
|
||||
<script src="script.js"></script>
|
||||
<!-- Font Awesome kit -->
|
||||
<script src="https://kit.fontawesome.com/86e812f22e.js" crossorigin="anonymous"></script>
|
||||
</body>
|
||||
</html>
|
262
script.js
Normal file
262
script.js
Normal file
@ -0,0 +1,262 @@
|
||||
// Created by Mohammed Nuseirat
|
||||
|
||||
// script.js
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
// Array to store all subject input elements
|
||||
const subjects = [];
|
||||
|
||||
// Add Subject Button Handler
|
||||
window.addSubject = function() {
|
||||
// Create container for new subject inputs
|
||||
const subjectInput = document.createElement("div");
|
||||
subjectInput.className = "subject";
|
||||
|
||||
// Create grade input field
|
||||
const gradeInput = document.createElement("input");
|
||||
gradeInput.type = "text";
|
||||
gradeInput.placeholder = "Enter grade (A, B+, B, C+, C, D, F)";
|
||||
gradeInput.className = "grade-input";
|
||||
|
||||
// Create credit hours input field
|
||||
const hoursInput = document.createElement("input");
|
||||
hoursInput.type = "number";
|
||||
hoursInput.placeholder = "Enter hours";
|
||||
hoursInput.className = "hours-input";
|
||||
hoursInput.min = "1";
|
||||
|
||||
// Create remove button with icon
|
||||
const removeButton = document.createElement("button");
|
||||
removeButton.innerHTML = '<i class="fas fa-times"></i>';
|
||||
removeButton.className = "remove-button";
|
||||
|
||||
// Add animation and removal functionality to remove button
|
||||
removeButton.addEventListener("click", function () {
|
||||
gsap.to(subjectInput, {
|
||||
duration: 0.3,
|
||||
opacity: 0,
|
||||
y: -20,
|
||||
ease: 'power2.in',
|
||||
onComplete: () => {
|
||||
subjectInput.remove();
|
||||
updateSubjectsArray();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Assemble the subject input container
|
||||
subjectInput.appendChild(gradeInput);
|
||||
subjectInput.appendChild(hoursInput);
|
||||
subjectInput.appendChild(removeButton);
|
||||
|
||||
// Add to DOM and subjects array
|
||||
document.getElementById("subjects-container").appendChild(subjectInput);
|
||||
subjects.push(subjectInput);
|
||||
|
||||
// Animate new subject entry
|
||||
gsap.from(subjectInput, {
|
||||
duration: 0.5,
|
||||
opacity: 0,
|
||||
y: 20,
|
||||
ease: 'power2.out'
|
||||
});
|
||||
|
||||
// Validate grade input
|
||||
gradeInput.addEventListener('input', function() {
|
||||
this.value = this.value.toUpperCase();
|
||||
const validGrades = ['A', 'B+', 'B', 'C+', 'C', 'D', 'F'];
|
||||
if (!validGrades.includes(this.value) && this.value !== '') {
|
||||
this.classList.add('invalid');
|
||||
} else {
|
||||
this.classList.remove('invalid');
|
||||
}
|
||||
});
|
||||
|
||||
// Validate hours input
|
||||
hoursInput.addEventListener('input', function() {
|
||||
if (this.value < 1) {
|
||||
this.classList.add('invalid');
|
||||
} else {
|
||||
this.classList.remove('invalid');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Clear All Button Handler
|
||||
window.clearAll = function() {
|
||||
const subjectInputs = document.querySelectorAll(".subject");
|
||||
|
||||
// Animate removal of all subjects
|
||||
gsap.to(subjectInputs, {
|
||||
duration: 0.3,
|
||||
opacity: 0,
|
||||
y: -20,
|
||||
stagger: 0.1,
|
||||
ease: 'power2.in',
|
||||
onComplete: () => {
|
||||
// Clear all inputs and results
|
||||
document.getElementById("subjects-container").innerHTML = '';
|
||||
subjects.length = 0;
|
||||
document.getElementById("prev-gpa").value = "";
|
||||
document.getElementById("prev-hours").value = "";
|
||||
document.getElementById("result").innerHTML = "";
|
||||
document.getElementById("result").classList.add("hidden");
|
||||
}
|
||||
});
|
||||
|
||||
// Animate calculator container
|
||||
gsap.to('.calculator-container', {
|
||||
duration: 0.2,
|
||||
scale: 0.98,
|
||||
ease: 'power2.in',
|
||||
yoyo: true,
|
||||
repeat: 1
|
||||
});
|
||||
};
|
||||
|
||||
// Calculate GPA Button Handler
|
||||
window.calculateGPA = function() {
|
||||
// Validate all inputs before calculation
|
||||
const invalidInputs = document.querySelectorAll('.invalid');
|
||||
if (invalidInputs.length > 0) {
|
||||
showResult("Please correct invalid inputs before calculating", "error");
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate totals
|
||||
const totalGradePoints = calculateTotalGradePoints();
|
||||
const totalHours = calculateTotalHours();
|
||||
|
||||
// Get previous GPA data
|
||||
const prevGPA = parseFloat(document.getElementById("prev-gpa").value) || 0;
|
||||
const prevHours = parseFloat(document.getElementById("prev-hours").value) || 0;
|
||||
|
||||
// Validate previous GPA
|
||||
if (prevGPA > 4) {
|
||||
showResult("Previous GPA cannot be greater than 4.0", "error");
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate cumulative statistics
|
||||
const cumulativeGradePoints = totalGradePoints + (prevGPA * prevHours);
|
||||
const cumulativeTotalHours = totalHours + prevHours;
|
||||
|
||||
// Validate hours
|
||||
if (totalHours === 0 && prevHours === 0) {
|
||||
showResult("Please enter valid grades and hours", "error");
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate GPAs
|
||||
const currentGPA = totalHours === 0 ? 0 : totalGradePoints / totalHours;
|
||||
const cumulativeGPA = cumulativeTotalHours === 0 ? 0 : cumulativeGradePoints / cumulativeTotalHours;
|
||||
|
||||
// Format and display results
|
||||
const resultHTML = `
|
||||
<div class="result-content">
|
||||
<div class="result-item">
|
||||
<span class="result-label">Semester Hours:</span>
|
||||
<span class="result-value">${totalHours}</span>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<span class="result-label">Total Hours:</span>
|
||||
<span class="result-value">${cumulativeTotalHours}</span>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<span class="result-label">Semester GPA:</span>
|
||||
<span class="result-value">${currentGPA.toFixed(2)}</span>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<span class="result-label">Cumulative GPA:</span>
|
||||
<span class="result-value">${cumulativeGPA.toFixed(2)}</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
showResult(resultHTML);
|
||||
|
||||
// Animate result items
|
||||
gsap.from('.result-item', {
|
||||
duration: 0.5,
|
||||
opacity: 0,
|
||||
y: 20,
|
||||
stagger: 0.1,
|
||||
ease: 'power2.out'
|
||||
});
|
||||
};
|
||||
|
||||
// Helper function to calculate total grade points
|
||||
function calculateTotalGradePoints() {
|
||||
let totalGradePoints = 0;
|
||||
|
||||
subjects.forEach(subject => {
|
||||
const grade = subject.querySelector(".grade-input").value;
|
||||
const hours = parseFloat(subject.querySelector(".hours-input").value) || 0;
|
||||
|
||||
const gradePoint = getGradePoint(grade);
|
||||
totalGradePoints += (gradePoint * hours);
|
||||
});
|
||||
|
||||
return totalGradePoints;
|
||||
}
|
||||
|
||||
// Helper function to calculate total hours
|
||||
function calculateTotalHours() {
|
||||
let totalHours = 0;
|
||||
|
||||
subjects.forEach(subject => {
|
||||
const hours = parseFloat(subject.querySelector(".hours-input").value) || 0;
|
||||
totalHours += hours;
|
||||
});
|
||||
|
||||
return totalHours;
|
||||
}
|
||||
|
||||
// Convert letter grades to grade points
|
||||
function getGradePoint(grade) {
|
||||
const gradePoints = {
|
||||
'A': 4,
|
||||
'B+': 3.5,
|
||||
'B': 3,
|
||||
'C+': 2.5,
|
||||
'C': 2,
|
||||
'D': 1.5,
|
||||
'F': 0
|
||||
};
|
||||
return gradePoints[grade.toUpperCase()] || 0;
|
||||
}
|
||||
|
||||
// Display result with animation
|
||||
function showResult(message, type = "success") {
|
||||
const resultDiv = document.getElementById("result");
|
||||
resultDiv.innerHTML = message;
|
||||
resultDiv.classList.remove("hidden");
|
||||
resultDiv.style.opacity = "0";
|
||||
|
||||
// Animate result appearance
|
||||
gsap.to(resultDiv, {
|
||||
duration: 0.5,
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
ease: 'power2.out'
|
||||
});
|
||||
|
||||
// Scroll result into view
|
||||
resultDiv.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||||
}
|
||||
|
||||
// Update subjects array after removal
|
||||
function updateSubjectsArray() {
|
||||
subjects.length = 0;
|
||||
document.querySelectorAll(".subject").forEach(subject => subjects.push(subject));
|
||||
}
|
||||
|
||||
// Validate previous GPA input
|
||||
const prevGPAInput = document.getElementById("prev-gpa");
|
||||
prevGPAInput.addEventListener('input', function() {
|
||||
if (this.value > 4) {
|
||||
this.classList.add('invalid');
|
||||
} else {
|
||||
this.classList.remove('invalid');
|
||||
}
|
||||
});
|
||||
});
|
361
style.css
Normal file
361
style.css
Normal file
@ -0,0 +1,361 @@
|
||||
/* Created by Mohammed Nuseirat*/
|
||||
|
||||
/* Define CSS custom properties (variables) for consistent theming across the application */
|
||||
:root {
|
||||
--primary-bg: linear-gradient(135deg, #020617, #1e293b); /* Dark gradient background */
|
||||
--glass-bg: rgba(30, 41, 59, 0.7); /* Semi-transparent background for glass effect */
|
||||
--text-color: #e2e8f0; /* Light text color for dark theme */
|
||||
--input-bg: rgba(30, 41, 59, 0.8); /* Slightly darker background for input fields */
|
||||
--btn-primary: #1e3a8a; /* Deep blue for primary buttons */
|
||||
--btn-success: #059669; /* Green for success buttons */
|
||||
--btn-danger: #991b1b; /* Red for danger/delete buttons */
|
||||
--shadow: 0 8px 32px rgba(0, 0, 0, 0.3); /* Subtle shadow for depth */
|
||||
--border: rgba(255, 255, 255, 0.1); /* Light border for glass effect */
|
||||
--invalid-color: #ef4444; /* Red for validation errors */
|
||||
--success-color: #10b981; /* Green for success states */
|
||||
--warning-color: #f59e0b; /* Orange for warnings */
|
||||
}
|
||||
|
||||
/* Reset default browser styles */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Base body styles with flexbox centering */
|
||||
body {
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
min-height: 100vh;
|
||||
background: var(--primary-bg);
|
||||
color: var(--text-color);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
/* Reusable glass morphism effect */
|
||||
.glass-effect {
|
||||
background: var(--glass-bg);
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 1.5rem;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
/* Main container layout */
|
||||
.container {
|
||||
width: 100%;
|
||||
max-width: 900px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
/* Logo section styling */
|
||||
.logo-container {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
/* Logo image styling with smooth transition */
|
||||
.logo {
|
||||
height: 100px;
|
||||
width: auto;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
/* Calculator section container */
|
||||
.calculator-container {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
/* Main heading styles */
|
||||
h1 {
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
font-size: 2.5rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* Grid layout for input fields */
|
||||
.input-group {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
/* Individual input field container */
|
||||
.input-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
/* Input field styling */
|
||||
input {
|
||||
width: 100%;
|
||||
padding: 1rem;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 0.75rem;
|
||||
background: var(--input-bg);
|
||||
color: var(--text-color);
|
||||
font-size: 1rem;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
/* Input focus state */
|
||||
input:focus {
|
||||
outline: none;
|
||||
border-color: var(--btn-primary);
|
||||
box-shadow: 0 0 0 2px rgba(30, 58, 138, 0.3);
|
||||
}
|
||||
|
||||
/* Input label styling */
|
||||
.input-label {
|
||||
font-size: 0.875rem;
|
||||
color: var(--text-color);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* Container for subject entries */
|
||||
.subjects-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
/* Individual subject entry styling */
|
||||
.subject {
|
||||
display: grid;
|
||||
grid-template-columns: 1.5fr 1fr auto;
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
background: var(--glass-bg);
|
||||
border-radius: 0.75rem;
|
||||
animation: slideIn 0.3s ease forwards;
|
||||
}
|
||||
|
||||
/* Button group layout */
|
||||
.button-group {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
/* Base button styles */
|
||||
.btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.75rem;
|
||||
padding: 1rem;
|
||||
border: none;
|
||||
border-radius: 0.75rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Icon sizing within buttons */
|
||||
.btn i {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
/* Button variants */
|
||||
.btn-primary { background: var(--btn-primary); }
|
||||
.btn-success { background: var(--btn-success); }
|
||||
.btn-danger { background: var(--btn-danger); }
|
||||
|
||||
/* Button hover effects */
|
||||
.btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--shadow);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* Button active state */
|
||||
.btn:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* Remove button styling */
|
||||
.remove-button {
|
||||
background: var(--btn-danger);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.2rem;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
/* Remove button hover effect */
|
||||
.remove-button:hover {
|
||||
transform: scale(1.1);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* Results section container */
|
||||
.result {
|
||||
padding: 2rem;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
/* Results content layout */
|
||||
.result-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
/* Individual result item styling */
|
||||
.result-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
background: rgba(30, 41, 59, 0.5);
|
||||
border-radius: 0.75rem;
|
||||
}
|
||||
|
||||
/* Result label styling */
|
||||
.result-label {
|
||||
font-weight: 500;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* Result value styling */
|
||||
.result-value {
|
||||
font-weight: 600;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
/* Footer section styling */
|
||||
.footer-content {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* Social links container */
|
||||
.social-links {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 2rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
/* Individual social link styling */
|
||||
.social-link {
|
||||
color: var(--text-color);
|
||||
opacity: 0.8;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
/* Social link hover effect */
|
||||
.social-link:hover {
|
||||
opacity: 1;
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
|
||||
/* Invalid input state */
|
||||
.invalid {
|
||||
border-color: var(--invalid-color);
|
||||
}
|
||||
|
||||
/* Hide elements */
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Animation keyframes */
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Responsive design for mobile devices */
|
||||
@media (max-width: 768px) {
|
||||
body {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.input-group,
|
||||
.button-group {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.subject {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
.result-item {
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Loading state styles */
|
||||
.loading {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Loading overlay animation */
|
||||
.loading::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(30, 41, 59, 0.7);
|
||||
border-radius: 0.75rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
animation: pulse 1.5s infinite;
|
||||
}
|
||||
|
||||
/* Loading pulse animation */
|
||||
@keyframes pulse {
|
||||
0% { opacity: 0.7; }
|
||||
50% { opacity: 0.4; }
|
||||
100% { opacity: 0.7; }
|
||||
}
|
Loading…
Reference in New Issue
Block a user