kirpalsingh2252002 commited on
Commit
19e5d94
·
verified ·
1 Parent(s): 0f7629a

create a fully functional ppt editing canvas where i put my html code and think it of like so i have created a presentation agent that will generate ppt using html css js example generated ppt

Browse files

so i want that you create me a full functional and generalised web ui where i input the code of ppt and so i can edit the components in the ppt like edit the text move the image charts etc. to anywhere seemlessly i want that the ui should be very good and should adjust to the size of the ppt it should be generalised and effective as it will be given to the end user so it should be working accurately i hope you understand what i want. think of a canvas where i can do anything ove anything

the slides are 16:9 so they should be properly visble they can contain images, charts etc.

eg ppt fcode

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Introduction to Thermodynamics</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #f5f5f5;
padding: 20px;
}

.slide-container {
width: 1280px;
min-height: 720px;
display: flex;
flex-direction: column;
font-family: 'Montserrat', sans-serif;
position: relative;
background-color: #ffffff;
color: #333333;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
padding: 40px;
}

.slide-header {
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 2px solid #003366;
}

.slide-header h1 {
font-size: 36px;
font-weight: 600;
color: #003366;
}

.content-wrapper {
display: flex;
flex: 1;
gap: 30px;
margin-top: 10px;
}

.text-content {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
}

.text-section {
margin-bottom: 25px;
}

.text-section h3 {
font-size: 20px;
font-weight: 600;
color: #003366;
margin-bottom: 10px;
}

.text-section p, .text-section li {
font-size: 16px;
line-height: 1.5;
margin-bottom: 8px;
}

.text-section ul {
list-style-type: none;
padding-left: 0;
}

.text-section li {
position: relative;
padding-left: 20px;
}

.text-section li:before {
content: "•";
color: #003366;
font-weight: bold;
position: absolute;
left: 0;
}

.image-content {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}

.image-content img {
max-width: 100%;
height: auto;
border: 1px solid #ddd;
border-radius: 4px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.fig-caption {
font-size: 14px;
color: #666;
margin-top: 10px;
text-align: center;
font-style: italic;
}

.slide-footer {
position: absolute;
bottom: 20px;
right: 20px;
font-size: 14px;
color: #666;
}



@media
(max-width: 1300px) {
.slide-container {
width: 100%;
min-height: 600px;
}
}
</style>
</head>
<body>
<div class="slide-container">
<div class="slide-header">
<h1>Introduction to Thermodynamics</h1>
</div>

<div class="content-wrapper">
<div class="text-content">
<div class="text-section">
<h3>Definition</h3>
<p>Thermodynamics is the branch of physics that deals with the relationships between heat, work, temperature, energy, and the laws governing energy conversion.</p>
</div>

<div class="text-section">
<h3>Key Concepts</h3>
<ul>
<li><strong>Energy:</strong> Capacity to do work or produce heat</li>
<li><strong>Temperature:</strong> Measure of average kinetic energy</li>
<li><strong>Entropy:</strong> Measure of disorder or randomness</li>
<li><strong>Thermal Equilibrium:</strong> State where no heat transfer occurs</li>
</ul>
</div>

<div class="text-section">
<h3>Importance</h3>
<p>Thermodynamics forms the foundation for engineering disciplines, chemical processes, physical theories, and explains everyday phenomena from engine operation to climate systems.</p>
</div>
</div>

<div class="image-content">
<img src="https://www.chemistrylearner.com/wp-content/uploads/2022/08/Laws-of-Thermodynamics.jpg" alt="Thermodynamic System and Surroundings">
<p class="fig-caption">Fig 2.1 Thermodynamic System and Surroundings</p>
</div>
</div>

<div class="slide-footer">
Slide 2
</div>
</div>
</body>
</html>


give attention to detail

Files changed (6) hide show
  1. README.md +8 -5
  2. components/navbar.js +74 -0
  3. components/sidebar.js +189 -0
  4. index.html +272 -19
  5. script.js +359 -0
  6. style.css +186 -18
README.md CHANGED
@@ -1,10 +1,13 @@
1
  ---
2
- title: Slidecraft Studio
3
- emoji: 😻
4
- colorFrom: pink
5
- colorTo: green
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: SlideCraft Studio 🎨
3
+ colorFrom: blue
4
+ colorTo: pink
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://huggingface.co/deepsite).
components/navbar.js ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class CustomNavbar extends HTMLElement {
2
+ connectedCallback() {
3
+ this.attachShadow({ mode: 'open' });
4
+ this.shadowRoot.innerHTML = `
5
+ <style>
6
+ nav {
7
+ background: linear-gradient(135deg, #3B82F6 0%, #1E40AF 100%);
8
+ color: white;
9
+ padding: 1rem 0;
10
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
11
+ }
12
+
13
+ .nav-container {
14
+ max-width: 1200px;
15
+ margin: 0 auto;
16
+ padding: 0 1rem;
17
+ display: flex;
18
+ justify-content: space-between;
19
+ align-items: center;
20
+ }
21
+
22
+ .logo {
23
+ display: flex;
24
+ align-items: center;
25
+ font-size: 1.5rem;
26
+ font-weight: bold;
27
+ }
28
+
29
+ .nav-links {
30
+ display: flex;
31
+ align-items: center;
32
+ gap: 2rem;
33
+ }
34
+
35
+ .nav-link {
36
+ color: white;
37
+ text-decoration: none;
38
+ padding: 0.5rem 1rem;
39
+ border-radius: 6px;
40
+ transition: background-color 0.2s ease;
41
+ }
42
+
43
+ .nav-link:hover {
44
+ background-color: rgba(255, 255, 255, 0.1);
45
+ }
46
+
47
+ @media (max-width: 768px) {
48
+ .nav-links {
49
+ gap: 1rem;
50
+ }
51
+
52
+ .logo {
53
+ font-size: 1.25rem;
54
+ }
55
+ }
56
+ </style>
57
+ <nav>
58
+ <div class="nav-container">
59
+ <div class="logo">
60
+ <i data-feather="layout"></i>
61
+ <span class="ml-2">SlideCraft Studio</span>
62
+ </div>
63
+ <div class="nav-links">
64
+ <a href="#" class="nav-link">Home</a>
65
+ <a href="#" class="nav-link">Templates</a>
66
+ <a href="#" class="nav-link">Help</a>
67
+ </div>
68
+ </div>
69
+ </nav>
70
+ `;
71
+ }
72
+ }
73
+
74
+ customElements.define('custom-navbar', CustomNavbar);
components/sidebar.js ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class CustomSidebar extends HTMLElement {
2
+ connectedCallback() {
3
+ this.attachShadow({ mode: 'open' });
4
+ this.shadowRoot.innerHTML = `
5
+ <style>
6
+ .sidebar {
7
+ background: white;
8
+ border-radius: 12px;
9
+ padding: 1.5rem;
10
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
11
+ }
12
+
13
+ .sidebar-section {
14
+ margin-bottom: 2rem;
15
+ }
16
+
17
+ .sidebar-title {
18
+ font-size: 1.125rem;
19
+ font-weight: 600;
20
+ color: #1f2937;
21
+ margin-bottom: 1rem;
22
+ display: flex;
23
+ align-items: center;
24
+ }
25
+
26
+ .sidebar-title i {
27
+ margin-right: 0.5rem;
28
+ }
29
+
30
+ .element-btn {
31
+ display: flex;
32
+ align-items: center;
33
+ width: 100%;
34
+ padding: 0.75rem 1rem;
35
+ border: 1px solid #e5e7eb;
36
+ border-radius: 8px;
37
+ margin-bottom: 0.5rem;
38
+ cursor: pointer;
39
+ transition: all 0.2s ease;
40
+ background: white;
41
+ }
42
+
43
+ .element-btn:hover {
44
+ background: #f3f4f6;
45
+ border-color: #3B82F6;
46
+ }
47
+
48
+ .element-btn i {
49
+ margin-right: 0.5rem;
50
+ }
51
+
52
+ .slide-thumbnail {
53
+ width: 100%;
54
+ aspect-ratio: 16/9;
55
+ background: #f8fafc;
56
+ border: 2px dashed #cbd5e1;
57
+ border-radius: 8px;
58
+ display: flex;
59
+ align-items: center;
60
+ justify-content: center;
61
+ margin-bottom: 0.75rem;
62
+ cursor: pointer;
63
+ transition: all 0.2s ease;
64
+ }
65
+
66
+ .slide-thumbnail:hover {
67
+ border-color: #3B82F6;
68
+ background: #eff6ff;
69
+ }
70
+
71
+ .slide-thumbnail.active {
72
+ border-color: #1E40AF;
73
+ background: #dbeafe;
74
+ }
75
+ </style>
76
+ <div class="sidebar">
77
+ <div class="sidebar-section">
78
+ <h3 class="sidebar-title">
79
+ <i data-feather="plus"></i>
80
+ Add Elements
81
+ </h3>
82
+ <button class="element-btn" data-type="text">
83
+ <i data-feather="type"></i>
84
+ Text Box
85
+ </button>
86
+ <button class="element-btn" data-type="image">
87
+ <i data-feather="image"></i>
88
+ Image
89
+ </button>
90
+ <button class="element-btn" data-type="shape">
91
+ <i data-feather="square"></i>
92
+ Shape
93
+ </button>
94
+ <button class="element-btn" data-type="chart">
95
+ <i data-feather="bar-chart-2"></i>
96
+ Chart
97
+ </button>
98
+ </div>
99
+
100
+ <div class="sidebar-section">
101
+ <h3 class="sidebar-title">
102
+ <i data-feather="layers"></i>
103
+ Slides
104
+ </h3>
105
+ <div class="slide-thumbnail active">
106
+ <i data-feather="file-text" class="text-gray-400"></i>
107
+ </div>
108
+ <div class="slide-thumbnail">
109
+ <i data-feather="file-text" class="text-gray-400"></i>
110
+ </div>
111
+ <div class="slide-thumbnail">
112
+ <i data-feather="file-text" class="text-gray-400"></i>
113
+ </div>
114
+ </div>
115
+
116
+ <div class="sidebar-section">
117
+ <h3 class="sidebar-title">
118
+ <i data-feather="settings"></i>
119
+ Properties
120
+ </h3>
121
+ <div class="property-control">
122
+ <label class="block text-sm text-gray-600 mb-1">Font Size</label>
123
+ <input type="range" min="8" max="72" value="16" class="w-full">
124
+ </div>
125
+ </div>
126
+ </div>
127
+ `;
128
+
129
+ // Add event listeners for element buttons
130
+ setTimeout(() => {
131
+ const buttons = this.shadowRoot.querySelectorAll('.element-btn');
132
+ buttons.forEach(button => {
133
+ button.addEventListener('click', () => {
134
+ const type = button.getAttribute('data-type');
135
+ this.addElement(type);
136
+ });
137
+ }, 100);
138
+ });
139
+ }
140
+
141
+ addElement(type) {
142
+ const canvasContainer = document.getElementById('canvasContainer');
143
+ let newElement;
144
+
145
+ switch(type) {
146
+ case 'text':
147
+ newElement = document.createElement('div');
148
+ newElement.className = 'editable-element';
149
+ newElement.setAttribute('contenteditable', 'true');
150
+ newElement.style.position = 'absolute';
151
+ newElement.style.left = '100px';
152
+ newElement.style.top = '100px';
153
+ newElement.style.padding = '10px';
154
+ newElement.style.background = 'white';
155
+ newElement.style.border = '1px solid #e5e7eb';
156
+ newElement.style.borderRadius = '6px';
157
+ newElement.style.minWidth = '200px';
158
+ newElement.style.minHeight = '40px';
159
+ newElement.style.zIndex = '1000';
160
+ newElement.textContent = 'Double click to edit text';
161
+ break;
162
+
163
+ case 'image':
164
+ newElement = document.createElement('div');
165
+ newElement.className = 'editable-element';
166
+ newElement.style.position = 'absolute';
167
+ newElement.style.left = '150px';
168
+ newElement.style.top = '150px';
169
+ newElement.style.width = '200px';
170
+ newElement.style.height = '150px';
171
+ newElement.style.background = '#f3f4f6';
172
+ newElement.style.border = '2px dashed #d1d5db';
173
+ newElement.style.borderRadius = '6px';
174
+ newElement.style.display = 'flex';
175
+ newElement.style.alignItems = 'center';
176
+ newElement.style.justifyContent = 'center';
177
+ newElement.innerHTML = `
178
+ <i data-feather="image" class="text-gray-400"></i>
179
+ <span class="ml-2 text-gray-500">Add Image</span>
180
+ `;
181
+ break;
182
+
183
+ case 'chart':
184
+ newElement = document.createElement('div');
185
+ newElement.className = 'editable-element';
186
+ newElement.style.position = 'absolute';
187
+ newElement.style.left = '200px';
188
+ newElement.style.top = '200px';
189
+ newElement.style.width = '300
index.html CHANGED
@@ -1,19 +1,272 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>SlideCraft Studio - PPT Editor</title>
7
+ <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
8
+ <link rel="stylesheet" href="style.css">
9
+ <script src="https://cdn.tailwindcss.com"></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
11
+ <script src="https://unpkg.com/feather-icons"></script>
12
+ <script>
13
+ tailwind.config = {
14
+ theme: {
15
+ extend: {
16
+ colors: {
17
+ primary: '#3B82F6',
18
+ secondary: '#1E40AF'
19
+ }
20
+ }
21
+ }
22
+ }
23
+ </script>
24
+ </head>
25
+ <body class="bg-gray-100 min-h-screen">
26
+ <custom-navbar></custom-navbar>
27
+
28
+ <div class="container mx-auto px-4 py-6">
29
+ <div class="grid grid-cols-1 lg:grid-cols-4 gap-6">
30
+ <!-- Sidebar -->
31
+ <div class="lg:col-span-1">
32
+ <custom-sidebar></custom-sidebar>
33
+ </div>
34
+
35
+ <!-- Main Content -->
36
+ <div class="lg:col-span-3">
37
+ <div class="bg-white rounded-xl shadow-lg p-6">
38
+ <div class="flex justify-between items-center mb-6">
39
+ <h1 class="text-2xl font-bold text-gray-800">PPT Editor</h1>
40
+ <div class="flex space-x-3">
41
+ <button id="previewMode" class="bg-primary hover:bg-secondary text-white px-4 py-2 rounded-lg transition-colors flex items-center">
42
+ <i data-feather="eye" class="w-4 h-4 mr-2"></i>
43
+ Preview
44
+ </button>
45
+ <button id="editMode" class="bg-gray-200 hover:bg-gray-300 text-gray-700 px-4 py-2 rounded-lg transition-colors flex items-center">
46
+ <i data-feather="edit" class="w-4 h-4 mr-2"></i>
47
+ Edit
48
+ </button>
49
+ <button id="exportBtn" class="bg-green-500 hover:bg-green-600 text-white px-4 py-2 rounded-lg transition-colors flex items-center">
50
+ <i data-feather="download" class="w-4 h-4 mr-2"></i>
51
+ Export
52
+ </button>
53
+ </div>
54
+ </div>
55
+
56
+ <!-- Code Input -->
57
+ <div class="mb-6">
58
+ <label class="block text-sm font-medium text-gray-700 mb-2">PPT HTML Code</label>
59
+ <textarea id="codeInput" class="w-full h-40 p-4 border border-gray-300 rounded-lg font-mono text-sm focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="Paste your PPT HTML code here...">
60
+ &lt;!DOCTYPE html&gt;
61
+ &lt;html lang="en"&gt;
62
+ &lt;head&gt;
63
+ &lt;meta charset="UTF-8"&gt;
64
+ &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
65
+ &lt;title&gt;Introduction to Thermodynamics&lt;/title&gt;
66
+ &lt;link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"&gt;
67
+ &lt;link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700&amp;display=swap" rel="stylesheet"&gt;
68
+ &lt;style&gt;
69
+ * {
70
+ margin: 0;
71
+ padding: 0;
72
+ box-sizing: border-box;
73
+ }
74
+
75
+ body {
76
+ display: flex;
77
+ justify-content: center;
78
+ align-items: center;
79
+ min-height: 100vh;
80
+ background-color: #f5f5f5;
81
+ padding: 20px;
82
+ }
83
+
84
+ .slide-container {
85
+ width: 1280px;
86
+ min-height: 720px;
87
+ display: flex;
88
+ flex-direction: column;
89
+ font-family: 'Montserrat', sans-serif;
90
+ position: relative;
91
+ background-color: #ffffff;
92
+ color: #333333;
93
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
94
+ padding: 40px;
95
+ }
96
+
97
+ .slide-header {
98
+ margin-bottom: 20px;
99
+ padding-bottom: 15px;
100
+ border-bottom: 2px solid #003366;
101
+ }
102
+
103
+ .slide-header h1 {
104
+ font-size: 36px;
105
+ font-weight: 600;
106
+ color: #003366;
107
+ }
108
+
109
+ .content-wrapper {
110
+ display: flex;
111
+ flex: 1;
112
+ gap: 30px;
113
+ margin-top: 10px;
114
+ }
115
+
116
+ .text-content {
117
+ flex: 1;
118
+ display: flex;
119
+ flex-direction: column;
120
+ justify-content: space-between;
121
+ }
122
+
123
+ .text-section {
124
+ margin-bottom: 25px;
125
+ }
126
+
127
+ .text-section h3 {
128
+ font-size: 20px;
129
+ font-weight: 600;
130
+ color: #003366;
131
+ margin-bottom: 10px;
132
+ }
133
+
134
+ .text-section p, .text-section li {
135
+ font-size: 16px;
136
+ line-height: 1.5;
137
+ margin-bottom: 8px;
138
+ }
139
+
140
+ .text-section ul {
141
+ list-style-type: none;
142
+ padding-left: 0;
143
+ }
144
+
145
+ .text-section li {
146
+ position: relative;
147
+ padding-left: 20px;
148
+ }
149
+
150
+ .text-section li:before {
151
+ content: "•";
152
+ color: #003366;
153
+ font-weight: bold;
154
+ position: absolute;
155
+ left: 0;
156
+ }
157
+
158
+ .image-content {
159
+ flex: 1;
160
+ display: flex;
161
+ flex-direction: column;
162
+ align-items: center;
163
+ justify-content: center;
164
+ }
165
+
166
+ .image-content img {
167
+ max-width: 100%;
168
+ height: auto;
169
+ border: 1px solid #ddd;
170
+ border-radius: 4px;
171
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
172
+ }
173
+
174
+ .fig-caption {
175
+ font-size: 14px;
176
+ color: #666;
177
+ margin-top: 10px;
178
+ text-align: center;
179
+ font-style: italic;
180
+ }
181
+
182
+ .slide-footer {
183
+ position: absolute;
184
+ bottom: 20px;
185
+ right: 20px;
186
+ font-size: 14px;
187
+ color: #666;
188
+ }
189
+
190
+ @media (max-width: 1300px) {
191
+ .slide-container {
192
+ width: 100%;
193
+ min-height: 600px;
194
+ }
195
+ }
196
+ &lt;/style&gt;
197
+ &lt;/head&gt;
198
+ &lt;body&gt;
199
+ &lt;div class="slide-container"&gt;
200
+ &lt;div class="slide-header"&gt;
201
+ &lt;h1&gt;Introduction to Thermodynamics&lt;/h1&gt;
202
+ &lt;/div&gt;
203
+
204
+ &lt;div class="content-wrapper"&gt;
205
+ &lt;div class="text-content"&gt;
206
+ &lt;div class="text-section"&gt;
207
+ &lt;h3&gt;Definition&lt;/h3&gt;
208
+ &lt;p&gt;Thermodynamics is the branch of physics that deals with the relationships between heat, work, temperature, energy, and the laws governing energy conversion.&lt;/p&gt;
209
+ &lt;/div&gt;
210
+
211
+ &lt;div class="text-section"&gt;
212
+ &lt;h3&gt;Key Concepts&lt;/h3&gt;
213
+ &lt;ul&gt;
214
+ &lt;li&gt;&lt;strong&gt;Energy:&lt;/strong&gt; Capacity to do work or produce heat&lt;/li&gt;
215
+ &lt;li&gt;&lt;strong&gt;Temperature:&lt;/strong&gt; Measure of average kinetic energy&lt;/li&gt;
216
+ &lt;li&gt;&lt;strong&gt;Entropy:&lt;/strong&gt; Measure of disorder or randomness&lt;/li&gt;
217
+ &lt;li&gt;&lt;strong&gt;Thermal Equilibrium:&lt;/strong&gt; State where no heat transfer occurs&lt;/li&gt;
218
+ &lt;/ul&gt;
219
+ &lt;/div&gt;
220
+
221
+ &lt;div class="text-section"&gt;
222
+ &lt;h3&gt;Importance&lt;/h3&gt;
223
+ &lt;p&gt;Thermodynamics forms the foundation for engineering disciplines, chemical processes, physical theories, and explains everyday phenomena from engine operation to climate systems.&lt;/p&gt;
224
+ &lt;/div&gt;
225
+ &lt;/div&gt;
226
+
227
+ &lt;div class="image-content"&gt;
228
+ &lt;img src="https://www.chemistrylearner.com/wp-content/uploads/2022/08/Laws-of-Thermodynamics.jpg" alt="Thermodynamic System and Surroundings"&gt;
229
+ &lt;p class="fig-caption"&gt;Fig 2.1 Thermodynamic System and Surroundings&lt;/p&gt;
230
+ &lt;/div&gt;
231
+ &lt;/div&gt;
232
+
233
+ &lt;div class="slide-footer"&gt;
234
+ Slide 2
235
+ &lt;/div&gt;
236
+ &lt;/div&gt;
237
+ &lt;/body&gt;
238
+ &lt;/html&gt;
239
+ </textarea>
240
+ <div class="flex justify-end mt-2">
241
+ <button id="loadCode" class="bg-primary hover:bg-secondary text-white px-4 py-2 rounded-lg transition-colors">
242
+ Load PPT
243
+ </button>
244
+ </div>
245
+ </div>
246
+
247
+ <!-- Canvas Container -->
248
+ <div class="border-2 border-dashed border-gray-300 rounded-xl p-4 bg-gray-50 min-h-[600px]">
249
+ <div id="canvasContainer" class="flex justify-center items-center min-h-[500px]">
250
+ <div id="placeholder" class="text-center text-gray-500">
251
+ <i data-feather="file" class="w-16 h-16 mx-auto mb-4"></i>
252
+ <p class="text-lg">Load your PPT code to start editing</p>
253
+ </div>
254
+ </div>
255
+ </div>
256
+ </div>
257
+ </div>
258
+ </div>
259
+ </div>
260
+
261
+ <custom-footer></custom-footer>
262
+
263
+ <script src="components/navbar.js"></script>
264
+ <script src="components/sidebar.js"></script>
265
+ <script src="components/footer.js"></script>
266
+ <script src="script.js"></script>
267
+ <script>
268
+ feather.replace();
269
+ </script>
270
+ <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
271
+ </body>
272
+ </html>
script.js ADDED
@@ -0,0 +1,359 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Global state
2
+ let currentMode = 'edit';
3
+ let selectedElement = null;
4
+ let isDragging = false;
5
+ let dragOffset = { x: 0, y: 0 };
6
+
7
+ // Initialize the application
8
+ document.addEventListener('DOMContentLoaded', function() {
9
+ initializeEventListeners();
10
+ setupCanvas();
11
+ });
12
+
13
+ function initializeEventListeners() {
14
+ // Mode buttons
15
+ document.getElementById('previewMode').addEventListener('click', () => switchMode('preview'));
16
+ document.getElementById('editMode').addEventListener('click', () => switchMode('edit'));
17
+
18
+ // Load code button
19
+ document.getElementById('loadCode').addEventListener('click', loadPPT);
20
+
21
+ // Export button
22
+ document.getElementById('exportBtn').addEventListener('click', exportPPT);
23
+
24
+ // Canvas events
25
+ document.getElementById('canvasContainer').addEventListener('click', handleCanvasClick);
26
+ document.addEventListener('keydown', handleKeyDown);
27
+ document.addEventListener('contextmenu', handleContextMenu);
28
+ }
29
+
30
+ function setupCanvas() {
31
+ // Set up initial canvas state
32
+ const canvas = document.getElementById('canvasContainer');
33
+ canvas.addEventListener('mousedown', startDrag);
34
+ canvas.addEventListener('mousemove', handleDrag);
35
+ canvas.addEventListener('mouseup', stopDrag);
36
+ }
37
+
38
+ function switchMode(mode) {
39
+ currentMode = mode;
40
+ const previewBtn = document.getElementById('previewMode');
41
+ const editBtn = document.getElementById('editMode');
42
+
43
+ if (mode === 'preview') {
44
+ previewBtn.classList.remove('bg-gray-200', 'text-gray-700');
45
+ previewBtn.classList.add('bg-primary', 'text-white');
46
+ editBtn.classList.remove('bg-primary', 'text-white');
47
+ editBtn.classList.add('bg-gray-200', 'text-gray-700');
48
+ disableEditing();
49
+ } else {
50
+ editBtn.classList.remove('bg-gray-200', 'text-gray-700');
51
+ editBtn.classList.add('bg-primary', 'text-white');
52
+ previewBtn.classList.remove('bg-primary', 'text-white');
53
+ previewBtn.classList.add('bg-gray-200', 'text-gray-700');
54
+ enableEditing();
55
+ }
56
+ }
57
+
58
+ function loadPPT() {
59
+ const codeInput = document.getElementById('codeInput').value;
60
+ const canvasContainer = document.getElementById('canvasContainer');
61
+
62
+ if (!codeInput.trim()) {
63
+ alert('Please enter PPT HTML code');
64
+ return;
65
+ }
66
+
67
+ try {
68
+ // Clear previous content
69
+ canvasContainer.innerHTML = '';
70
+
71
+ // Create iframe to safely render the HTML
72
+ const iframe = document.createElement('iframe');
73
+ iframe.style.width = '100%';
74
+ iframe.style.height = '500px';
75
+ iframe.style.border = 'none';
76
+ iframe.style.borderRadius = '8px';
77
+
78
+ iframe.onload = function() {
79
+ // Once iframe is loaded, extract the content and make it editable
80
+ const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
81
+ iframeDoc.open();
82
+ iframeDoc.write(codeInput);
83
+ iframeDoc.close();
84
+
85
+ // Replace iframe with editable content
86
+ setTimeout(() => {
87
+ const slideContent = iframeDoc.body.firstElementChild.cloneNode(true);
88
+ canvasContainer.innerHTML = '';
89
+ canvasContainer.appendChild(slideContent);
90
+
91
+ // Make elements editable
92
+ makeElementsEditable(slideContent);
93
+
94
+ // Scale the slide to fit container
95
+ scaleSlideToFit(slideContent);
96
+ }, 100);
97
+ };
98
+
99
+ canvasContainer.appendChild(iframe);
100
+ } catch (error) {
101
+ console.error('Error loading PPT:', error);
102
+ alert('Error loading PPT. Please check your HTML code.');
103
+ }
104
+ }
105
+
106
+ function makeElementsEditable(container) {
107
+ // Add editable class to all elements
108
+ const allElements = container.querySelectorAll('*');
109
+ allElements.forEach(element => {
110
+ element.classList.add('editable-element');
111
+
112
+ // Make text elements directly editable
113
+ if (element.tagName === 'P' || element.tagName === 'H1' || element.tagName === 'H2' ||
114
+ element.tagName === 'H3' || element.tagName === 'LI' || element.tagName === 'SPAN') {
115
+ element.setAttribute('contenteditable', 'true');
116
+ }
117
+
118
+ // Add event listeners for interaction
119
+ element.addEventListener('mousedown', handleElementMouseDown);
120
+ element.addEventListener('dblclick', handleElementDoubleClick);
121
+ });
122
+ }
123
+
124
+ function scaleSlideToFit(slide) {
125
+ const container = document.getElementById('canvasContainer');
126
+ const containerWidth = container.clientWidth;
127
+ const slideWidth = 1280; // Standard 16:9 slide width
128
+
129
+ if (slideWidth > containerWidth) {
130
+ const scale = (containerWidth - 40) / slideWidth;
131
+ slide.style.transform = `scale(${scale})`;
132
+ slide.style.transformOrigin = 'center top';
133
+ }
134
+ }
135
+
136
+ function handleElementMouseDown(e) {
137
+ if (currentMode !== 'edit') return;
138
+
139
+ e.stopPropagation();
140
+ selectElement(e.target);
141
+
142
+ if (e.target.tagName === 'IMG' || e.target.classList.contains('image-content')) {
143
+ isDragging = true;
144
+ const rect = e.target.getBoundingClientRect();
145
+ dragOffset.x = e.clientX - rect.left;
146
+ dragOffset.y = e.clientY - rect.top;
147
+ }
148
+ }
149
+
150
+ function handleElementDoubleClick(e) {
151
+ if (currentMode !== 'edit') return;
152
+
153
+ e.stopPropagation();
154
+ const element = e.target;
155
+
156
+ if (element.tagName === 'P' || element.tagName === 'H1' || element.tagName === 'H2' ||
157
+ element.tagName === 'H3' || element.tagName === 'LI') {
158
+ element.focus();
159
+ selectElement(element);
160
+ }
161
+ }
162
+
163
+ function startDrag(e) {
164
+ if (currentMode !== 'edit' || !selectedElement) return;
165
+
166
+ isDragging = true;
167
+ const rect = selectedElement.getBoundingClientRect();
168
+ dragOffset.x = e.clientX - rect.left;
169
+ dragOffset.y = e.clientY - rect.top;
170
+ }
171
+
172
+ function handleDrag(e) {
173
+ if (!isDragging || !selectedElement) return;
174
+
175
+ e.preventDefault();
176
+
177
+ const container = document.getElementById('canvasContainer');
178
+ const containerRect = container.getBoundingClientRect();
179
+
180
+ const newX = e.clientX - containerRect.left - dragOffset.x;
181
+ const newY = e.clientY - containerRect.top - dragOffset.y;
182
+
183
+ selectedElement.style.position = 'absolute';
184
+ selectedElement.style.left = `${newX}px`;
185
+ selectedElement.style.top = `${newY}px`;
186
+ selectedElement.style.zIndex = '1000';
187
+ }
188
+
189
+ function stopDrag() {
190
+ isDragging = false;
191
+ }
192
+
193
+ function selectElement(element) {
194
+ // Deselect previous element
195
+ if (selectedElement) {
196
+ selectedElement.classList.remove('selected');
197
+ }
198
+
199
+ // Select new element
200
+ selectedElement = element;
201
+ selectedElement.classList.add('selected');
202
+ }
203
+
204
+ function handleCanvasClick(e) {
205
+ if (e.target === document.getElementById('canvasContainer')) {
206
+ if (selectedElement) {
207
+ selectedElement.classList.remove('selected');
208
+ selectedElement = null;
209
+ }
210
+ }
211
+ }
212
+
213
+ function handleKeyDown(e) {
214
+ if (currentMode !== 'edit' || !selectedElement) return;
215
+
216
+ // Delete selected element
217
+ if (e.key === 'Delete' || e.key === 'Backspace') {
218
+ e.preventDefault();
219
+ selectedElement.remove();
220
+ selectedElement = null;
221
+ }
222
+ }
223
+
224
+ function handleContextMenu(e) {
225
+ if (currentMode !== 'edit') return;
226
+
227
+ e.preventDefault();
228
+
229
+ const element = e.target;
230
+ if (element.classList.contains('editable-element')) {
231
+ selectElement(element);
232
+ showContextMenu(e.clientX, e.clientY, element);
233
+ }
234
+ }
235
+
236
+ function showContextMenu(x, y, element) {
237
+ // Remove existing context menu
238
+ const existingMenu = document.querySelector('.context-menu');
239
+ if (existingMenu) {
240
+ existingMenu.remove();
241
+ }
242
+
243
+ const contextMenu = document.createElement('div');
244
+ contextMenu.className = 'context-menu';
245
+ contextMenu.style.left = `${x}px`;
246
+ contextMenu.style.top = `${y}px`;
247
+
248
+ const menuItems = [
249
+ { icon: 'edit-3', text: 'Edit Text', action: () => editText(element) },
250
+ { icon: 'trash-2', text: 'Delete', action: () => deleteElement(element) },
251
+ { icon: 'copy', text: 'Duplicate', action: () => duplicateElement(element) },
252
+ { icon: 'layers', text: 'Bring to Front', action: () => bringToFront(element) },
253
+ { icon: 'move', text: 'Move to Back', action: () => moveToBack(element) }
254
+ ];
255
+
256
+ menuItems.forEach(item => {
257
+ const menuItem = document.createElement('div');
258
+ menuItem.className = 'context-menu-item';
259
+ menuItem.innerHTML = `
260
+ <i data-feather="${item.icon}"></i>
261
+ <span>${item.text}</span>
262
+ `;
263
+ menuItem.addEventListener('click', item.action);
264
+ contextMenu.appendChild(menuItem);
265
+ });
266
+
267
+ document.body.appendChild(contextMenu);
268
+ feather.replace();
269
+
270
+ // Close context menu when clicking elsewhere
271
+ setTimeout(() => {
272
+ document.addEventListener('click', function closeMenu() {
273
+ contextMenu.remove();
274
+ document.removeEventListener('click', closeMenu);
275
+ });
276
+ }, 10);
277
+ }
278
+
279
+ function editText(element) {
280
+ element.focus();
281
+ const range = document.createRange();
282
+ range.selectNodeContents(element);
283
+ const selection = window.getSelection();
284
+ selection.removeAllRanges();
285
+ selection.addRange(range);
286
+ }
287
+
288
+ function deleteElement(element) {
289
+ element.remove();
290
+ selectedElement = null;
291
+ }
292
+
293
+ function duplicateElement(element) {
294
+ const clone = element.cloneNode(true);
295
+ element.parentNode.insertBefore(clone, element.nextSibling);
296
+ makeElementsEditable(clone);
297
+ selectElement(clone);
298
+ }
299
+
300
+ function bringToFront(element) {
301
+ element.style.zIndex = '1000';
302
+ }
303
+
304
+ function moveToBack(element) {
305
+ element.style.zIndex = '0';
306
+ }
307
+
308
+ function enableEditing() {
309
+ const editableElements = document.querySelectorAll('.editable-element');
310
+ editableElements.forEach(element => {
311
+ element.style.cursor = 'move';
312
+ if (element.tagName === 'P' || element.tagName === 'H1' || element.tagName === 'H2' ||
313
+ element.tagName === 'H3' || element.tagName === 'LI' || element.tagName === 'SPAN') {
314
+ element.setAttribute('contenteditable', 'true');
315
+ }
316
+ });
317
+ }
318
+
319
+ function disableEditing() {
320
+ const editableElements = document.querySelectorAll('.editable-element');
321
+ editableElements.forEach(element => {
322
+ element.style.cursor = 'default';
323
+ element.removeAttribute('contenteditable');
324
+ });
325
+ }
326
+
327
+ function exportPPT() {
328
+ const slideContent = document.querySelector('#canvasContainer > *');
329
+ if (!slideContent) {
330
+ alert('No PPT content to export');
331
+ return;
332
+ }
333
+
334
+ const htmlContent = `
335
+ <!DOCTYPE html>
336
+ <html lang="en">
337
+ <head>
338
+ <meta charset="UTF-8">
339
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
340
+ ${document.querySelector('style').outerHTML}
341
+ </head>
342
+ <body>
343
+ ${slideContent.outerHTML}
344
+ </body>
345
+ </html>`;
346
+
347
+ // Create download link
348
+ const blob = new Blob([htmlContent], { type: 'text/html' });
349
+ const url = URL.createObjectURL(blob);
350
+ const a = document.createElement('a');
351
+ a.href = url;
352
+ a.download = 'presentation.html';
353
+ document.body.appendChild(a);
354
+ a.click();
355
+ document.body.removeChild(a);
356
+ URL.revokeObjectURL(url);
357
+
358
+ alert('PPT exported successfully!');
359
+ }
style.css CHANGED
@@ -1,28 +1,196 @@
 
 
 
 
 
 
 
1
  body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  }
5
 
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
 
9
  }
10
 
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
 
 
 
16
  }
17
 
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
 
 
 
 
 
24
  }
25
 
26
- .card p:last-child {
27
- margin-bottom: 0;
 
 
 
 
 
 
 
 
28
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Global Styles */
2
+ * {
3
+ margin: 0;
4
+ padding: 0;
5
+ box-sizing: border-box;
6
+ }
7
+
8
  body {
9
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
10
+ line-height: 1.6;
11
+ color: #333;
12
+ }
13
+
14
+ /* Canvas Styles */
15
+ .editable-element {
16
+ position: relative;
17
+ cursor: move;
18
+ transition: all 0.2s ease;
19
+ }
20
+
21
+ .editable-element:hover {
22
+ outline: 2px dashed #3B82F6;
23
+ }
24
+
25
+ .editable-element.selected {
26
+ outline: 2px solid #1E40AF;
27
+ box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
28
+ }
29
+
30
+ .edit-handle {
31
+ position: absolute;
32
+ width: 8px;
33
+ height: 8px;
34
+ background: #1E40AF;
35
+ border: 1px solid white;
36
+ border-radius: 50%;
37
+ cursor: pointer;
38
+ z-index: 1000;
39
+ }
40
+
41
+ .edit-handle.top-left { top: -4px; left: -4px; }
42
+ .edit-handle.top-right { top: -4px; right: -4px; }
43
+ .edit-handle.bottom-left { bottom: -4px; left: -4px; }
44
+ .edit-handle.bottom-right { bottom: -4px; right: -4px; }
45
+
46
+ .text-edit-overlay {
47
+ position: absolute;
48
+ top: 0;
49
+ left: 0;
50
+ right: 0;
51
+ bottom: 0;
52
+ background: rgba(59, 130, 246, 0.1);
53
+ display: flex;
54
+ align-items: center;
55
+ justify-content: center;
56
+ opacity: 0;
57
+ transition: opacity 0.2s ease;
58
+ cursor: text;
59
+ }
60
+
61
+ .text-edit-overlay:hover {
62
+ opacity: 1;
63
+ }
64
+
65
+ /* Context Menu */
66
+ .context-menu {
67
+ position: fixed;
68
+ background: white;
69
+ border: 1px solid #e5e7eb;
70
+ border-radius: 8px;
71
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
72
+ padding: 8px 0;
73
+ z-index: 10000;
74
+ min-width: 160px;
75
+ }
76
+
77
+ .context-menu-item {
78
+ display: flex;
79
+ align-items: center;
80
+ padding: 8px 16px;
81
+ cursor: pointer;
82
+ transition: background-color 0.2s ease;
83
+ }
84
+
85
+ .context-menu-item:hover {
86
+ background-color: #f3f4f6;
87
  }
88
 
89
+ .context-menu-item i {
90
+ width: 16px;
91
+ height: 16px;
92
+ margin-right: 8px;
93
  }
94
 
95
+ /* Slide Container */
96
+ .slide-container {
97
+ position: relative;
98
+ width: 1280px;
99
+ min-height: 720px;
100
+ background: white;
101
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
102
+ transform-origin: center top;
103
  }
104
 
105
+ /* Toolbar */
106
+ .toolbar {
107
+ position: fixed;
108
+ top: 50%;
109
+ right: 20px;
110
+ transform: translateY(-50%);
111
+ background: white;
112
+ border-radius: 12px;
113
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
114
+ padding: 12px;
115
+ z-index: 1000;
116
  }
117
 
118
+ .toolbar-btn {
119
+ display: flex;
120
+ align-items: center;
121
+ justify-content: center;
122
+ width: 44px;
123
+ height: 44px;
124
+ border-radius: 8px;
125
+ margin-bottom: 8px;
126
+ cursor: pointer;
127
+ transition: all 0.2s ease;
128
  }
129
+
130
+ .toolbar-btn:hover {
131
+ background: #f3f4f6;
132
+ transform: scale(1.05);
133
+ }
134
+
135
+ /* Responsive Design */
136
+ @media (max-width: 1024px) {
137
+ .slide-container {
138
+ width: 100%;
139
+ min-height: 600px;
140
+ transform: scale(0.8);
141
+ }
142
+ }
143
+
144
+ @media (max-width: 768px) {
145
+ .slide-container {
146
+ transform: scale(0.7);
147
+ min-height: 500px;
148
+ }
149
+
150
+ .toolbar {
151
+ right: 10px;
152
+ padding: 8px;
153
+ }
154
+
155
+ .toolbar-btn {
156
+ width: 36px;
157
+ height: 36px;
158
+ }
159
+ }
160
+
161
+ /* Animation Classes */
162
+ .fade-in {
163
+ animation: fadeIn 0.3s ease-in-out;
164
+ }
165
+
166
+ @keyframes fadeIn {
167
+ from { opacity: 0; transform: translateY(10px); }
168
+ to { opacity: 1; transform: translateY(0); }
169
+ }
170
+
171
+ .slide-in {
172
+ animation: slideIn 0.3s ease-out;
173
+ }
174
+
175
+ @keyframes slideIn {
176
+ from { transform: translateX(-20px); opacity: 0; }
177
+ to { transform: translateX(0); opacity: 1; }
178
+ }
179
+
180
+ /* Custom Scrollbar */
181
+ ::-webkit-scrollbar {
182
+ width: 6px;
183
+ }
184
+
185
+ ::-webkit-scrollbar-track {
186
+ background: #f1f1f1;
187
+ }
188
+
189
+ ::-webkit-scrollbar-thumb {
190
+ background: #c1c1c1;
191
+ border-radius: 3px;
192
+ }
193
+
194
+ ::-webkit-scrollbar-thumb:hover {
195
+ background: #a8a8a8;
196
+ }