mrpolla commited on
Commit
8fe74c6
·
verified ·
1 Parent(s): 2724b76

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +747 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Edp Comparison Tool
3
- emoji: 💻
4
- colorFrom: green
5
- colorTo: yellow
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: edp-comparison-tool
3
+ emoji: 🐳
4
+ colorFrom: yellow
5
+ colorTo: red
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,747 @@
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>EPD Comparison Tool | Sustainable Building Materials</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ .fade-in {
11
+ animation: fadeIn 0.3s ease-in-out;
12
+ }
13
+ @keyframes fadeIn {
14
+ from { opacity: 0; transform: translateY(10px); }
15
+ to { opacity: 1; transform: translateY(0); }
16
+ }
17
+ .indicator-chip {
18
+ transition: all 0.2s ease;
19
+ }
20
+ .indicator-chip:hover {
21
+ transform: translateY(-2px);
22
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
23
+ }
24
+ .stage-cell {
25
+ position: relative;
26
+ }
27
+ .stage-cell:hover .stage-tooltip {
28
+ display: block;
29
+ }
30
+ .stage-tooltip {
31
+ display: none;
32
+ position: absolute;
33
+ bottom: 100%;
34
+ left: 50%;
35
+ transform: translateX(-50%);
36
+ background: #1f2937;
37
+ color: white;
38
+ padding: 4px 8px;
39
+ border-radius: 4px;
40
+ font-size: 12px;
41
+ white-space: nowrap;
42
+ z-index: 10;
43
+ }
44
+ .chart-container {
45
+ height: 300px;
46
+ }
47
+ .ai-chat {
48
+ transition: all 0.3s ease;
49
+ }
50
+ .ai-chat.collapsed {
51
+ height: 60px;
52
+ overflow: hidden;
53
+ }
54
+ .smooth-scroll {
55
+ scroll-behavior: smooth;
56
+ }
57
+ </style>
58
+ </head>
59
+ <body class="bg-gray-50 text-gray-800 font-sans smooth-scroll">
60
+ <!-- Header -->
61
+ <header class="bg-green-700 text-white shadow-md">
62
+ <div class="container mx-auto px-4 py-4 flex justify-between items-center">
63
+ <div class="flex items-center space-x-2">
64
+ <i class="fas fa-leaf text-2xl"></i>
65
+ <h1 class="text-2xl font-bold">EPD Comparison Tool</h1>
66
+ </div>
67
+ <nav>
68
+ <ul class="flex space-x-6">
69
+ <li><a href="#" class="hover:text-green-200 transition" id="nav-home">Home</a></li>
70
+ <li><a href="#" class="hover:text-green-200 transition" id="nav-about">About</a></li>
71
+ <li><a href="#" class="hover:text-green-200 transition" id="nav-help">Help</a></li>
72
+ </ul>
73
+ </nav>
74
+ <div class="flex items-center space-x-4">
75
+ <button id="login-btn" class="bg-white text-green-700 px-4 py-2 rounded-md hover:bg-green-100 transition">
76
+ Sign In
77
+ </button>
78
+ <div id="user-profile" class="hidden items-center space-x-2">
79
+ <img src="https://via.placeholder.com/40" alt="User" class="rounded-full w-8 h-8">
80
+ <span class="font-medium">User</span>
81
+ </div>
82
+ </div>
83
+ </div>
84
+ </header>
85
+
86
+ <!-- Main Content -->
87
+ <main class="container mx-auto px-4 py-8">
88
+ <!-- Selection Page (Default View) -->
89
+ <div id="selection-page" class="fade-in">
90
+ <div class="bg-white rounded-lg shadow-md p-6 mb-8">
91
+ <h2 class="text-xl font-semibold mb-4 text-green-700">Compare Environmental Product Declarations</h2>
92
+ <p class="text-gray-600 mb-6">Select indicators and components to compare their environmental performance across different lifecycle stages.</p>
93
+
94
+ <!-- Indicator Filter -->
95
+ <div class="mb-8">
96
+ <label for="indicator-search" class="block text-sm font-medium text-gray-700 mb-2">Search Indicators</label>
97
+ <div class="relative">
98
+ <input type="text" id="indicator-search" placeholder="Global Warming Potential, Ozone Depletion, etc."
99
+ class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-green-500 focus:border-green-500">
100
+ <div id="indicator-suggestions" class="absolute z-10 mt-1 w-full bg-white border border-gray-300 rounded-md shadow-lg hidden max-h-60 overflow-y-auto"></div>
101
+ </div>
102
+ <div id="selected-indicators" class="mt-3 flex flex-wrap gap-2"></div>
103
+ </div>
104
+
105
+ <!-- Max Results Picker -->
106
+ <div class="mb-8">
107
+ <label for="max-results" class="block text-sm font-medium text-gray-700 mb-2">Maximum Results</label>
108
+ <select id="max-results" class="px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-green-500 focus:border-green-500">
109
+ <option value="5">5</option>
110
+ <option value="10" selected>10</option>
111
+ <option value="15">15</option>
112
+ <option value="20">20</option>
113
+ </select>
114
+ </div>
115
+
116
+ <!-- Component Search -->
117
+ <div class="mb-8">
118
+ <label for="component-search" class="block text-sm font-medium text-gray-700 mb-2">Search Components</label>
119
+ <div class="relative">
120
+ <input type="text" id="component-search" placeholder="Concrete, Steel, Wood, etc."
121
+ class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-green-500 focus:border-green-500">
122
+ <div id="component-suggestions" class="absolute z-10 mt-1 w-full bg-white border border-gray-300 rounded-md shadow-lg hidden max-h-60 overflow-y-auto"></div>
123
+ </div>
124
+ <div id="component-list" class="mt-3 border border-gray-200 rounded-md p-3 max-h-60 overflow-y-auto">
125
+ <!-- Components will be added here -->
126
+ <p class="text-gray-500 text-center py-4">Search for components to compare</p>
127
+ </div>
128
+ </div>
129
+
130
+ <!-- Weighting Section -->
131
+ <div class="mb-8">
132
+ <div class="flex justify-between items-center mb-2">
133
+ <label class="text-sm font-medium text-gray-700">Indicator Weighting</label>
134
+ <button id="reset-weights" class="text-sm text-green-600 hover:text-green-800">Reset All</button>
135
+ </div>
136
+ <div id="weight-sliders" class="space-y-4">
137
+ <!-- Sliders will be added here -->
138
+ <p class="text-gray-500 text-center py-4">Select indicators to enable weighting</p>
139
+ </div>
140
+ </div>
141
+
142
+ <div class="flex justify-end">
143
+ <button id="compare-btn" class="bg-green-600 text-white px-6 py-2 rounded-md hover:bg-green-700 transition flex items-center space-x-2">
144
+ <i class="fas fa-chart-bar"></i>
145
+ <span>Compare Components</span>
146
+ </button>
147
+ </div>
148
+ </div>
149
+
150
+ <!-- AI Suggestions -->
151
+ <div class="bg-white rounded-lg shadow-md p-6">
152
+ <div class="flex items-center justify-between mb-4">
153
+ <h3 class="text-lg font-semibold text-green-700 flex items-center">
154
+ <i class="fas fa-robot mr-2"></i>
155
+ AI Suggestions
156
+ </h3>
157
+ <button id="refresh-suggestions" class="text-green-600 hover:text-green-800">
158
+ <i class="fas fa-sync-alt"></i>
159
+ </button>
160
+ </div>
161
+ <div id="ai-suggestions" class="space-y-4">
162
+ <div class="p-4 bg-blue-50 rounded-md">
163
+ <p class="font-medium text-blue-800">Based on your previous searches, you might want to compare:</p>
164
+ <ul class="list-disc pl-5 mt-2 text-blue-700">
165
+ <li>Concrete vs. Cross-Laminated Timber</li>
166
+ <li>Steel vs. Aluminum structural elements</li>
167
+ </ul>
168
+ </div>
169
+ <div class="p-4 bg-green-50 rounded-md">
170
+ <p class="font-medium text-green-800">For projects focusing on carbon reduction:</p>
171
+ <p class="mt-1 text-green-700">Consider including "Global Warming Potential" and "Embodied Carbon" indicators in your comparison.</p>
172
+ </div>
173
+ </div>
174
+ </div>
175
+ </div>
176
+
177
+ <!-- Results Page (Hidden by Default) -->
178
+ <div id="results-page" class="hidden fade-in">
179
+ <div class="flex justify-between items-center mb-6">
180
+ <h2 class="text-2xl font-semibold text-green-700">Comparison Results</h2>
181
+ <div class="flex space-x-3">
182
+ <button id="back-to-selection" class="bg-gray-200 text-gray-700 px-4 py-2 rounded-md hover:bg-gray-300 transition flex items-center space-x-2">
183
+ <i class="fas fa-arrow-left"></i>
184
+ <span>Modify Selection</span>
185
+ </button>
186
+ <button id="export-pdf" class="bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700 transition flex items-center space-x-2">
187
+ <i class="fas fa-file-pdf"></i>
188
+ <span>Export PDF</span>
189
+ </button>
190
+ <button id="save-session" class="bg-green-600 text-white px-4 py-2 rounded-md hover:bg-green-700 transition flex items-center space-x-2">
191
+ <i class="fas fa-save"></i>
192
+ <span>Save Session</span>
193
+ </button>
194
+ </div>
195
+ </div>
196
+
197
+ <!-- Summary Cards -->
198
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8">
199
+ <div class="bg-white p-4 rounded-lg shadow-sm border-l-4 border-green-500">
200
+ <h3 class="font-medium text-gray-700 mb-1">Selected Indicators</h3>
201
+ <p id="summary-indicators" class="text-2xl font-bold text-green-600">3</p>
202
+ </div>
203
+ <div class="bg-white p-4 rounded-lg shadow-sm border-l-4 border-blue-500">
204
+ <h3 class="font-medium text-gray-700 mb-1">Compared Components</h3>
205
+ <p id="summary-components" class="text-2xl font-bold text-blue-600">5</p>
206
+ </div>
207
+ <div class="bg-white p-4 rounded-lg shadow-sm border-l-4 border-purple-500">
208
+ <h3 class="font-medium text-gray-700 mb-1">Lifecycle Stages</h3>
209
+ <p id="summary-stages" class="text-2xl font-bold text-purple-600">6</p>
210
+ </div>
211
+ </div>
212
+
213
+ <!-- Key Insights -->
214
+ <div class="bg-white rounded-lg shadow-md p-6 mb-8">
215
+ <div class="flex items-center justify-between mb-4">
216
+ <h3 class="text-lg font-semibold text-green-700 flex items-center">
217
+ <i class="fas fa-lightbulb mr-2"></i>
218
+ Key Insights
219
+ </h3>
220
+ <button id="refresh-insights" class="text-green-600 hover:text-green-800">
221
+ <i class="fas fa-sync-alt"></i>
222
+ </button>
223
+ </div>
224
+ <div id="insights-content" class="space-y-4">
225
+ <div class="p-4 bg-yellow-50 rounded-md">
226
+ <p class="font-medium text-yellow-800">Best Overall Performer:</p>
227
+ <p class="mt-1 text-yellow-700">Cross-Laminated Timber shows the lowest environmental impact across 4 of your 5 selected indicators.</p>
228
+ </div>
229
+ <div class="p-4 bg-red-50 rounded-md">
230
+ <p class="font-medium text-red-800">Sustainability Warning:</p>
231
+ <p class="mt-1 text-red-700">PVC has poor recyclability (Module D) and high ozone depletion potential. Consider alternatives for your project.</p>
232
+ </div>
233
+ <div class="p-4 bg-green-50 rounded-md">
234
+ <p class="font-medium text-green-800">Balanced Option:</p>
235
+ <p class="mt-1 text-green-700">Recycled Steel offers a good compromise between structural performance and environmental impact.</p>
236
+ </div>
237
+ </div>
238
+ </div>
239
+
240
+ <!-- Results Tabs -->
241
+ <div class="mb-8">
242
+ <div class="border-b border-gray-200">
243
+ <nav class="-mb-px flex space-x-8">
244
+ <button id="tab-table" class="border-b-2 border-green-500 text-green-600 px-1 py-4 text-sm font-medium">Data Tables</button>
245
+ <button id="tab-charts" class="border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 px-1 py-4 text-sm font-medium">Visualizations</button>
246
+ <button id="tab-calculations" class="border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 px-1 py-4 text-sm font-medium">Calculation Details</button>
247
+ </nav>
248
+ </div>
249
+ </div>
250
+
251
+ <!-- Tables View -->
252
+ <div id="tables-view">
253
+ <div id="indicator-tables" class="space-y-8">
254
+ <!-- Tables will be added here -->
255
+ <div class="bg-white rounded-lg shadow-md p-6">
256
+ <h3 class="text-lg font-semibold mb-4 text-green-700">Global Warming Potential (kg CO₂ eq)</h3>
257
+ <div class="overflow-x-auto">
258
+ <table class="min-w-full divide-y divide-gray-200">
259
+ <thead class="bg-gray-50">
260
+ <tr>
261
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Component</th>
262
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider stage-cell">
263
+ A1 (Raw Material)
264
+ <span class="stage-tooltip">Raw material extraction and processing</span>
265
+ </th>
266
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider stage-cell">
267
+ A1-A3 (Product)
268
+ <span class="stage-tooltip">Cradle to gate (raw materials to manufactured product)</span>
269
+ </th>
270
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider stage-cell">
271
+ C (End of Life)
272
+ <span class="stage-tooltip">End-of-life processing</span>
273
+ </th>
274
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider stage-cell">
275
+ D (Benefits)
276
+ <span class="stage-tooltip">Potential benefits from reuse, recovery or recycling</span>
277
+ </th>
278
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Total</th>
279
+ </tr>
280
+ </thead>
281
+ <tbody class="bg-white divide-y divide-gray-200">
282
+ <tr>
283
+ <td class="px-6 py-4 whitespace-nowrap font-medium">Concrete (30MPa)</td>
284
+ <td class="px-6 py-4 whitespace-nowrap bg-red-100 text-red-800">245</td>
285
+ <td class="px-6 py-4 whitespace-nowrap bg-red-100 text-red-800">320</td>
286
+ <td class="px-6 py-4 whitespace-nowrap bg-yellow-100 text-yellow-800">45</td>
287
+ <td class="px-6 py-4 whitespace-nowrap bg-green-100 text-green-800">-15</td>
288
+ <td class="px-6 py-4 whitespace-nowrap font-semibold">350</td>
289
+ </tr>
290
+ <tr>
291
+ <td class="px-6 py-4 whitespace-nowrap font-medium">Cross-Laminated Timber</td>
292
+ <td class="px-6 py-4 whitespace-nowrap bg-green-100 text-green-800">35</td>
293
+ <td class="px-6 py-4 whitespace-nowrap bg-green-100 text-green-800">75</td>
294
+ <td class="px-6 py-4 whitespace-nowrap bg-green-100 text-green-800">5</td>
295
+ <td class="px-6 py-4 whitespace-nowrap bg-green-100 text-green-800">-25</td>
296
+ <td class="px-6 py-4 whitespace-nowrap font-semibold">55</td>
297
+ </tr>
298
+ <tr>
299
+ <td class="px-6 py-4 whitespace-nowrap font-medium">Recycled Steel</td>
300
+ <td class="px-6 py-4 whitespace-nowrap bg-yellow-100 text-yellow-800">120</td>
301
+ <td class="px-6 py-4 whitespace-nowrap bg-yellow-100 text-yellow-800">150</td>
302
+ <td class="px-6 py-4 whitespace-nowrap bg-green-100 text-green-800">10</td>
303
+ <td class="px-6 py-4 whitespace-nowrap bg-green-100 text-green-800">-40</td>
304
+ <td class="px-6 py-4 whitespace-nowrap font-semibold">120</td>
305
+ </tr>
306
+ </tbody>
307
+ </table>
308
+ </div>
309
+ </div>
310
+ </div>
311
+ </div>
312
+
313
+ <!-- Charts View -->
314
+ <div id="charts-view" class="hidden">
315
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
316
+ <div class="bg-white rounded-lg shadow-md p-6">
317
+ <h3 class="text-lg font-semibold mb-4 text-green-700">Global Warming Potential Comparison</h3>
318
+ <div class="chart-container">
319
+ <canvas id="gwp-chart"></canvas>
320
+ </div>
321
+ </div>
322
+ <div class="bg-white rounded-lg shadow-md p-6">
323
+ <h3 class="text-lg font-semibold mb-4 text-green-700">Lifecycle Stage Breakdown</h3>
324
+ <div class="chart-container">
325
+ <canvas id="stage-chart"></canvas>
326
+ </div>
327
+ </div>
328
+ <div class="bg-white rounded-lg shadow-md p-6">
329
+ <h3 class="text-lg font-semibold mb-4 text-green-700">Weighted Environmental Score</h3>
330
+ <div class="chart-container">
331
+ <canvas id="weighted-chart"></canvas>
332
+ </div>
333
+ </div>
334
+ <div class="bg-white rounded-lg shadow-md p-6">
335
+ <h3 class="text-lg font-semibold mb-4 text-green-700">Indicator Comparison</h3>
336
+ <div class="chart-container">
337
+ <canvas id="indicator-chart"></canvas>
338
+ </div>
339
+ </div>
340
+ </div>
341
+ </div>
342
+
343
+ <!-- Calculations View -->
344
+ <div id="calculations-view" class="hidden">
345
+ <div class="bg-white rounded-lg shadow-md p-6">
346
+ <h3 class="text-lg font-semibold mb-4 text-green-700">Calculation Methodology</h3>
347
+ <div class="prose max-w-none">
348
+ <h4 class="text-md font-medium text-gray-800">Data Sources</h4>
349
+ <p>All environmental impact data is sourced from verified Environmental Product Declarations (EPDs) published in accordance with ISO 14025 and EN 15804 standards.</p>
350
+
351
+ <h4 class="text-md font-medium text-gray-800 mt-4">Lifecycle Stages</h4>
352
+ <p>The following lifecycle stages are considered in the calculations:</p>
353
+ <ul class="list-disc pl-5">
354
+ <li><strong>A1:</strong> Raw material extraction and supply</li>
355
+ <li><strong>A2:</strong> Transport to manufacturing facility</li>
356
+ <li><strong>A3:</strong> Manufacturing process</li>
357
+ <li><strong>C1-C4:</strong> End-of-life processing (recycling, disposal, etc.)</li>
358
+ <li><strong>D:</strong> Benefits and loads beyond the system boundary</li>
359
+ </ul>
360
+
361
+ <h4 class="text-md font-medium text-gray-800 mt-4">Weighting Methodology</h4>
362
+ <p>When indicator weights are applied, the following calculation is used:</p>
363
+ <div class="bg-gray-50 p-4 rounded-md my-2">
364
+ <code>Weighted Score = Σ (Indicator Value × Indicator Weight) / Σ Indicator Weights</code>
365
+ </div>
366
+
367
+ <h4 class="text-md font-medium text-gray-800 mt-4">EPD References</h4>
368
+ <table class="min-w-full divide-y divide-gray-200 mt-2">
369
+ <thead class="bg-gray-50">
370
+ <tr>
371
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Component</th>
372
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">EPD Reference</th>
373
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Validity</th>
374
+ </tr>
375
+ </thead>
376
+ <tbody class="bg-white divide-y divide-gray-200">
377
+ <tr>
378
+ <td class="px-6 py-4 whitespace-nowrap">Concrete (30MPa)</td>
379
+ <td class="px-6 py-4 whitespace-nowrap">EPD-CON-2022-12345</td>
380
+ <td class="px-6 py-4 whitespace-nowrap">2022-2027</td>
381
+ </tr>
382
+ <tr>
383
+ <td class="px-6 py-4 whitespace-nowrap">Cross-Laminated Timber</td>
384
+ <td class="px-6 py-4 whitespace-nowrap">EPD-CLT-2023-67890</td>
385
+ <td class="px-6 py-4 whitespace-nowrap">2023-2028</td>
386
+ </tr>
387
+ <tr>
388
+ <td class="px-6 py-4 whitespace-nowrap">Recycled Steel</td>
389
+ <td class="px-6 py-4 whitespace-nowrap">EPD-RST-2021-54321</td>
390
+ <td class="px-6 py-4 whitespace-nowrap">2021-2026</td>
391
+ </tr>
392
+ </tbody>
393
+ </table>
394
+ </div>
395
+ </div>
396
+ </div>
397
+
398
+ <!-- AI Chat Panel -->
399
+ <div class="bg-white rounded-lg shadow-md p-6 mt-8 ai-chat">
400
+ <div class="flex items-center justify-between mb-4 cursor-pointer" id="chat-toggle">
401
+ <h3 class="text-lg font-semibold text-green-700 flex items-center">
402
+ <i class="fas fa-comments mr-2"></i>
403
+ AI Sustainability Assistant
404
+ </h3>
405
+ <i class="fas fa-chevron-down text-gray-500 transition-transform" id="chat-icon"></i>
406
+ </div>
407
+ <div id="chat-content">
408
+ <div class="bg-gray-50 rounded-md p-4 mb-4 max-h-60 overflow-y-auto" id="chat-messages">
409
+ <div class="flex mb-3">
410
+ <div class="bg-green-100 rounded-lg p-3 max-w-3/4">
411
+ <p class="text-green-800">Hello! I'm your sustainability assistant. Ask me anything about these EPD comparisons or sustainable building materials.</p>
412
+ </div>
413
+ </div>
414
+ </div>
415
+ <div class="flex space-x-2">
416
+ <input type="text" id="chat-input" placeholder="Ask a question about the results..."
417
+ class="flex-1 px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-green-500 focus:border-green-500">
418
+ <button id="send-chat" class="bg-green-600 text-white px-4 py-2 rounded-md hover:bg-green-700 transition">
419
+ <i class="fas fa-paper-plane"></i>
420
+ </button>
421
+ </div>
422
+ <div class="mt-2 text-xs text-gray-500">
423
+ <p>Example questions: "Which component has the lowest carbon footprint?" or "What are alternatives to PVC?"</p>
424
+ </div>
425
+ </div>
426
+ </div>
427
+ </div>
428
+ </main>
429
+
430
+ <!-- Footer -->
431
+ <footer class="bg-gray-800 text-white py-8">
432
+ <div class="container mx-auto px-4">
433
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-8">
434
+ <div>
435
+ <h3 class="text-lg font-semibold mb-4">EPD Comparison Tool</h3>
436
+ <p class="text-gray-400">Making sustainable building decisions easier through transparent environmental data comparison.</p>
437
+ </div>
438
+ <div>
439
+ <h3 class="text-lg font-semibold mb-4">Resources</h3>
440
+ <ul class="space-y-2">
441
+ <li><a href="#" class="text-gray-400 hover:text-white transition">EPD Database</a></li>
442
+ <li><a href="#" class="text-gray-400 hover:text-white transition">Sustainability Standards</a></li>
443
+ <li><a href="#" class="text-gray-400 hover:text-white transition">Calculation Methodology</a></li>
444
+ </ul>
445
+ </div>
446
+ <div>
447
+ <h3 class="text-lg font-semibold mb-4">Contact</h3>
448
+ <ul class="space-y-2">
449
+ <li class="flex items-center space-x-2 text-gray-400">
450
+ <i class="fas fa-envelope"></i>
451
+ <span>support@epdcompare.com</span>
452
+ </li>
453
+ <li class="flex items-center space-x-2 text-gray-400">
454
+ <i class="fas fa-phone"></i>
455
+ <span>+1 (555) 123-4567</span>
456
+ </li>
457
+ </ul>
458
+ </div>
459
+ </div>
460
+ <div class="border-t border-gray-700 mt-8 pt-6 text-center text-gray-400">
461
+ <p>&copy; 2023 EPD Comparison Tool. All rights reserved.</p>
462
+ </div>
463
+ </div>
464
+ </footer>
465
+
466
+ <!-- JavaScript -->
467
+ <script>
468
+ // Sample data
469
+ const indicators = [
470
+ "Global Warming Potential (kg CO₂ eq)",
471
+ "Ozone Depletion Potential (kg CFC-11 eq)",
472
+ "Acidification Potential (kg SO₂ eq)",
473
+ "Eutrophication Potential (kg PO₄ eq)",
474
+ "Abiotic Depletion Potential (kg Sb eq)",
475
+ "Water Consumption (m³)",
476
+ "Primary Energy Demand (MJ)",
477
+ "Photochemical Ozone Creation Potential (kg C₂H₄ eq)"
478
+ ];
479
+
480
+ const components = [
481
+ "Concrete (30MPa)",
482
+ "Concrete (40MPa)",
483
+ "Reinforced Concrete",
484
+ "Cross-Laminated Timber",
485
+ "Glued Laminated Timber",
486
+ "Structural Steel",
487
+ "Recycled Steel",
488
+ "Aluminum",
489
+ "PVC",
490
+ "Copper",
491
+ "Glass",
492
+ "Brick",
493
+ "Aerated Concrete",
494
+ "Fiber Cement Board",
495
+ "Gypsum Board"
496
+ ];
497
+
498
+ // DOM Elements
499
+ const selectionPage = document.getElementById('selection-page');
500
+ const resultsPage = document.getElementById('results-page');
501
+ const compareBtn = document.getElementById('compare-btn');
502
+ const backToSelection = document.getElementById('back-to-selection');
503
+ const indicatorSearch = document.getElementById('indicator-search');
504
+ const indicatorSuggestions = document.getElementById('indicator-suggestions');
505
+ const selectedIndicators = document.getElementById('selected-indicators');
506
+ const componentSearch = document.getElementById('component-search');
507
+ const componentSuggestions = document.getElementById('component-suggestions');
508
+ const componentList = document.getElementById('component-list');
509
+ const weightSliders = document.getElementById('weight-sliders');
510
+ const resetWeights = document.getElementById('reset-weights');
511
+ const maxResults = document.getElementById('max-results');
512
+ const tablesView = document.getElementById('tables-view');
513
+ const chartsView = document.getElementById('charts-view');
514
+ const calculationsView = document.getElementById('calculations-view');
515
+ const tabTable = document.getElementById('tab-table');
516
+ const tabCharts = document.getElementById('tab-charts');
517
+ const tabCalculations = document.getElementById('tab-calculations');
518
+ const chatToggle = document.getElementById('chat-toggle');
519
+ const chatContent = document.getElementById('chat-content');
520
+ const chatIcon = document.getElementById('chat-icon');
521
+ const chatInput = document.getElementById('chat-input');
522
+ const sendChat = document.getElementById('send-chat');
523
+ const chatMessages = document.getElementById('chat-messages');
524
+ const loginBtn = document.getElementById('login-btn');
525
+ const userProfile = document.getElementById('user-profile');
526
+
527
+ // State
528
+ let selectedIndicatorList = [];
529
+ let selectedComponentList = [];
530
+ let indicatorWeights = {};
531
+
532
+ // Initialize
533
+ document.addEventListener('DOMContentLoaded', function() {
534
+ // Set up event listeners
535
+ compareBtn.addEventListener('click', showResults);
536
+ backToSelection.addEventListener('click', showSelection);
537
+ indicatorSearch.addEventListener('input', handleIndicatorSearch);
538
+ componentSearch.addEventListener('input', handleComponentSearch);
539
+ resetWeights.addEventListener('click', resetAllWeights);
540
+ tabTable.addEventListener('click', () => switchTab('table'));
541
+ tabCharts.addEventListener('click', () => switchTab('charts'));
542
+ tabCalculations.addEventListener('click', () => switchTab('calculations'));
543
+ chatToggle.addEventListener('click', toggleChat);
544
+ sendChat.addEventListener('click', sendMessage);
545
+ chatInput.addEventListener('keypress', function(e) {
546
+ if (e.key === 'Enter') sendMessage();
547
+ });
548
+ loginBtn.addEventListener('click', mockLogin);
549
+
550
+ // Initialize charts (mock data)
551
+ initializeCharts();
552
+ });
553
+
554
+ // Functions
555
+ function handleIndicatorSearch() {
556
+ const query = indicatorSearch.value.toLowerCase();
557
+ if (query.length < 2) {
558
+ indicatorSuggestions.classList.add('hidden');
559
+ return;
560
+ }
561
+
562
+ const matches = indicators.filter(ind =>
563
+ ind.toLowerCase().includes(query) &&
564
+ !selectedIndicatorList.includes(ind)
565
+ );
566
+
567
+ if (matches.length === 0) {
568
+ indicatorSuggestions.innerHTML = '<div class="px-4 py-2 text-gray-500">No matching indicators found</div>';
569
+ indicatorSuggestions.classList.remove('hidden');
570
+ return;
571
+ }
572
+
573
+ indicatorSuggestions.innerHTML = '';
574
+ matches.slice(0, 5).forEach(ind => {
575
+ const div = document.createElement('div');
576
+ div.className = 'px-4 py-2 hover:bg-gray-100 cursor-pointer';
577
+ div.textContent = ind;
578
+ div.addEventListener('click', () => selectIndicator(ind));
579
+ indicatorSuggestions.appendChild(div);
580
+ });
581
+
582
+ indicatorSuggestions.classList.remove('hidden');
583
+ }
584
+
585
+ function selectIndicator(indicator) {
586
+ if (!selectedIndicatorList.includes(indicator)) {
587
+ selectedIndicatorList.push(indicator);
588
+ indicatorWeights[indicator] = 1; // Default weight
589
+ renderSelectedIndicators();
590
+ createWeightSlider(indicator);
591
+ }
592
+
593
+ indicatorSearch.value = '';
594
+ indicatorSuggestions.classList.add('hidden');
595
+ indicatorSearch.focus();
596
+ }
597
+
598
+ function renderSelectedIndicators() {
599
+ selectedIndicators.innerHTML = '';
600
+
601
+ selectedIndicatorList.forEach(ind => {
602
+ const chip = document.createElement('div');
603
+ chip.className = 'flex items-center bg-green-100 text-green-800 px-3 py-1 rounded-full text-sm indicator-chip';
604
+
605
+ const span = document.createElement('span');
606
+ span.textContent = ind;
607
+
608
+ const button = document.createElement('button');
609
+ button.className = 'ml-2 text-green-600 hover:text-green-900';
610
+ button.innerHTML = '<i class="fas fa-times"></i>';
611
+ button.addEventListener('click', () => removeIndicator(ind));
612
+
613
+ chip.appendChild(span);
614
+ chip.appendChild(button);
615
+ selectedIndicators.appendChild(chip);
616
+ });
617
+ }
618
+
619
+ function removeIndicator(indicator) {
620
+ selectedIndicatorList = selectedIndicatorList.filter(ind => ind !== indicator);
621
+ delete indicatorWeights[indicator];
622
+ renderSelectedIndicators();
623
+
624
+ // Remove corresponding slider
625
+ const sliderId = `weight-${indicator.replace(/\s+/g, '-')}`;
626
+ const sliderElement = document.getElementById(sliderId);
627
+ if (sliderElement) {
628
+ sliderElement.parentElement.remove();
629
+ }
630
+
631
+ // If no indicators left, show placeholder
632
+ if (selectedIndicatorList.length === 0) {
633
+ weightSliders.innerHTML = '<p class="text-gray-500 text-center py-4">Select indicators to enable weighting</p>';
634
+ }
635
+ }
636
+
637
+ function createWeightSlider(indicator) {
638
+ // Remove placeholder if it exists
639
+ if (weightSliders.querySelector('p')) {
640
+ weightSliders.innerHTML = '';
641
+ }
642
+
643
+ const sliderId = `weight-${indicator.replace(/\s+/g, '-')}`;
644
+
645
+ const sliderDiv = document.createElement('div');
646
+ sliderDiv.className = 'space-y-1';
647
+
648
+ const labelDiv = document.createElement('div');
649
+ labelDiv.className = 'flex justify-between';
650
+
651
+ const label = document.createElement('label');
652
+ label.className = 'text-sm text-gray-700';
653
+ label.textContent = indicator;
654
+ label.htmlFor = sliderId;
655
+
656
+ const valueSpan = document.createElement('span');
657
+ valueSpan.className = 'text-sm text-gray-700';
658
+ valueSpan.id = `${sliderId}-value`;
659
+ valueSpan.textContent = '1';
660
+
661
+ labelDiv.appendChild(label);
662
+ labelDiv.appendChild(valueSpan);
663
+
664
+ const slider = document.createElement('input');
665
+ slider.type = 'range';
666
+ slider.id = sliderId;
667
+ slider.className = 'w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer';
668
+ slider.min = '0';
669
+ slider.max = '5';
670
+ slider.step = '0.1';
671
+ slider.value = '1';
672
+
673
+ slider.addEventListener('input', function() {
674
+ const value = parseFloat(this.value).toFixed(1);
675
+ valueSpan.textContent = value;
676
+ indicatorWeights[indicator] = parseFloat(value);
677
+ });
678
+
679
+ sliderDiv.appendChild(labelDiv);
680
+ sliderDiv.appendChild(slider);
681
+ weightSliders.appendChild(sliderDiv);
682
+ }
683
+
684
+ function resetAllWeights() {
685
+ selectedIndicatorList.forEach(ind => {
686
+ indicatorWeights[ind] = 1;
687
+ const sliderId = `weight-${ind.replace(/\s+/g, '-')}`;
688
+ const slider = document.getElementById(sliderId);
689
+ if (slider) {
690
+ slider.value = '1';
691
+ document.getElementById(`${sliderId}-value`).textContent = '1';
692
+ }
693
+ });
694
+ }
695
+
696
+ function handleComponentSearch() {
697
+ const query = componentSearch.value.toLowerCase();
698
+ if (query.length < 2) {
699
+ componentSuggestions.classList.add('hidden');
700
+ return;
701
+ }
702
+
703
+ const matches = components.filter(comp =>
704
+ comp.toLowerCase().includes(query) &&
705
+ !selectedComponentList.includes(comp)
706
+ );
707
+
708
+ if (matches.length === 0) {
709
+ componentSuggestions.innerHTML = '<div class="px-4 py-2 text-gray-500">No matching components found</div>';
710
+ componentSuggestions.classList.remove('hidden');
711
+ return;
712
+ }
713
+
714
+ componentSuggestions.innerHTML = '';
715
+ matches.slice(0, 5).forEach(comp => {
716
+ const div = document.createElement('div');
717
+ div.className = 'px-4 py-2 hover:bg-gray-100 cursor-pointer';
718
+ div.textContent = comp;
719
+ div.addEventListener('click', () => selectComponent(comp));
720
+ componentSuggestions.appendChild(div);
721
+ });
722
+
723
+ componentSuggestions.classList.remove('hidden');
724
+ }
725
+
726
+ function selectComponent(component) {
727
+ if (!selectedComponentList.includes(component)) {
728
+ selectedComponentList.push(component);
729
+ renderComponentList();
730
+ }
731
+
732
+ componentSearch.value = '';
733
+ componentSuggestions.classList.add('hidden');
734
+ componentSearch.focus();
735
+ }
736
+
737
+ function renderComponentList() {
738
+ if (selectedComponentList.length === 0) {
739
+ componentList.innerHTML = '<p class="text-gray-500 text-center py-4">Search for components to compare</p>';
740
+ return;
741
+ }
742
+
743
+ componentList.innerHTML = '';
744
+
745
+ selectedComponentList.forEach(comp => {
746
+ const item = document.createElement
747
+ </html>