Merge branch 'UI-Responsiveness' into 'dev'
Ui responsiveness See merge request eb2342s/swe-b1-a!5
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Thema 1",
|
"displayName": "Geschichten erzählen",
|
||||||
"icon": "fa-divide",
|
"icon": "fa-divide",
|
||||||
"description": "Eine kurze Beschreibung des Themas",
|
"description": "Eine kurze Beschreibung des Themas",
|
||||||
"relatedTopics": [
|
"relatedTopics": [
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Thema 2",
|
"displayName": "Wortarten",
|
||||||
"icon": "fa-divide",
|
"icon": "fa-divide",
|
||||||
"description": "Eine kurze Beschreibung des Themas",
|
"description": "Eine kurze Beschreibung des Themas",
|
||||||
"relatedTopics": [
|
"relatedTopics": [
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Thema 3",
|
"displayName": "Vier Fälle",
|
||||||
"icon": "fa-divide",
|
"icon": "fa-divide",
|
||||||
"description": "Eine kurze Beschreibung des Themas",
|
"description": "Eine kurze Beschreibung des Themas",
|
||||||
"relatedTopics": [
|
"relatedTopics": [
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Thema 4",
|
"displayName": "Personalpronomen",
|
||||||
"icon": "fa-divide",
|
"icon": "fa-divide",
|
||||||
"description": "Eine kurze Beschreibung des Themas",
|
"description": "Eine kurze Beschreibung des Themas",
|
||||||
"relatedTopics": [
|
"relatedTopics": [
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Thema 5",
|
"displayName": "Personalpronomen in den vier Fällen",
|
||||||
"icon": "fa-divide",
|
"icon": "fa-divide",
|
||||||
"description": "Eine kurze Beschreibung des Themas",
|
"description": "Eine kurze Beschreibung des Themas",
|
||||||
"relatedTopics": [
|
"relatedTopics": [
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Thema 6",
|
"displayName": "Satzglieder",
|
||||||
"icon": "fa-divide",
|
"icon": "fa-divide",
|
||||||
"description": "Eine kurze Beschreibung des Themas",
|
"description": "Eine kurze Beschreibung des Themas",
|
||||||
"relatedTopics": [
|
"relatedTopics": [
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Thema 7",
|
"displayName": "Possessivpronomen",
|
||||||
"icon": "fa-divide",
|
"icon": "fa-divide",
|
||||||
"description": "Eine kurze Beschreibung des Themas",
|
"description": "Eine kurze Beschreibung des Themas",
|
||||||
"relatedTopics": [
|
"relatedTopics": [
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Thema 8",
|
"displayName": "Adverbiale Bestimmung",
|
||||||
"icon": "fa-divide",
|
"icon": "fa-divide",
|
||||||
"description": "Eine kurze Beschreibung des Themas",
|
"description": "Eine kurze Beschreibung des Themas",
|
||||||
"relatedTopics": [
|
"relatedTopics": [
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Thema 1",
|
"displayName": "Schriftliches Multiplizieren",
|
||||||
"icon": "fa-divide",
|
"icon": "fa-divide",
|
||||||
"description": "Eine kurze Beschreibung des Themas",
|
"description": "Eine kurze Beschreibung des Themas",
|
||||||
"relatedTopics": [
|
"relatedTopics": [
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Das ist der Erklärtext
|
||||||
|
<img alt="Ein Bild" src="$TOPICPATH/image.png">
|
||||||
|
<br>
|
||||||
|
When \(a \ne 0\), there are two solutions to \(ax^2 + bx + c = 0\) and they are
|
||||||
|
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
|
||||||
BIN
webseite/config/subjects/mathe/topics/topic10/exercise1.pdf
Normal file
BIN
webseite/config/subjects/mathe/topics/topic10/image.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"displayName": "Rechnen mit Zeit",
|
||||||
|
"icon": "fa-divide",
|
||||||
|
"description": "Eine kurze Beschreibung des Themas",
|
||||||
|
"relatedTopics": [
|
||||||
|
"topic2", "topic3"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"exercise1.pdf"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Das ist der Erklärtext
|
||||||
|
<img alt="Ein Bild" src="$TOPICPATH/image.png">
|
||||||
|
<br>
|
||||||
|
When \(a \ne 0\), there are two solutions to \(ax^2 + bx + c = 0\) and they are
|
||||||
|
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
|
||||||
BIN
webseite/config/subjects/mathe/topics/topic11/exercise1.pdf
Normal file
BIN
webseite/config/subjects/mathe/topics/topic11/image.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"displayName": "Punkt- vor Strichrechnung",
|
||||||
|
"icon": "fa-divide",
|
||||||
|
"description": "Eine kurze Beschreibung des Themas",
|
||||||
|
"relatedTopics": [
|
||||||
|
"topic2", "topic3"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"exercise1.pdf"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Das ist der Erklärtext
|
||||||
|
<img alt="Ein Bild" src="$TOPICPATH/image.png">
|
||||||
|
<br>
|
||||||
|
When \(a \ne 0\), there are two solutions to \(ax^2 + bx + c = 0\) and they are
|
||||||
|
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
|
||||||
BIN
webseite/config/subjects/mathe/topics/topic12/exercise1.pdf
Normal file
BIN
webseite/config/subjects/mathe/topics/topic12/image.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"displayName": "Rechnen mit Klammern",
|
||||||
|
"icon": "fa-divide",
|
||||||
|
"description": "Eine kurze Beschreibung des Themas",
|
||||||
|
"relatedTopics": [
|
||||||
|
"topic2", "topic3"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"exercise1.pdf"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Thema 2",
|
"displayName": "Schriftliches Dividieren",
|
||||||
"icon": "fa-divide",
|
"icon": "fa-divide",
|
||||||
"description": "Eine kurze Beschreibung des Themas",
|
"description": "Eine kurze Beschreibung des Themas",
|
||||||
"relatedTopics": [
|
"relatedTopics": [
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Thema 3",
|
"displayName": "Echte Brüche",
|
||||||
"icon": "fa-divide",
|
"icon": "fa-divide",
|
||||||
"description": "Eine kurze Beschreibung des Themas",
|
"description": "Eine kurze Beschreibung des Themas",
|
||||||
"relatedTopics": [
|
"relatedTopics": [
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Das ist der Erklärtext
|
||||||
|
<img alt="Ein Bild" src="$TOPICPATH/image.png">
|
||||||
|
<br>
|
||||||
|
When \(a \ne 0\), there are two solutions to \(ax^2 + bx + c = 0\) and they are
|
||||||
|
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
|
||||||
BIN
webseite/config/subjects/mathe/topics/topic4/exercise1.pdf
Normal file
BIN
webseite/config/subjects/mathe/topics/topic4/image.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
11
webseite/config/subjects/mathe/topics/topic4/properties.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"displayName": "Unechte Brüche",
|
||||||
|
"icon": "fa-divide",
|
||||||
|
"description": "Eine kurze Beschreibung des Themas",
|
||||||
|
"relatedTopics": [
|
||||||
|
"topic2", "topic3"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"exercise1.pdf"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Das ist der Erklärtext
|
||||||
|
<img alt="Ein Bild" src="$TOPICPATH/image.png">
|
||||||
|
<br>
|
||||||
|
When \(a \ne 0\), there are two solutions to \(ax^2 + bx + c = 0\) and they are
|
||||||
|
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
|
||||||
BIN
webseite/config/subjects/mathe/topics/topic5/exercise1.pdf
Normal file
BIN
webseite/config/subjects/mathe/topics/topic5/image.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
11
webseite/config/subjects/mathe/topics/topic5/properties.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"displayName": "Gemischte Zahlen",
|
||||||
|
"icon": "fa-divide",
|
||||||
|
"description": "Eine kurze Beschreibung des Themas",
|
||||||
|
"relatedTopics": [
|
||||||
|
"topic2", "topic3"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"exercise1.pdf"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Das ist der Erklärtext
|
||||||
|
<img alt="Ein Bild" src="$TOPICPATH/image.png">
|
||||||
|
<br>
|
||||||
|
When \(a \ne 0\), there are two solutions to \(ax^2 + bx + c = 0\) and they are
|
||||||
|
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
|
||||||
BIN
webseite/config/subjects/mathe/topics/topic6/exercise1.pdf
Normal file
BIN
webseite/config/subjects/mathe/topics/topic6/image.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
11
webseite/config/subjects/mathe/topics/topic6/properties.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"displayName": "Addition & Subtraktion mit Brüchen",
|
||||||
|
"icon": "fa-divide",
|
||||||
|
"description": "Eine kurze Beschreibung des Themas",
|
||||||
|
"relatedTopics": [
|
||||||
|
"topic2", "topic3"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"exercise1.pdf"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Das ist der Erklärtext
|
||||||
|
<img alt="Ein Bild" src="$TOPICPATH/image.png">
|
||||||
|
<br>
|
||||||
|
When \(a \ne 0\), there are two solutions to \(ax^2 + bx + c = 0\) and they are
|
||||||
|
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
|
||||||
BIN
webseite/config/subjects/mathe/topics/topic7/exercise1.pdf
Normal file
BIN
webseite/config/subjects/mathe/topics/topic7/image.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
11
webseite/config/subjects/mathe/topics/topic7/properties.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"displayName": "Multiplikation & Division mit Brüchen",
|
||||||
|
"icon": "fa-divide",
|
||||||
|
"description": "Eine kurze Beschreibung des Themas",
|
||||||
|
"relatedTopics": [
|
||||||
|
"topic2", "topic3"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"exercise1.pdf"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Das ist der Erklärtext
|
||||||
|
<img alt="Ein Bild" src="$TOPICPATH/image.png">
|
||||||
|
<br>
|
||||||
|
When \(a \ne 0\), there are two solutions to \(ax^2 + bx + c = 0\) and they are
|
||||||
|
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
|
||||||
BIN
webseite/config/subjects/mathe/topics/topic8/exercise1.pdf
Normal file
BIN
webseite/config/subjects/mathe/topics/topic8/image.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
11
webseite/config/subjects/mathe/topics/topic8/properties.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"displayName": "Rechnen mit Gewichten",
|
||||||
|
"icon": "fa-divide",
|
||||||
|
"description": "Eine kurze Beschreibung des Themas",
|
||||||
|
"relatedTopics": [
|
||||||
|
"topic2", "topic3"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"exercise1.pdf"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Das ist der Erklärtext
|
||||||
|
<img alt="Ein Bild" src="$TOPICPATH/image.png">
|
||||||
|
<br>
|
||||||
|
When \(a \ne 0\), there are two solutions to \(ax^2 + bx + c = 0\) and they are
|
||||||
|
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
|
||||||
BIN
webseite/config/subjects/mathe/topics/topic9/exercise1.pdf
Normal file
BIN
webseite/config/subjects/mathe/topics/topic9/image.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
11
webseite/config/subjects/mathe/topics/topic9/properties.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"displayName": "Rechnen mit Längen",
|
||||||
|
"icon": "fa-divide",
|
||||||
|
"description": "Eine kurze Beschreibung des Themas",
|
||||||
|
"relatedTopics": [
|
||||||
|
"topic2", "topic3"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"exercise1.pdf"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -136,20 +136,71 @@
|
|||||||
require_once ("classes/SubjectData.php");
|
require_once ("classes/SubjectData.php");
|
||||||
$subjects = SubjectData::getAll();
|
$subjects = SubjectData::getAll();
|
||||||
|
|
||||||
|
// Function to generate color variants from base color
|
||||||
|
function generateColorVariants($baseColor) {
|
||||||
|
// Remove # if present
|
||||||
|
$baseColor = ltrim($baseColor, '#');
|
||||||
|
|
||||||
|
// Convert to RGB
|
||||||
|
$r = hexdec(substr($baseColor, 0, 2));
|
||||||
|
$g = hexdec(substr($baseColor, 2, 2));
|
||||||
|
$b = hexdec(substr($baseColor, 4, 2));
|
||||||
|
|
||||||
|
// Generate lighter variant for secondary
|
||||||
|
$secondary = sprintf("#%02x%02x%02x",
|
||||||
|
min(255, $r + 70),
|
||||||
|
min(255, $g + 70),
|
||||||
|
min(255, $b + 70)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Generate very light variant for background
|
||||||
|
$light = sprintf("#%02x%02x%02x",
|
||||||
|
min(255, $r + 140),
|
||||||
|
min(255, $g + 140),
|
||||||
|
min(255, $b + 140)
|
||||||
|
);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'primary' => '#' . $baseColor,
|
||||||
|
'secondary' => $secondary,
|
||||||
|
'light' => $light
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate colors for each subject
|
||||||
foreach ($subjects as $subject) {
|
foreach ($subjects as $subject) {
|
||||||
|
$colors = generateColorVariants($subject->color);
|
||||||
?>
|
?>
|
||||||
<a href="subject.php?subject=<?php echo($subject->id); ?>" class="block">
|
<a href="subject.php?subject=<?php echo($subject->id); ?>" class="block">
|
||||||
<div class="gradient-border p-6 card-hover bg-white">
|
<div class="gradient-border p-6 card-hover" style="
|
||||||
|
background: linear-gradient(145deg,
|
||||||
|
<?php echo $colors['light']; ?> 0%,
|
||||||
|
white 100%
|
||||||
|
);
|
||||||
|
border: 2px solid <?php echo $colors['secondary']; ?>;
|
||||||
|
border-radius: 1rem;
|
||||||
|
box-shadow: 0 4px 6px -1px <?php echo $colors['light']; ?>,
|
||||||
|
0 2px 4px -2px <?php echo $colors['secondary']; ?>;">
|
||||||
<div class="flex items-start space-x-4">
|
<div class="flex items-start space-x-4">
|
||||||
<div class="w-12 h-12 rounded-lg bg-purple-100 flex items-center justify-center">
|
<div class="w-12 h-12 rounded-lg flex items-center justify-center"
|
||||||
<i class="fas <?php echo($subject->icon); ?> text-2xl text-purple-600"></i>
|
style="background-color: rgba(<?php
|
||||||
|
$hex = ltrim($colors['primary'], '#');
|
||||||
|
$r = hexdec(substr($hex, 0, 2));
|
||||||
|
$g = hexdec(substr($hex, 2, 2));
|
||||||
|
$b = hexdec(substr($hex, 4, 2));
|
||||||
|
echo "$r, $g, $b, 0.1";
|
||||||
|
?>)">
|
||||||
|
<i class="fas <?php echo($subject->icon); ?> text-2xl"
|
||||||
|
style="color: <?php echo $colors['primary']; ?>"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<h3 class="text-xl font-bold text-gray-900 mb-2"><?php echo($subject->displayName); ?></h3>
|
<h3 class="text-xl font-bold text-gray-900 mb-2"><?php echo($subject->displayName); ?></h3>
|
||||||
<p class="text-gray-600 mb-4"><?php echo($subject->description); ?></p>
|
<p class="text-gray-600 mb-4"><?php echo($subject->description); ?></p>
|
||||||
<div class="grid grid-cols-3 gap-4 mb-4">
|
<div class="grid grid-cols-3 gap-4 mb-4">
|
||||||
<div class="text-center p-2 rounded-lg bg-purple-50">
|
<div class="text-center p-2 rounded-lg"
|
||||||
<div class="font-bold text-purple-600">150+</div>
|
style="background-color: <?php echo $colors['light']; ?>">
|
||||||
|
<div class="font-bold"
|
||||||
|
style="color: <?php echo $colors['primary']; ?>">150+</div>
|
||||||
<div class="text-sm text-gray-600">Übungen</div>
|
<div class="text-sm text-gray-600">Übungen</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center p-2 rounded-lg bg-purple-50">
|
<div class="text-center p-2 rounded-lg bg-purple-50">
|
||||||
@@ -163,7 +214,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex items-center space-x-2">
|
<div class="flex items-center space-x-2">
|
||||||
<span class="text-sm text-gray-500">Aktuelle Einheit:</span>
|
<span class="text-sm text-gray-500">Aktuelle Einheit:</span>
|
||||||
<span class="px-2 py-1 rounded-full bg-purple-100 text-purple-600 text-sm">Bruchrechnung</span>
|
<span class="px-2 py-1 rounded-full text-sm"
|
||||||
|
style="background-color: <?php echo $colors['light']; ?>;
|
||||||
|
color: <?php echo $colors['primary']; ?>">
|
||||||
|
Bruchrechnung
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -109,16 +109,16 @@ $topics = $subjectData->topics;
|
|||||||
.search-container {
|
.search-container {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 280px;
|
|
||||||
right: 0;
|
right: 0;
|
||||||
padding: 1rem 2rem;
|
padding: 1rem;
|
||||||
background: var(--card-bg);
|
background: var(--card-bg);
|
||||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
||||||
transition: left 0.3s ease;
|
|
||||||
z-index: 40;
|
z-index: 40;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-box {
|
.search-box {
|
||||||
@@ -146,11 +146,12 @@ $topics = $subjectData->topics;
|
|||||||
|
|
||||||
.container {
|
.container {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); /* Back to original 380px for desktop */
|
||||||
gap: 2rem;
|
gap: 2rem; /* Back to original 2rem gap */
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
max-width: 1600px;
|
max-width: 1600px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.topic-card {
|
.topic-card {
|
||||||
@@ -296,7 +297,31 @@ $topics = $subjectData->topics;
|
|||||||
transition: width 1.5s cubic-bezier(0.4, 0, 0.2, 1);
|
transition: width 1.5s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1025px) {
|
||||||
|
.menu-toggle {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-container {
|
||||||
|
left: 280px; /* Sidebar width */
|
||||||
|
width: calc(100% - 280px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
margin-left: 280px;
|
||||||
|
width: calc(100% - 280px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 1024px) {
|
@media (max-width: 1024px) {
|
||||||
|
.menu-toggle {
|
||||||
|
display: flex !important;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar {
|
.sidebar {
|
||||||
transform: translateX(-100%);
|
transform: translateX(-100%);
|
||||||
}
|
}
|
||||||
@@ -305,13 +330,58 @@ $topics = $subjectData->topics;
|
|||||||
transform: translateX(0);
|
transform: translateX(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-container {
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
padding-left: 4.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.main-content {
|
.main-content {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-box {
|
||||||
|
width: calc(100% - 2rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
.search-container {
|
.search-container {
|
||||||
left: 0;
|
padding: 1rem;
|
||||||
|
padding-left: 4.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-box {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.search-container {
|
||||||
|
padding: 0.75rem;
|
||||||
|
padding-left: 4rem; /* Keep space for menu icon */
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-box {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
padding: 0.5rem 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-links {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-btn {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topic-card {
|
||||||
|
margin: 0 0.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,20 +390,21 @@ $topics = $subjectData->topics;
|
|||||||
top: 1rem;
|
top: 1rem;
|
||||||
left: 1rem;
|
left: 1rem;
|
||||||
z-index: 60;
|
z-index: 60;
|
||||||
background: white;
|
background: var(--card-bg);
|
||||||
border: none;
|
border: none;
|
||||||
padding: 0.75rem;
|
padding: 0.75rem;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
||||||
display: none;
|
width: 42px;
|
||||||
|
height: 42px;
|
||||||
|
display: none; /* Hidden by default */
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: var(--text-primary);
|
||||||
|
transition: all 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 1024px) {
|
|
||||||
.menu-toggle {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Add floating animation for icons */
|
/* Add floating animation for icons */
|
||||||
@keyframes float {
|
@keyframes float {
|
||||||
0%, 100% { transform: translateY(0); }
|
0%, 100% { transform: translateY(0); }
|
||||||
@@ -523,15 +594,6 @@ $topics = $subjectData->topics;
|
|||||||
<a href="#" class="nav-link">
|
<a href="#" class="nav-link">
|
||||||
<i class="fas fa-book"></i> Kurse
|
<i class="fas fa-book"></i> Kurse
|
||||||
</a>
|
</a>
|
||||||
<a href="#" class="nav-link">
|
|
||||||
<i class="fas fa-trophy"></i> Erfolge
|
|
||||||
</a>
|
|
||||||
<a href="#" class="nav-link">
|
|
||||||
<i class="fas fa-chart-line"></i> Fortschritt
|
|
||||||
</a>
|
|
||||||
<a href="#" class="nav-link">
|
|
||||||
<i class="fas fa-question-circle"></i> Hilfe
|
|
||||||
</a>
|
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div class="search-container">
|
<div class="search-container">
|
||||||
@@ -601,9 +663,100 @@ $topics = $subjectData->topics;
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const menuToggle = document.querySelector('.menu-toggle');
|
||||||
|
const sidebar = document.querySelector('.sidebar');
|
||||||
|
const searchContainer = document.querySelector('.search-container');
|
||||||
|
const mainContent = document.querySelector('.main-content');
|
||||||
|
|
||||||
|
// Function to handle sidebar toggle
|
||||||
function toggleSidebar() {
|
function toggleSidebar() {
|
||||||
document.querySelector('.sidebar').classList.toggle('active');
|
sidebar.classList.toggle('active');
|
||||||
|
|
||||||
|
// Add overlay when sidebar is active on mobile/tablet
|
||||||
|
if (window.innerWidth <= 1024) {
|
||||||
|
if (sidebar.classList.contains('active')) {
|
||||||
|
addOverlay();
|
||||||
|
} else {
|
||||||
|
removeOverlay();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to add overlay
|
||||||
|
function addOverlay() {
|
||||||
|
const overlay = document.createElement('div');
|
||||||
|
overlay.className = 'sidebar-overlay';
|
||||||
|
overlay.style.cssText = `
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 45;
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
`;
|
||||||
|
document.body.appendChild(overlay);
|
||||||
|
|
||||||
|
// Close sidebar when clicking overlay
|
||||||
|
overlay.addEventListener('click', () => {
|
||||||
|
sidebar.classList.remove('active');
|
||||||
|
removeOverlay();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fade in
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
overlay.style.opacity = '1';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to remove overlay
|
||||||
|
function removeOverlay() {
|
||||||
|
const overlay = document.querySelector('.sidebar-overlay');
|
||||||
|
if (overlay) {
|
||||||
|
overlay.style.opacity = '0';
|
||||||
|
setTimeout(() => overlay.remove(), 300);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add click event to menu toggle
|
||||||
|
menuToggle.addEventListener('click', toggleSidebar);
|
||||||
|
|
||||||
|
// Handle window resize
|
||||||
|
let resizeTimer;
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
clearTimeout(resizeTimer);
|
||||||
|
resizeTimer = setTimeout(() => {
|
||||||
|
if (window.innerWidth > 1024) {
|
||||||
|
sidebar.classList.remove('active');
|
||||||
|
removeOverlay();
|
||||||
|
}
|
||||||
|
}, 250);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle escape key to close sidebar
|
||||||
|
document.addEventListener('keydown', (e) => {
|
||||||
|
if (e.key === 'Escape' && sidebar.classList.contains('active')) {
|
||||||
|
sidebar.classList.remove('active');
|
||||||
|
removeOverlay();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add this right after your existing toggleSidebar function
|
||||||
|
function updateMenuVisibility() {
|
||||||
|
const menuToggle = document.querySelector('.menu-toggle');
|
||||||
|
if (window.innerWidth <= 768) { // Smartphone breakpoint
|
||||||
|
menuToggle.style.display = 'flex';
|
||||||
|
} else {
|
||||||
|
menuToggle.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add event listeners
|
||||||
|
window.addEventListener('load', updateMenuVisibility);
|
||||||
|
window.addEventListener('resize', updateMenuVisibility);
|
||||||
|
|
||||||
// Animate progress bars on load
|
// Animate progress bars on load
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
@@ -671,9 +824,11 @@ $topics = $subjectData->topics;
|
|||||||
const progressBars = document.querySelectorAll('.progress-bar');
|
const progressBars = document.querySelectorAll('.progress-bar');
|
||||||
progressBars.forEach(bar => {
|
progressBars.forEach(bar => {
|
||||||
const progressElement = bar.querySelector('.progress');
|
const progressElement = bar.querySelector('.progress');
|
||||||
|
if (progressElement) { // Add null check
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
progressElement.style.width = '100%';
|
progressElement.style.width = '100%';
|
||||||
}, 300);
|
}, 300);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -714,29 +869,42 @@ $topics = $subjectData->topics;
|
|||||||
// Add card hover effects
|
// Add card hover effects
|
||||||
document.querySelectorAll('.topic-card').forEach(card => {
|
document.querySelectorAll('.topic-card').forEach(card => {
|
||||||
card.addEventListener('mouseenter', () => {
|
card.addEventListener('mouseenter', () => {
|
||||||
gsap.to(card.querySelector('.topic-icon'), {
|
const icon = card.querySelector('.topic-icon');
|
||||||
|
if (window.gsap) {
|
||||||
|
gsap.to(icon, {
|
||||||
rotate: -10,
|
rotate: -10,
|
||||||
scale: 1.2,
|
scale: 1.2,
|
||||||
duration: 0.3
|
duration: 0.3
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
// Fallback animation using CSS
|
||||||
|
icon.style.transform = 'rotate(-10deg) scale(1.2)';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
card.addEventListener('mouseleave', () => {
|
card.addEventListener('mouseleave', () => {
|
||||||
gsap.to(card.querySelector('.topic-icon'), {
|
const icon = card.querySelector('.topic-icon');
|
||||||
|
if (window.gsap) {
|
||||||
|
gsap.to(icon, {
|
||||||
rotate: 0,
|
rotate: 0,
|
||||||
scale: 1,
|
scale: 1,
|
||||||
duration: 0.3
|
duration: 0.3
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
// Fallback animation using CSS
|
||||||
|
icon.style.transform = 'none';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Update search function with fallback animation
|
||||||
function handleSearch() {
|
function handleSearch() {
|
||||||
const searchTerm = document.getElementById('searchInput').value.toLowerCase();
|
const searchTerm = document.getElementById('searchInput').value.toLowerCase();
|
||||||
const topicCards = document.querySelectorAll('.topic-card');
|
const topicCards = document.querySelectorAll('.topic-card');
|
||||||
|
|
||||||
topicCards.forEach(card => {
|
topicCards.forEach(card => {
|
||||||
const title = card.querySelector('.topic-title').textContent.toLowerCase();
|
const title = card.querySelector('.topic-title')?.textContent.toLowerCase() || '';
|
||||||
const description = card.querySelector('.topic-description').textContent.toLowerCase();
|
const description = card.querySelector('.topic-description')?.textContent.toLowerCase() || '';
|
||||||
const relatedTopics = Array.from(card.querySelectorAll('.related-topics li'))
|
const relatedTopics = Array.from(card.querySelectorAll('.related-topics li'))
|
||||||
.map(li => li.textContent.toLowerCase())
|
.map(li => li.textContent.toLowerCase())
|
||||||
.join(' ');
|
.join(' ');
|
||||||
@@ -745,17 +913,60 @@ $topics = $subjectData->topics;
|
|||||||
|
|
||||||
if (content.includes(searchTerm)) {
|
if (content.includes(searchTerm)) {
|
||||||
card.style.display = 'block';
|
card.style.display = 'block';
|
||||||
// Optional: Add animation for appearing cards
|
if (window.gsap) {
|
||||||
gsap.to(card, {
|
gsap.to(card, {
|
||||||
opacity: 1,
|
opacity: 1,
|
||||||
y: 0,
|
y: 0,
|
||||||
duration: 0.3
|
duration: 0.3
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
card.style.opacity = 1;
|
||||||
|
card.style.transform = 'translateY(0)';
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
card.style.display = 'none';
|
card.style.display = 'none';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the menu visibility JavaScript
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const menuToggle = document.querySelector('.menu-toggle');
|
||||||
|
const sidebar = document.querySelector('.sidebar');
|
||||||
|
|
||||||
|
// Force correct initial state based on viewport
|
||||||
|
function updateMenuState() {
|
||||||
|
if (window.innerWidth <= 1024) {
|
||||||
|
menuToggle.style.display = 'flex';
|
||||||
|
sidebar.style.transform = 'translateX(-100%)';
|
||||||
|
} else {
|
||||||
|
menuToggle.style.display = 'none';
|
||||||
|
sidebar.style.transform = 'translateX(0)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initial state
|
||||||
|
updateMenuState();
|
||||||
|
|
||||||
|
// Update on resize with debounce
|
||||||
|
let resizeTimer;
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
clearTimeout(resizeTimer);
|
||||||
|
resizeTimer = setTimeout(updateMenuState, 250);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Toggle sidebar
|
||||||
|
menuToggle.addEventListener('click', () => {
|
||||||
|
const isHidden = sidebar.style.transform === 'translateX(-100%)';
|
||||||
|
sidebar.style.transform = isHidden ? 'translateX(0)' : 'translateX(-100%)';
|
||||||
|
|
||||||
|
if (isHidden) {
|
||||||
|
addOverlay();
|
||||||
|
} else {
|
||||||
|
removeOverlay();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Code injected by live-server -->
|
<!-- Code injected by live-server -->
|
||||||
|
|||||||