PageSourceSearch

https://openaccess.energy/pages/energypro-marketplace

html openaccess.energy collected 2026-10-08 22:20:14 UTC 92,294 bytes, 1,686 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en">
3<head>
4  <!-- Google tag (gtag.js) -->
vendor: 66 bytes, lines 4-5
4
5  <script async src="https://www.googletagmanager.com/gtag/js?id=
5G-LLRQX4VF7X
vendor: 14 bytes, lines 5-6
5"></script>
6  
6<script>
7    
vendor: 140 bytes, lines 7-11
7window.dataLayer = window.dataLayer || [];
8    function gtag(){dataLayer.push(arguments);}
9    gtag('js', new Date());
10
11    gtag('config', '
11G-LLRQX4VF7X
vendor: 6 bytes, lines 11-12
11');
12  
12</script>
12
13  
14  <meta charset="UTF-8">
15  <meta name="viewport" content="width=device-width, initial-scale=1.0">
16  <title>Energypro Marketplace - Open Access Energy</title>
17  <meta name="description" content="Energypro Marketplace helps large energy users procure renewable electricity efficiently, transparently, and without a formal tender process through our technology-driven platform.">
18  
19  <!-- Open Graph -->
20  <meta property="og:title" content="Energypro Marketplace - Open Access Energy">
21  <meta property="og:description" content="Energypro Marketplace helps large energy users procure renewable electricity efficiently, transparently, and without a formal tender process through our technology-driven platform.">
22  <meta property="og:type" content="website">
23  <meta property="og:url" content="https://openaccess.energy/pages/energypro-marketplace.html">
24  <meta property="og:image" content="https://openaccess.energy/src/images/mini%20hero/neon%20hands.jpg">
25  <meta property="og:image:width" content="1200">
26  <meta property="og:image:height" content="630">
27  <meta property="og:image:alt" content="Energypro Marketplace - Renewable Energy Procurement">
28  <meta property="og:site_name" content="Open Access Energy">
29  
30  <!-- Twitter Card -->
31  <meta name="twitter:card" content="summary_large_image">
32  <meta name="twitter:url" content="https://openaccess.energy/pages/energypro-marketplace.html">
33  <meta name="twitter:title" content="Energypro Marketplace - Open Access Energy">
34  <meta name="twitter:description" content="Energypro Marketplace helps large energy users procure renewable electricity efficie
34ntly, transparently, and without a formal tender process through our technology-driven platform.">
35  <meta name="twitter:image" content="https://openaccess.energy/src/images/mini%20hero/neon%20hands.jpg">
36  <meta name="twitter:image:alt" content="Energypro Marketplace - Renewable Energy Procurement">
37  
38  <!-- Favicon -->
39  <link rel="icon" type="image/png" href="/assets/favicon-COhEPEEa.png">
40  <link rel="shortcut icon" type="image/png" href="/assets/favicon-COhEPEEa.png">
41  <link rel="apple-touch-icon" href="/assets/apple-touch-icon-CwanEDBn.png">
42  
43  <!-- Styles -->
44  
45  <!-- Scripts -->
46  
47  <!-- Savings Calculator Alpine.js Component - Multi-Step Lead Form -->
48  
48<script>
49    document.addEventListener('alpine:init', () => {
50      Alpine.data('savingsCalculator', () => ({
51        modalOpen: false,
52        currentStep: 1,
53        isSubmitting: false,
54        submitError: null,
55        
56        // Step 2: Contact & Business Details
57        contactData: {
58          name: '',
59          role: '',
60          email: '',
61          industry: '',
62          provinces: [],
63          providers: [],
64          otherMunicipality: ''
65        },
66        
67        // Step 3: Consumption Data - Single Site Monthly
68        monthlyUsage: {
69          january: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
70          february: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
71          march: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
72          april: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
73          may: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
74          june: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
75          july: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
76          august: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
77          september: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
78          october: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
79          november: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
80          december: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false }
81        },
82        
83        // Step 3: Consumption Data - Multi-Site ZIP Upload
84        zipFile: null,
85        
86        // Step 3 Single-Site: 'manual' = enter kWh per month, 'file' = instructions only (user attaches file in email)
87        consumptionDataMode: 'manual',
88        
89        // Additional comments (both modes)
90        comments: '',
91        
92        // Validation errors
93        errors: {},
94        
95        // Dropdown options
96        industryOptions: [
97          { value: 'mining', label: 'Mining' },
98          { value: 'manufacturing', label: 'Manufacturing' },
99          { value: 'processing', label: 'Processing Plant' },
100          { value: 'data-centre', label: 'Data Centre' },
101          { value: 'retail', label: 'Retail' },
102          { value: 'hospitality', label: 'Hospitality' },
103          { value: 'agriculture', label: 'Agriculture' },
104          { value: 'cold-storage', label: 'Cold Storage / Logistics' },
105          { value: 'commercial-property', label: 'Commercial Property' },
106          { value: 'healthcare', label: 'Healthcare' },
107          { value: 'education', label: 'Education' },
108          { value: 'other', label: 'Other' }
109        ],
110        
111        provinceOptions: [
112          { value: 'eastern-cape', label: 'Eastern Cape' },
113          { value: 'free-state', label: 'Free State' },
114          { value: 'gauteng', label: 'Gauteng' },
115          { value: 'kwazulu-natal', label: 'KwaZulu-Natal' },
116          { value: 'limpopo', label: 'Limpopo' },
117          { value: 'mpumalanga', label: 'Mpumalanga' },
118          { value: 'north-west', label: 'North West' },
119          { value: 'northern-cape', label: 'Northern Cape' },
120          { value: 'western-cape', label: 'Western Cape' }
121        ],
122        
123        providerOptions: [
124          { value: 'eskom', label: 'Eskom' },
125          { value: 'city-of-cape-town', label: 'City of Cape Town' },
126          { value: 'city-power', label: 'City of Johannesburg (City Power)' },
127          { value: 'city-of-tshwane', label: 'City of Tshwane' },
128          { value: 'ethekwini', label: 'eThekwini Municipality' },
129          { value: 'nelson-mandela-bay', label: 'Nelson Mandela Bay Municipality' },
130          { value: 'other-municipality', label: 'Other Municipality' }
131        ],
132        
133        months: ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'],
134        
135        // Computed: Check if bulk upload is required (multiple provinces OR multiple providers)
136        get requiresBulkUpload() {
137          return this.contactData.provinces.length > 1 || this.contactData.providers.length > 1
138        },
139        
140        // Check if "Other Municipality" is selected
141        get showOtherMunicipalityInput() {
142          return this.contactData.providers.includes('other-municipality')
143        },
144        
145        init() {
146          window.addEventListener('open-calculator', () => {
147            this.modalOpen = true
148            this.currentStep = 1
149          })
150        },
151        
152        closeModal() {
153          this.modalOpen = false
154          this.currentStep = 1
155          this.resetForm()
156        },
157        
158        resetForm() {
159          this.contactData = {
160            name: '',
161            role: '',
162            email: '',
163            industry: '',
164            provinces: [],
165            providers: [],
166            otherMunicipality: ''
167          }
168          this.monthlyUsage = {
169            january: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
170            february: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
171            march: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
172            april: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
173            may: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
174            june: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
175            july: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
176            august: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
177            september: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
178            october: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
179            november: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false },
180            december: { peak: '', standard: '', offpeak: '', billFile: null, useUpload: false }
181          }
182          this.zipFile = null
183          this.comments = ''
184          this.consumptionDataMode = 'manual'
185          this.errors = {}
186          this.submitError = null
187          this.isSubmitting = false
188        },
189        
190        nextStep() {
191          if (this.validateStep(this.currentStep)) {
192            this.currentStep++
193          }
194        },
195        
196        prevStep() {
197          if (this.currentStep > 1) {
198            this.currentStep--
199          }
200        },
201        
202        validateStep(step) {
203          this.errors = {}
204          
205          if (step === 2) {
206            if (!this.contactData.name.trim()) {
207              this.errors.name = 'Please enter your full name'
208            }
209            if (!this.contactData.role.trim()) {
210              this.errors.role = 'Please enter your role or job title'
211            }
212            if (!this.contactData.email.trim()) {
213              this.errors.email = 'Please enter your email address'
214            } else if (!this.isValidEmail(this.contactData.email)) {
215              this.errors.email = 'Please enter a valid email address'
216            }
217            if (this.contactData.provinces.length === 0) {
218              this.errors.provinces = 'Please select at least one province'
219            }
220            if (this.contactData.providers.length === 0) {
221              this.errors.providers = 'Please select your bill provider'
222            }
223            // Validate "Other Municipality" text input if selected
224            if (this.contactData.providers.includes('other-municipality') && !this.contactData.otherMunicipality.trim()) {
225              this.errors.otherMunicipality = 'Please specify your municipality'
226            }
227          }
228          
229          if (step === 3) {
230            if (this.requiresBulkUpload) {
231              if (!this.zipFile) {
232                this.errors.zipFile = 'Please upload a ZIP file containing your bills'
233              }
234            } else {
235              if (this.consumptionDataMode === 'file') {
236                // No file required – user attaches in their email client
237              } else {
238                // Manual: require kWh for all 12 months
239                let monthsWithData = 0
240                for (const month of this.months) {
241                  const data = this.monthlyUsage[month]
242                  if (data.peak && data.standard && data.offpeak) {
243                    monthsWithData++
244                  }
245                }
246                if (monthsWithData < 12) {
247                  this.errors.monthlyData = `Please provide data for all 12 months (${monthsWithData}/12 completed)`
248                }
249              }
250            }
251          }
252          
253          return Object.keys(this.errors).length === 0
254        },
255        
256        isValidEmail(email) {
257          return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)
258        },
259        
260        toggleProvinceSelection(value) {
261          const index = this.contactData.provinces.indexOf(value)
262          if (index > -1) {
263            this.contactData.provinces.splice(index, 1)
264          } else {
265            this.contactData.provinces.push(value)
266          }
267        },
268        
269        toggleProviderSelection(value) {
270          const index = this.contactData.providers.indexOf(value)
271          if (index > -1) {
272            this.contactData.providers.splice(index, 1)
273            // Clear other municipality text if deselected
274            if (value === 'other-municipality') {
275              this.contactData.otherMunicipality = ''
276            }
277          } else {
278            this.contactData.providers.push(value)
279          }
280        },
281        
282        handleZipFileUpload(event) {
283          const file = event.target.files[0]
284          if (!file) return
285          
286          // Validate file type
287          if (!file.name.toLowerCase().endsWith('.zip')) {
288            alert('Please upload a ZIP file.')
289            event.target.value = ''
290            return
291          }
292          
293          // Validate file size (4MB max for email attachment)
294          if (file.size > 4 * 1024 * 1024) {
295            alert('File exceeds 4MB limit for email attachment. Please compress your file or email it separately to jared@open
295access.energy')
296            event.target.value = ''
297            return
298          }
299          
300          this.zipFile = file
301          event.target.value = ''
302        },
303        
304        removeZipFile() {
305          this.zipFile = null
306        },
307        
308        formatFileSize(bytes) {
309          if (bytes < 1024) return bytes + ' B'
310          if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'
311          return (bytes / (1024 * 1024)).toFixed(1) + ' MB'
312        },
313        
314        capitalise(str) {
315          return str.charAt(0).toUpperCase() + str.slice(1)
316        },
317        
318        getProvincesLabel() {
319          if (this.contactData.provinces.length === 0) return ''
320          return this.contactData.provinces.map(p => {
321            const opt = this.provinceOptions.find(o => o.value === p)
322            return opt ? opt.label : p
323          }).join(', ')
324        },
325        
326        getProvidersLabel() {
327          if (this.contactData.providers.length === 0) return ''
328          return this.contactData.providers.map(p => {
329            if (p === 'other-municipality' && this.contactData.otherMunicipality) {
330              return `Other: ${this.contactData.otherMunicipality}`
331            }
332            const opt = this.providerOptions.find(o => o.value === p)
333            return opt ? opt.label : p
334          }).join(', ')
335        },
336        
337        submitForm() {
338          if (!this.validateStep(3)) return
339          
340          this.isSubmitting = true
341          this.submitError = null
342          
343          const hasFiles = this.requiresBulkUpload ? this.zipFile !== null : 
344            (this.consumptionDataMode === 'file')
345          
346          this.hasFilesToAttach = hasFiles
347          this.fileAttachmentList = this.getFileList()
348          
349          if (window.GATracker) {
350            window.GATracker.trackFormSubmit('Savings Calculator', {
351              industry: this.contactData.industry,
352              provinces: this.contactData.provinces.length,
353              has_files: hasFiles
354            })
355            window.GATracker.trackLead('Savings Calculator', {
356              form_type: 'savings_calculator',
357              industry: this.contactData.industry,
358              provinces: this.contactData.provinces.length
359            })
360          }
361          
362          // Mailto only - opens email client with pre-filled body (user attaches files manually)
363          this.fallbackToMailto()
364          // Defer UI update so mailto dialog opens first and avoids white flash
365          requestAnimationFrame(() => {
366            this.currentStep = 4
367            this.isSubmitting = false
368          })
369        },
370        
371        fallbackToMailto() {
372          const subject = encodeURIComponent(`Savings Calculator Request - ${this.contactData.name}`)
373          const body = encodeURIComponent(this.buildEmailBody())
374          const mailtoUrl = `mailto:[email protected]?subject=${subject}&body=${body}`
375          if (typeof window.openMailto === 'function') {
376            window.openMailto(mailtoUrl)
377          } else {
378            window.open(mailtoUrl, '_blank')
379          }
380        },
381        
382        getFileList() {
383          const files = []
384          if (this.requiresBulkUpload && this.zipFile) {
385            files.push(this.zipFile.name)
386          }
387          // Single-site file mode: no file selected in wizard, user attaches in email
388          return files
389        },
390        
391        hasFilesToAttach: false,
392        fileAttachmentList: [],
393        
394        buildEmailBody() {
395          let body = `SAVINGS CALCULATOR SUBMISSION\n${'='.repeat(40)}\n\n`
396          
397          body += `CONTACT DETAILS\n${'-'.repeat(20)}\n`
398          body += `Name: ${this.contactData.name}\n`
399          body += `Role: ${this.contactData.role}\n`
400          body += `Email: ${this.contactData.email}\n`
401          body += `Industry: ${this.contactData.industry || 'Not specified'}\n\n`
402          
403          body += `LOCATION & PROVIDER\n${'-'.repeat(20)}\n`
404          body += `Province(s): ${this.getProvincesLabel()}\n`
405          body += `Bill Provider(s): ${this.getProvidersLabel()}\n\n`
406          
407          body += `CONSUMPTION DATA\n${'-'.repeat(20)}\n`
408          
409          if (this.requiresBulkUpload) {
410            body += `Submission Type: Multi-site (ZIP upload)\n`
411            if (this.zipFile) {
412              body += `ZIP file to attach: ${this.zipFile.name}
412 (${this.formatFileSize(this.zipFile.size)})\n`
413            }
414          } else if (this.consumptionDataMode === 'file') {
415            body += `Submission Type: Single-site (file)\n`
416            body += `User will attach consumption data file(s) when sending this email.\n`
417          } else {
418            body += `Submission Type: Single-site (monthly data)\n\n`
419            for (const month of this.months) {
420              const data = this.monthlyUsage[month]
421              if (data.peak && data.standard && data.offpeak) {
422                body += `${this.capitalise(month)}: Peak ${data.peak} kWh, Standard ${data.standard} kWh, Offpeak ${data.offpeak} kWh\n`
423              }
424            }
425          }
426          
427          body += `\nADDITIONAL COMMENTS\n${'-'.repeat(20)}\n`
428          body += this.comments.trim() || 'None provided'
429          
430          body += `\n\n${'-'.repeat(40)}\n`
431          body += `Submitted via Energypro Marketplace Savings Calculator\n`
432          body += `Date: ${new Date().toLocaleString('en-ZA')}`
433          
434          return body
435        }
436      }))
437    })
438  </script>
438
439  
440  <!-- Preload fonts -->
441  <link rel="preconnect" href="https://fonts.googleapis.com">
442  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
443  
443<script type="module" crossorigin src="/assets/main-Dzhg-eiR.js"></script>
443
444  <link rel="stylesheet" crossorigin href="/assets/main-Bi2TgnkB.css">
445</head>
446<body x-data="app" x-init="init()" class="antialiased">
447  
448  <!-- Header Include -->
449  <div data-include="/src/includes/header.html"></div>
450
451  <!-- Hero Section -->
452  <section class="hero-section min-h-[60vh] flex items-center relative overflow-hidden">
453    <!-- Background Image -->
454    <div class="absolute inset-0">
455      <img src="/assets/neon%20hands-ioC3RgDc.jpg" alt="Energypro Marketplace - Renewable Energy Procurement" class="w-full h-full object-cover" style="object-position: center 35%;">
456      <div class="absolute inset-0 bg-gradient-to-br from-dark-navy/60 via-primary-blue/50 to-blue-800/60"></div>
457    </div>
458    
459    <!-- Content -->
460    <div class="container-custom relative z-10">
461      <div class="max-w-4xl mx-auto text-center">
462        <div class="animate-on-scroll">
463          <h1 class="text-4xl md:text-5xl lg:text-6xl font-heading font-bold text-white mb-6 leading-tight">
464            Energypro Marketplace
465          </h1>
466        </div>
467        
468        <div class="animate-on-scroll" style="animation-delay: 0.2s;">
469          <p class="text-xl md:text-2xl text-blue-100 mb-8 leading-relaxed max-w-3xl mx-auto">
470            Helping large energy users procure renewable electricity efficie
470ntly, transparently, and without a formal tender process.
471          </p>
472        </div>
473
474        <!-- CTA Buttons -->
475        <div class="animate-on-scroll flex flex-col sm:flex-row gap-4 justify-center" style="animation-delay: 0.4s;">
476          <a href="/public/Buyers Programme.pdf" download="Buyers-Programme-Brochure.pdf" class="btn-secondary border-2 border-white text-white hover:bg-white hover:text-primary-blue text-lg px-8 py-4 inline-flex items-center justify-center">
477            <svg class="mr-2 w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
478              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v2a2 2 0 002 2h12a2 2 0 002-2v-2M7 10l5 5 5-5M12 4v12"></path>
479            </svg>
480            Download Brochure
481          </a>
482          <button 
483            @click="window.dispatchEvent(new CustomEvent('open-calculator'))"
484            class="btn-primary bg-white text-primary-blue hover:bg-gray-100 text-lg px-8 py-4 inline-flex items-center justify-center"
485          >
486            <svg class="mr-2 w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
487              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 7h6m0 10v-3m-3 3h.01M9 17h.01M9 14h.01M12 14h.01M15 11h.01M12 11h.01M9 11h.01M7 21h10a2 2 0 002-2V5a2 2 0 00-2-2H7a2 2 0 00-2 2v14a2 2 0 002 2z"></path>
488            </svg>
489            Calculate my Savings
490          </button>
491        </div>
492      </div>
493    </div>
494  </section>
495
496  <!-- Savings Calculator Modal - Multi-Step Lead Form -->
497  <div 
498    x-data="savingsCalculator()"
499    x-show="modalOpen"
500    x-transition:enter="transition ease-out duration-300"
501    x-transition:enter-start="opacity-0"
502    x-transition:enter-end="opacity-100"
503    x-transition:leave="transition ease-in duration-200"
504    x-transition:leave-start="opacity-100"
505    x-transition:leave-end="opacity-0"
506    class="fixed inset-0 z-50 overflow-y-auto"
507    style="display: none;"
508    role="dialog"
509    aria-modal="true"
510    aria-labelledby="modal-title"
511  >
512    <!-- Backdrop -->
513    <div class="fixed inset-0 bg-black/50 backdrop-blur-sm" @click="closeModal()"></div>
514    
515    <!-- Modal Container -->
516    <div class="flex min-h-full items-center justify-center p-4">
517      <div 
518        @click.away=""
519        class="relative bg-white rounded-2xl shadow-2xl w-full max-w-4xl max-h-[90vh] overflow-y-auto"
520        x-transition:enter="transition ease-out duration-300"
521        x-transition:enter-start="opacity-0 transform scale-95"
522        x-transition:enter-end="opacity-100 transform scale-100"
523        x-transition:leave="transition ease-in duration-200"
524        x-transition:leave-start="opacity-100 transform scale-100"
525        x-transition:leave-end="opacity-0 transform scale-95"
526      >
527        <!-- Close Button -->
528        <button 
529          @click="closeModal()"
530          class="absolute top-4 right-4 z-10 p-2 text-dark-gray hover:text-primary-blue transition-colors rounded-full hover:bg-light-gray"
531          aria-label="Close modal"
532        >
533          <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
534            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
535          </svg>
536        </button>
537
538        <!-- Step Progress Indicator -->
539        <div class="px-6 md:px-8 pt-6 pb-4" x-show="currentStep < 4">
540          <div class="flex items-center justify-center space-x-2 md:space-x-4">
541            <template x-for="step in [1, 2, 3]" :key="step">
542              <div class="flex items-center">
543                <div 
544                  class="w-8 h-8 rounded-full flex items-center justify-center text-sm font-semibold transition-all duration-300"
545                  :class="currentStep >= step ? 'bg-primary-blue text-white' : 'bg-light-gray text-dark-gray'"
546                >
547                  <span x-text="step"></span>
548                </div>
549                <div 
550                  x-show="step < 3"
551                  class="w-8 md:w-16 h-1 mx-2 rounded transition-all duration-300"
552                  :class="currentStep > step ? 'bg-primary-blue' : 'bg-light-gray'"
553                ></div>
554              </div>
555            </template>
556          </div>
557          <div class="flex justify-center mt-2">
558            <p class="text-xs text-dark-gray">
559              <span x-show="currentStep === 1">About Wheeling</span>
560              <span x-show="currentStep === 2">Your Details</span>
561              <span x-show="currentStep === 3">Consumption Data</span>
562            </p>
563          </div>
564        </div>
565
566        <!-- Modal Content -->
567        <div class="p-6 md:p-8 pt-2">
568          
569          <!-- ==================== STEP 1: Value Proposition ==================== -->
570          <div x-show="currentStep === 1" x-transition:enter="transition ease-out duration-300" x-transition:enter-start="opacity-0 transform translate-x-4" x-transition:enter-end="opacity-100 transform translate-x-0">
571            <div class="text-center mb-8">
572              <h2 id="modal-title" class="text-2xl md:text-3xl font-heading font-bold text-dark-navy mb-3">
573                Unlock Your Energy Savings
574              </h2>
575              <p class="text-lg text-dark-gray">
576                Discover how wheeling can reduce your electricity costs
577              </p>
578            </div>
579
580            <!-- Wheeling Explainer -->
581            <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
582              <!-- What is Wheeling -->
583              <div class="bg-light-gray rounded-xl p-6 text-center">
584                <div class="w-16 h-16 bg-gradient-to-br from-primary-blue to-cta-blue rounded-full flex items-center justify-center mx-auto mb-4">
585                  <svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
586                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
587                  </svg>
588                </div>
589                <h3 class="font-heading font-bold text-dark-navy mb-2">What is Wheeling?</h3>
590                <p class="text-sm text-dark-gray leading-relaxed">
591                  Wheeling allows you to purchase renewable energy from independent power producers and have it delivered through the existing grid.
592                </p>
593              </div>
594
595              <!-- How You Save -->
596              <div class="bg-light-gray rounded-xl p-6 text-center">
597                <div class="w-16 h-16 bg-gradient-to-br from-accent-green to-green-600 rounded-full flex items-center justify-center mx-auto mb-4">
598                  <svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
599                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
600                  </svg>
601                </div>
602                <h3 class="font-heading font-bold text-dark-navy mb-2">
602How You Save</h3>
603                <p class="text-sm text-dark-gray leading-relaxed">
604                  By sourcing energy through the Energypro Marketplace, you access competitive rates below standard utility tariffs.
605                </p>
606              </div>
607
608              <!-- The OAE Advantage -->
609              <div class="bg-light-gray rounded-xl p-6 text-center">
610                <div class="w-16 h-16 bg-gradient-to-br from-secondary-gold to-yellow-500 rounded-full flex items-center justify-center mx-auto mb-4">
611                  <svg class="w-8 h-8 text-dark-navy" fill="none" stroke="currentColor" viewBox="0 0 24 24">
612                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4M7.835 4.697a3.42 3.42 0 001.946-.806 3.42 3.42 0 014.438 0 3.42 3.42 0 001.946.806 3.42 3.42 0 013.138 3.138 3.42 3.42 0 00.806 1.946 3.42 3.42 0 010 4.438 3.42 3.42 0 00-.806 1.946 3.42 3.42 0 01-3.138 3.138 3.42 3.42 0 00-1.946.806 3.42 3.42 0 01-4.438 0 3.42 3.42 0 00-1.946-.806 3.42 3.42 0 01-3.138-3.138 3.42 3.42 0 00-.806-1.946 3.42 3.42 0 010-4.438 3.42 3.42 0 00.806-1.946 3.42 3.42 0 013.138-3.138z"></path>
613                  </svg>
614                </div>
615                <h3 class="font-heading font-bold text-dark-navy mb-2">The OAE Advantage</h3>
616                <p class="text-sm text-dark-gray leading-relaxed">
617                  We handle the complexity—from supplier matching to billing management—while you enjoy the savings.
618                </p>
619              </div>
620            </div>
621
622            <!-- CTA Button -->
623            <div class="flex justify-center">
624              <button 
625                @click="nextStep()"
626                class="btn-primary text-lg px-10 py-4 inline-flex items-center justify-center"
627              >
628                Get Started
629                <svg class="ml-2 w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
630                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"></path>
631                </svg>
632              </button>
633            </div>
634          </div>
635
636          <!-- ==================== STEP 2: Contact & Business Details ==================== -->
637          <div x-show="currentStep === 2" x-transition:enter="transition ease-out duration-300" x-transition:enter-start="opacity-0 transform translate-x-4" x-transition:enter-end="opacity-100 transform translate-x-0">
638            <div class="text-center mb-6">
639              <h2 class="text-xl md:text-2xl font-heading font-bold text-dark-navy mb-2">
640                Tell Us About Yourself
641              </h2>
642              <p class="text-dark-gray">
643                We'll use this information to prepare your personalised savings proposal
644              </p>
645            </div>
646
647            <form @submit.prevent="nextStep()" class="space-y-4">
648              <!-- Contact Details -->
649              <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
650                <!-- Name -->
651                <div>
652                  <label for="contact-name" class="block text-sm font-semibold text-dark-gray mb-2">
653                    Full Name <span class="text-red-500">*</span>
654                  </label>
655                  <input 
656                    type="text"
657                    id="contact-name"
658                    x-model="contactData.name"
659                    placeholder="Enter your full name"
660                    class="w-full px-4 py-3 border rounded-lg focus:ring-2 focus:ring-primary-blue focus:border-primary-blue outline-none bg-white text-dark-gray"
661                    :class="errors.name ? 'border-red-500' : 'border-medium-gray'"
662                  />
663                  <p x-show="errors.name" x-text="errors.name" class="text-red-500 text-xs mt-1"></p>
664                </div>
665
666                <!-- Role -->
667                <div>
668                  <label for="contact-role" class="block text-sm font-semibold text-dark-gray mb-2">
669                    Role / Job Title <span class="text-red-500">*</span>
670                  </label>
671                  <input 
672                    type="text"
673                    id="contact-role"
674                    x-model="contactData.role"
675                    placeholder="e.g. Energy Manager, CFO, Operations Director"
676                    class="w-full px-4 py-3 border rounded-lg focus:ring-2 focus:ring-primary-blue focus:border-primary-blue outline-none bg-white text-dark-gray"
677                    :class="errors.role ? 'border-red-500' : 'border-medium-gray'"
678                  />
679                  <p x-show="errors.role" x-text="errors.role" class="text-red-500 text-xs mt-1"></p>
680                </div>
681              </div>
682
683              <!-- Email and Industry Row -->
684              <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
685                <div>
686                  <label for="contact-email" class="block text-sm font-semibold text-dark-gray mb-2">
687                    Email Address <span class="text-red-500">*</span>
688                  </label>
689                  <input 
690                    type="email"
691                    id="contact-email"
692                    x-model="contactData.email"
693                    placeholder="[email protected]"
694                    class="w-full px-4 py-3 border rounded-lg focus:ring-2 focus:ring-primary-blue focus:border-primary-blue outline-none bg-white text-dark-gray"
695                    :class="errors.email ? 'border-red-500' : 'border-medium-gray'"
696                  />
697                  <p x-show="errors.email" x-text="errors.email" class="text-red-500 text-xs mt-1"></p>
698                </div>
699
700                <!-- Industry -->
701                <div>
702                  <label for="contact-industry" class="block text-sm font-semibold text-dark-gray mb-2">
703                    Industry <span class="text-dark-gray/50">(optional)</span>
704                  </label>
705                  <select 
706                    id="contact-industry"
707                    x-model="contactData.industry"
708                    class="w-full px-4 py-3 border border-medium-gray rounded-lg focus:ring-2 focus:ring-primary-blue focus:border-primary-blue outline-none bg-white text-dark-gray"
709                  >
710                    <option value="">Select your industry</option>
711                    <template x-for="opt in industryOptions" :key="opt.value">
712                      <option :value="opt.value" x-text="opt.label"></option>
713                    </template>
714                  </select>
715                </div>
716              </div>
717
718              <!-- Province and Provider Row -->
719              <div class="grid grid-cols-1 md:grid-cols-2 gap-4 pt-4 border-t border-medium-gray/30">
720                <!-- Province(s) Multi-Select -->
721                <div x-data="{ provinceDropdownOpen: false, openUpward: false }" x-init="$watch('provinceDropdownOpen', (open) => { if (open) { const rect = $refs.provinceBtn.getBoundingClientRect(); openUpward = (window.innerHeight - rect.bottom) < 400; } })">
722                  <label class="block text-sm font-semibold text-dark-gray mb-2">
723                    Province(s) <span class="text-red-500">*</span>
724                  </label>
725                  <div class="relative">
726                    <button 
727                      type="button"
728                      x-ref="provinceBtn"
729                      @click="provinceDropdownOpen = !provinceDropdownOpen"
730                      @click.away="provinceDropdownOpen = false"
731                      class="w-full px-4 py-3 border rounded-lg focus:ring-2 focus:ring-primary-blue focus:border-primary-blue outline-none bg-white text-dark-gray text-left flex items-center justify-between"
732                      :class="errors.provinces ? 'border-red-500' : 'border-medium-gray'"
733                    >
734                      <span x-text="contactData.provinces.length > 0 ? contactData.provinces.length + ' selected' : 'Select province(s)'" class="truncate" :class="contactData.provinces.length === 0 ? 'text-gray-400' : ''"></span>
735                      <svg class="w-5 h-5 text-gray-400 flex-shrink-0 transition-transform" :class="provinceDropdownOpen ? 'rotate-180' : ''" fill="none" stroke="currentColor" viewBox="0 0 24 24">
736                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
737                      </svg>
738                    </button>
739                    <div 
740                      x-show="provinceDropdownOpen"
741                      x-transition
742                      class="absolute z-20 w-full bg-white border border-medium-gray rounded-lg shadow-lg"
743                      :class="openUpward ? 'bottom-full mb-1' : 'top-full mt-1'"
744                    >
745                      <template x-for="opt in provinceOptions" :key="opt.value">
746                        <label 
747                          class="flex items-center px-4 py-2 hover:bg-light-gray cursor-pointer"
748                          :class="contactData.provinces.includes(opt.value) ? 'bg-primary-blue/5' : ''"
749                        >
750                          <input 
751                            type="checkbox"
752                            :checked="contactData.provinces.includes(opt.value)"
753                            @change="toggleProvinceSelection(opt.value)"
754                            class="w-4 h-4 text-primary-blue border-medium-gray rounded focus:ring-primary-blue"
755                          />
756                          <span class="ml-2 text-sm text-dark-gray" x-text="opt.label"></span>
757                        </label>
758                      </template>
759                    </div>
760                  </div>
761                  <p x-show="errors.provinces" x-text="errors.provinces" class="text-red-500 text-xs mt-1"></p>
762                </div>
763
764                <!-- Provider(s) Multi-Select -->
765                <div x-data="{ providerDropdownOpen: false, openUpward: false }" x-init="$watch('providerDropdownOpen', (open) => { if (open) { const rect = $refs.providerBtn.getBoundingClientRect(); openUpward = (window.innerHeight - rect.bottom) < 320; } })">
766                  <label class="block text-sm font-semibold text-dark-gray mb-2">
767                    Bill Provider(s) <span class="text-red-500">*</span>
768                  </label>
769                  <div class="relative">
770                    <button 
771                      type="button"
772                      x-ref="providerBtn"
773                      @click="providerDropdownOpen = !providerDropdownOpen"
774                      @click.away="providerDropdownOpen = false"
775                      class="w-full px-4 py-3 border rounded-lg focus:ring-2 focus:ring-primary-blue focus:border-primary-blue outline-none bg-white text-dark-gray text-left flex items-center justify-between"
776                      :class="errors.providers ? 'border-red-500' : 'border-medium-gray'"
777                    >
778                      <span x-text="contactData.providers.length > 0 ? contactData.providers.length + ' selected' : 'Select provider(s)'" class="truncate" :class="contactData.providers.length === 0 ? 'text-gray-400' : ''"></span>
779                      <svg class="w-5 h-5 text-gray-400 flex-shrink-0 transition-transform" :class="providerDropdownOpen ? 'rotate-180' : ''" fill="none" stroke="currentColor" viewBox="0 0 24 24">
780                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
781                      </svg>
782                    </button>
783                    <div 
784                      x-show="providerDropdownOpen"
785                      x-transition
786                      class="absolute z-20 w-full bg-white border border-medium-gray rounded-lg shadow-lg"
787                      :class="openUpward ? 'bottom-full mb-1' : 'top-full mt-1'"
788                    >
789                      <template x-for="opt in providerOptions" :key="opt.value">
790                        <label 
791                          class="flex items-center px-4 py-2 hover:bg-light-gray cursor-pointer"
792                          :class="contactData.providers.includes(opt.value) ? 'bg-primary-blue/5' : ''"
793                        >
794                          <input 
795                            type="checkbox"
796                            :checked="contactData.providers.includes(opt.value)"
797                            @change="toggleProviderSelection(opt.value)"
798                            class="w-4 h-4 text-primary-blue border-medium-gray rounded focus:ring-primary-blue"
799                          />
800                          <span class="ml-2 text-sm text-dark-gray" x-text="opt.label"></span>
801                        </label>
802                      </template>
803                    </div>
804                  </div>
805                  <p x-show="errors.providers" x-text="errors.providers" class="text-red-500 text-xs mt-1"></p>
806                </div>
807              </div>
808
809              <!-- Other Municipality Input -->
810              <div x-show="showOtherMunicipalityInput" x-transition>
811                <label for="other-municipality" class="block text-sm font-semibold text-dark-gray mb-2">
812                  Please specify municipality name <span class="text-red-500">*</span>
813                </label>
814                <input 
815                  type="text"
816                  id="other-municipality"
817                  x-model="contactData.otherMunicipality"
818                  placeholder="Enter municipality name"
819                  class="w-full px-4 py-3 border rounded-lg focus:ring-2 focus:ring-primary-blue focus:border-primary-blue outline-none bg-white text-dark-gray"
820                  :class="errors.otherMunicipality ? 'border-red-500' : 'border-medium-gray'"
821                />
822                <p x-show="errors.otherMunicipality" x-text="errors.otherMunicipality" class="text-red-500 text-xs mt-1"></p>
823              </div>
824
825              <!-- Navigation Buttons -->
826              <div class="flex justify-between pt-4">
827                <button 
828                  type="button"
829                  @click="prevStep()"
830                  class="btn-secondary border-2 border-medium-gray text-dark-gray hover:bg-light-gray px-6 py-3 inline-flex items-center justify-center"
831                >
832                  <svg class="mr-2 w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
833                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16l-4-4m0 0l4-4m-4 4h18"></path>
834                  </svg>
835                  Back
836                </button>
837                <button 
838                  type="submit"
839                  class="btn-primary px-8 py-3 inline-flex items-center justify-center"
840                >
841                  Next
842                  <svg class="ml-2 w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
843                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"></path>
844                  </svg>
845                </button>
846              </div>
847            </form>
848          </div>
849
850          <!-- ==================== STEP 3: Consumption Data ==================== -->
851          <div x-show="currentStep === 3" x-transition:enter="transition ease-out duration-300" x-transition:enter-start="opacity-0 transform translate-x-4" x-transition:enter-end="opacity-100 transform translate-x-0">
852            
853            <!-- Single Site Mode -->
854            <div x-show="!requiresBulkUpload">
855              <div class="text-center mb-6">
856                <h2 class="text-xl md:text-2xl font-heading font-bold text-dark-navy mb-2">
857                  Your Monthly Consumption
858                </h2>
859                <p class="text-dark-gray mb-4">
860                  Choose how you'd like to share your consumption data:
861                </p>
862              </div>
863
864              <!-- Two options: Manual entry OR Share a file -->
865              <div class="flex flex-col sm:flex-row gap-3 mb-6">
866                <button 
867                  type="button"
868                  @click="consumptionDataMode = 'manual'"
869                  class="flex-1 px-4 py-4 rounded-xl border-2 text-left transition-all"
870                  :class="consumptionDataMode === 'manual' ? 'border-primary-blue bg-primary-blue/10 text-dark-navy font-semibold' : 'border-medium-gray bg-white text-dark-gray hover:border-primary-blue/50'"
871                >
872                  <span class="flex items-center">
873                    <span class="w-8 h-8 rounded-full flex items-center justify-center mr-3 flex-shrink-0" :class="consumptionDataMode === 'manual' ? 'bg-primary-blue text-white' : 'bg-light-gray text-dark-gray'">
874                      <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
875                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 7h6m0 10v-3m-3 3h.01M9 17h.01M9 14h.01M12 14h.01M15 11h.01M12 11h.01M9 11h.01M7 21h10a2 2 0 002-2V5a2 2 0 00-2-2H7a2 2 0 00-2 2v14a2 2 0 002 2z"></path>
876                      </svg>
877                    </span>
878                    <span>
879                      <span class="block font-semibold text-dark-navy">Enter data manually</span>
880                      <span class="block text-sm text-dark-gray/80 mt-0.5">Type Peak, Standard &amp; Offpeak kWh for each of the 12 months</span>
881                    </span>
882                  </span>
883                </button>
884                <button 
885                  type="button"
886                  @click="consumptionDataMode = 'file'"
887                  class="flex-1 px-4 py-4 rounded-xl border-2 text-left transition-all"
888                  :class="consumptionDataMode === 'file' ? 'border-primary-blue bg-primary-blue/10 text-dark-navy font-semibold' : 'border-medium-gray bg-white text-dark-gray hover:border-primary-blue/50'"
889                >
890                  <span class="flex items-center">
891                    <span class="w-8 h-8 rounded-full flex items-center justify-center mr-3 flex-shrink-0" :class="consumptionDataMode === 'file' ? 'bg-primary-blue text-white' : 'bg-light-gray text-dark-gray'">
892                      <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
893                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
894                      </svg>
895                    </span>
896                    <span>
897                      <span class="block font-semibold text-dark-navy">I'll share a file</span>
898                      <span class="block text-sm text-dark-gray/80 mt-0.5">We'll prepare an email; you attach your file when you send it</span>
899                    </span>
900                  </span>
901                </button>
902              </div>
903
904              <!-- Option A: Manual entry – 12-month table (no upload column) -->
905              <div x-show="consumptionDataMode === 'manual'" class="mb-6">
906                <p class="text-sm text-dark-gray mb-3">Enter kWh for each time-of-use (TOU) band per month:</p>
907                <div class="overflow-x-auto">
908                  <table class="w-full text-sm">
909                    <thead>
910                      <tr class="bg-light-gray">
911                        <th class="text-left p-3 font-semibold text-dark-navy rounded-tl-lg">Month</th>
912                        <th class="text-center p-3 font-semibold text-dark-navy">Peak (kWh)</th>
913                        <th class="text-center p-3 font-semibold text-dark-navy">Standard (kWh)</th>
914                        <th class="text-center p-3 font-semibold text-dark-navy rounded-tr-lg">Offpeak (kWh)</th>
915                      </tr>
916                    </thead>
917                    <tbody>
918                      <template x-for="month in months" :key="month">
919                        <tr class="border-b border-medium-gray/30">
920                          <td class="p-2 font-medium text-dark-navy" x-text="capitalise(month)"></td>
921                          <td class="p-2">
922                            <input 
923                              type="number"
924                              x-model="monthlyUsage[month].peak"
925                              placeholder="0"
926                              step="0.01"
927                              min="0"
928                              class="w-full px-2 py-2 text-center border border-medium-gray rounded focus:ring-1 focus:ring-primary-blue focus:border-primary-blue outline-none"
929                            />
930                          </td>
931                          <td class="p-2">
932                            <input 
933                              type="number"
934                              x-model="monthlyUsage[month].standard"
935                              placeholder="0"
936                              step="0.01"
937                              min="0"
938                              class="w-full px-2 py-2 text-center border border-medium-gray rounded focus:ring-1 focus:ring-primary-blue focus:border-primary-blue outline-none"
939                            />
940                          </td>
941                          <td class="p-2">
942                            <input 
943                              type="number"
944                              x-model="monthlyUsage[month].offpeak"
945                              placeholder="0"
946                              step="0.01"
947                              min="0"
948                              class="w-full px-2 py-2 text-center border border-medium-gray rounded focus:ring-1 focus:ring-primary-blue focus:border-primary-blue outline-none"
949                            />
950                          </td>
951                        </tr>
952                      </template>
953                    </tbody>
954                  </table>
955                </div>
956                <p x-show="errors.monthlyData" x-text="errors.monthlyData" class="text-red-500 text-sm mt-3 text-center"></p>
957              </div>
958
959              <!-- Option B: Share a file – instructions only; user attaches file in their email client -->
960              <div x-show="consumptionDataMode === 'file'" class="mb-6">
961                <div class="bg-light-gray rounded-xl p-5">
962                  <p class="text-sm text-dark-gray mb-2"><strong class="text-dark-navy">Instructions:</strong> When you click "Send My Savings", your email client will open with a pre-filled message. <strong>Attach your consumption data file(s)</strong> to that email before sending (e.g. spreadsheet or PDF of your usage).</p>
963                </div>
964              </div>
965            </div>
966
967            <!-- Multi-Site Mode (ZIP Upload) -->
968            <div x-show="requiresBulkUpload">
969              <div class="text-center mb-6">
970                <h2 class="text-xl md:text-2xl font-heading font-bold text-dark-navy mb-2">
971                  Share Your Electricity Bills
972                </h2>
973                <p class="text-dark-gray">
974                  For multi-site analysis, select your ZIP file below. We'll open your email client with a pre-filled message — attach this ZIP when you send it.
975                </p>
976              </div>
977
978              <!-- Instructions -->
979              <div class="bg-light-gray rounded-xl p-6 mb-6">
980                <div class="flex items-start">
981                  <svg class="w-6 h-6 text-primary-blue mr-3 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
982                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
983                  </svg>
984                  <div>
985                    <h4 class="font-semibold text-dark-navy mb-2">Requirements</h4>
986                    <ul class="text-sm text-dark-gray space-y-1">
987                      <li>• ZIP file containing your electricity bills</li>
988                      <li>• At least 12 rolling months; include bills for one or more sites</li>
989                      <li>• Maximum file size: 4MB</li>
990                      <li>• You will attach the ZIP to the prepared email when you send it</li>
991                    </ul>
992                  </div>
993                </div>
994              </div>
995
996              <!-- Drag and Drop Area -->
997              <div 
998                x-show="!zipFile"
999                class="border-2 border-dashed border-medium-gray rounded-xl p-8 text-center mb-6 hover:border-primary-blue transition-colors cursor-pointer"
1000                @click="$refs.zipFileInput.click()"
1001                @dragover.prevent="$el.classList.add('border-primary-blue', 'bg-primary-blue/5')"
1002                @dragleave.prevent="$el.classList.remove('border-primary-blue', 'bg-primary-blue/5')"
1003                @drop.prevent="$el.classList.remove('border-primary-blue', 'bg-primary-blue/5'); handleZipFileUpload({target: {files: $event.dataTransfer.files}})"
1004              >
1005                <input 
1006                  type="file"
1007                  x-ref="zipFileInput"
1008                  accept=".zip"
1009                  @change="handleZipFileUpload($event)"
1010                  class="sr-only"
1011                />
1012                <svg class="w-12 h-12 text-medium-gray mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1013                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"></path>
1014                </svg>
1015                <p class="text-dark-navy font-semibold mb-1">Drag and drop your ZIP file here</p>
1016                <p class="text-dark-gray text-sm">or click to browse</p>
1017                <p class="text-dark-gray/60 text-xs mt-2">ZIP file • Max 4MB</p>
1018              </div>
1019
1020              <!-- Uploaded ZIP File Display -->
1021              <div x-show="zipFile" class="mb-6">
1022                <h4 class="font-semibold text-dark-navy mb-3">Uploaded File</h4>
1023                <div class="flex items-center justify-between bg-light-gray rounded-lg px-4 py-3">
1024                  <div class="flex items-center min-w-0">
1025                    <svg class="w-6 h-6 text-accent-green mr-3 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1026                      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
1027                    </svg>
1028                    <div>
1029                      <span class="text-sm font-medium text-dark-navy" x-text="zipFile?.name"></span>
1030                      <span class="text-xs text-dark-gray/60 ml-2" x-text="zipFile ? '(' + formatFileSize(zipFile.size) + ')' : ''"></span>
1031                    </div>
1032                  </div>
1033                  <button 
1034                    type="button"
1035                    @click="removeZipFile()"
1036                    class="text-red-500 hover:text-red-700 p-1 ml-2 flex-shrink-0"
1037                  >
1038                    <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1039                      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
1040                    </svg>
1041                  </button>
1042                </div>
1043              </div>
1044
1045              <p x-show="errors.zipFile" x-text="errors.zipFile" class="text-red-500 text-sm mb-4 text-center"></p>
1046            </div>
1047
1048            <!-- Additional Comments (Both Modes) -->
1049            <div class="mt-6 pt-6 border-t border-medium-gray/30">
1050              <label for="comments" class="block text-sm font-semibold text-dark-gray mb-2">
1051                Additional Comments <span class="text-dark-gray/50">(optional)</span>
1052              </label>
1053              <textarea 
1054                id="comments"
1055                x-model="comments"
1056                rows="3"
1057                maxlength="1000"
1058                placeholder="Any additional information you'd like to share about your energy usage or requirements..."
1059                class="w-full px-4 py-3 border border-medium-gray rounded-lg focus:ring-2 focus:ring-primary-blue focus:border-primary-blue outline-none bg-white text-dark-gray resize-none"
1060              ></textarea>
1061              <p class="text-xs text-dark-gray/60 mt-1 text-right" x-text="comments.length + '/1000'"></p>
1062            </div>
1063
1064            <!-- Error Display -->
1065            <div x-show="submitError" class="bg-red-50 border border-red-200 rounded-lg p-4 mb-4 mt-4">
1066              <p class="text-red-700 text-sm" x-text="submitError"></p>
1067            </div>
1068
1069            <!-- Navigation Buttons -->
1070            <div class="flex justify-between pt-4 mt-4 border-t border-medium-gray/30">
1071              <button 
1072                type="button"
1073                @click="prevStep()"
1074                class="btn-secondary border-2 border-medium-gray text-dark-gray hover:bg-light-gray px-6 py-3 inline-flex items-center justify-center"
1075              >
1076                <svg class="mr-2 w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1077                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16l-4-4m0 0l4-4m-4 4h18"></path>
1078                </svg>
1079                Back
1080              </button>
1081              <button 
1082                type="button"
1083                @click="submitForm()"
1084                :disabled="isSubmitting"
1085                class="btn-primary px-8 py-3 inline-flex items-center justify-center"
1086              >
1087                <span x-show="!isSubmitting">Send My Savings</span>
1088                <span x-show="isSubmitting" class="flex items-center">
1089                  <svg class="animate-spin -ml-1 mr-2 h-4 w-4 text-white" fill="none" viewBox="0 0 24 24">
1090                    <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
1091                    <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
1092                  </svg>
1093                  Sending...
1094                </span>
1095                <svg x-show="!isSubmitting" class="ml-2 w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1096                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"></path>
1097                </svg>
1098              </button>
1099            </div>
1100          </div>
1101
1102          <!-- ==================== STEP 4: Success Confirmation (mailto) ==================== -->
1103          <div x-show="currentStep === 4" x-transition:enter="transition ease-out duration-500" x-transition:enter-start="opacity-0 transform scale-95" x-transition:enter-end="opacity-100 transform scale-100">
1104            
1105            <!-- Mailto - Email client opens with pre-filled request; user sends and attaches files manually -->
1106            <div class="text-center py-6">
1107              <div class="relative inline-block mb-4">
1108                <div class="w-20 h-20 bg-gradient-to-br from-primary-blue to-dark-navy rounded-full flex items-center justify-center mx-auto">
1109                  <svg class="w-10 h-10 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1110                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 4.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path>
1111                  </svg>
1112                </div>
1113              </div>
1114
1115              <h2 class="text-2xl md:text-3xl font-heading font-bold text-dark-navy mb-2">
1116                Almost there!
1117              </h2>
1118              <p class="text-lg text-dark-gray mb-6">
1119                Your email client should have opened with your request details
1120              </p>
1121
1122              <!-- File Attachment Reminder -->
1123              <div x-show="hasFilesToAttach" class="bg-amber-50 border border-amber-200 rounded-xl p-5 mb-6 text-left max-w-lg mx-auto">
1124                <div class="flex items-start">
1125                  <svg class="w-6 h-6 text-amber-600 mr-3 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1126                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
1127                  </svg>
1128                  <div>
1129                    <h4 class="font-semibold text-amber-800 mb-2">Important: Attach Your Files</h4>
1130                    <p class="text-sm text-amber-700 mb-2" x-show="fileAttachmentList.length">
1131                      Please attach the following file(s) to the email before sending:
1132                    </p>
1133                    <ul class="text-sm text-amber-700 space-y-1" x-show="fileAttachmentList.length">
1134                      <template x-for="file in fileAttachmentList" :key="file">
1135                        <li class="flex items-center">
1136                          <svg class="w-4 h-4 mr-2 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1137                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13"></path>
1138                          </svg>
1139                          <span x-text="file"></span>
1140                        </li>
1141                      </template>
1142                    </ul>
1143                    <p class="text-sm text-amber-700" x-show="!fileAttachmentList.length">
1144                      Please attach your consumption data file(s) to the email before sending.
1145                    </p>
1146                  </div>
1147                </div>
1148              </div>
1149
1150              <!-- What Happens Next - Mailto -->
1151              <div class="bg-light-gray rounded-xl p-5 mb-6 text-left max-w-lg mx-auto">
1152                <h4 class="font-heading font-bold text-dark-navy mb-3 text-center">What Happens Next</h4>
1153                <div class="space-y-3">
1154                  <div class="flex items-start">
1155                    <div class="w-7 h-7 bg-accent-green rounded-full flex items-center justify-center mr-3 flex-shrink-0">
1156                      <svg class="w-4 h-4 text-white" fill="currentColor" viewBox="0 0 20 20">
1157                        <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
1158                      </svg>
1159                    </div>
1160                    <div>
1161                      <p class="font-semibold text-dark-navy text-sm">Send the email</p>
1162                      <p class="text-xs text-dark-gray">Review and send from your email client</p>
1163                    </div>
1164                  </div>
1165                  <div class="flex items-start">
1166                    <div class="w-7 h-7 bg-primary-blue rounded-full flex items-center justify-center mr-3 flex-shrink-0">
1167                      <span class="text-white text-xs font-bold">2</span>
1168                    </div>
1169                    <div>
1170                      <p class="font-semibold text-dark-navy text-sm">We analyse your data</p>
1171                      <p class="text-xs text-dark-gray">Our team prepares your savings estimate</p>
1172                    </div>
1173                  </div>
1174                  <div class="flex items-start">
1175                    <div class="w-7 h-7 bg-medium-gray rounded-full flex items-center justify-center mr-3 flex-shrink-0">
1176                      <span class="text-dark-gray text-xs font-bold">3</span>
1177                    </div>
1178                    <div>
1179                      <p class="font-semibold text-dark-navy text-sm">Proposal delivered</p>
1180                      <p class="text-xs text-dark-gray">Within 24 hours to <span x-text="contactData.email"></span></p>
1181                    </div>
1182                  </div>
1183                </div>
1184              </div>
1185
1186              <p class="text-sm text-dark-gray mb-4">
1187                Questions? Contact us at 
1188                <a href="mailto:[email protected]" class="text-primary-blue hover:underline">[email protected]</a>
1189              </p>
1190
1191              <button 
1192                @click="closeModal()"
1193                class="btn-primary px-10 py-4 inline-flex items-center justify-center"
1194              >
1195                Done
1196              </button>
1197            </div>
1198          </div>
1199
1200        </div>
1201      </div>
1202    </div>
1203  </div>
1204
1205  <!-- How Wheeling Works Section -->
1206  <section class="section-padding bg-white">
1207    <div class="container-custom">
1208      <!-- Section Header -->
1209      <div class="text-center mb-16">
1210        <div class="animate-on-scroll">
1211          <h2 class="text-3xl md:text-4xl font-heading font-bold text-dark-navy mb-6">
1212            How Wheeling Works
1213          </h2>
1214        </div>
1215        <div class="animate-on-scroll" style="animation-delay: 0.1s;">
1216          <p class="text-xl text-dark-gray leading-relaxed max-w-3xl mx-auto">
1217            OAE structures Power Purchase Agreements under both of Eskom's recognised frameworks. The right one depends on how many sites you have and how you want your savings delivered.
1218          </p>
1219        </div>
1220      </div>
1221
1222      <!-- Wheeling Model Cards -->
1223      <div class="grid grid-cols-1 md:grid-cols-2 gap-8 max-w-5xl mx-auto">
1224        
1225        <!-- Traditional Wheeling -->
1226        <div class="animate-on-scroll card p-8 text-center">
1227          <div class="rounded-full flex items-center justify-center mx-auto mb-6" style="width: 90px; height: 90px; background-color: #F2BD08;">
1228            <svg class="text-dark-navy" style="width: 45px; height: 45px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1229              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"></path>
1230            </svg>
1231          </div>
1232          <h3 class="text-xl font-heading font-bold text-dark-navy mb-2">Traditional Wheeling</h3>
1233          <p class="text-sm font-semibold uppercase tracking-wide text-secondary-gold mb-6">Best for 1–5 sites</p>
1234          <ul class="space-y-3 text-left">
1235            <li class="flex items-start gap-3">
1236              <span class="text-dark-gray leading-relaxed">Savings appear as a credit on your bill</span>
1237            </li>
1238            <li class="flex items-start gap-3">
1239              <span class="text-dark-gray leading-relaxed">Fees charged per point of delivery</span>
1240            </li>
1241            <li class="flex items-start gap-3">
1242              <span class="text-dark-gray leading-relaxed">Amended Eskom or municipal supply agreement</span>
1243            </li>
1244            <li class="flex items-start gap-3">
1245              <span class="text-dark-gray leading-relaxed">Best for one-to-one transactions</span>
1246            </li>
1247          </ul>
1248        </div>
1249
1250        <!-- Virtual Wheeling -->
1251        <div class="animate-on-scroll card p-8 text-center" style="animation-delay: 0.1s;">
1252          <div class="rounded-full flex items-center justify-center mx-auto mb-6" style="width: 90px; height: 90px; background-color: #F2BD08;">
1253            <svg class="text-dark-navy" style="width: 45px; height: 45px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1254              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 21V11h4V21"></path>
1255              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.5 14v1M4.5 17v1"></path>
1256              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 21V4h4V21"></path>
1257              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11.5 7v1M11.5 10v1M11.5 13v1M11.5 16v1"></path>
1258              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M18 21V15h3V21"></path>
1259              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19.5 17v1"></path>
1260            </svg>
1261          </div>
1262          <h3 class="text-xl font-heading font-bold text-dark-navy mb-2">Virtual Wheeling</h3>
1263          <p class="text-sm font-semibold uppercase tracking-wide text-secondary-gold mb-6">Best for 30+ sites</p>
1264          <ul class="space-y-3 text-left">
1265            <li class="flex items-start gap-3">
1266              <span class="text-dark-gray leading-relaxed">Savings paid as a cash rebate</span>
1267            </li>
1268            <li class="flex items-start gap-3">
1269              <span class="text-dark-gray leading-relaxed">Fixed fee covering unlimited accounts</span>
1270            </li>
1271            <li class="flex items-start gap-3">
1272              <span class="text-dark-gray leading-relaxed">No changes to existing supply agreements</span>
1273            </li>
1274            <li class="flex items-start gap-3">
1275              <span class="text-dark-gray leading-relaxed">Municipal-connected sites eligible</span>
1276            </li>
1277          </ul>
1278        </div>
1279
1280      </div>
1281
1282      <!-- TOU Footer Note -->
1283      <div class="animate-on-scroll text-center max-w-3xl mx-auto mt-12" style="animation-delay: 0.2s;">
1284        <p class="text-lg text-dark-gray leading-relaxed">
1285          Both models calculate the rebate on a <strong class="font-semibold text-dark-navy">Time-of-Use (TOU) basis</strong> — aligning generation with consumption across Peak, Standard, and Off-Peak periods. OAE handles the structuring, claim submission, and reconciliation end-to-end.
1286        </p>
1287      </div>
1288
1289      <!-- CTA -->
1290      <div class="animate-on-scroll text-center mt-12" style="animation-delay: 0.3s;">
1291        <button
1292          type="button"
1293          @click="openEnquiryModal('energypro-marketplace')"
1294          class="btn-primary text-lg px-8 py-4 inline-flex items-center justify-center"
1295        >
1296          Speak to a Buyers Specialist
1297          <svg class="ml-2 w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1298            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"></path>
1299          </svg>
1300        </button>
1301      </div>
1302    </div>
1303  </section>
1304
1305  <!-- How It Works Section -->
1306  <section class="section-padding bg-light-gray">
1307    <div class="container-custom">
1308      <!-- Section Header -->
1309      <div class="text-center mb-16">
1310        <div class="animate-on-scroll">
1311          <h2 class="text-3xl md:text-4xl font-heading font-bold text-dark-navy mb-6">
1312            How It Works
1313          </h2>
1314        </div>
1315        <div class="animate-on-scroll" style="animation-delay: 0.1s;">
1316          <p class="text-xl text-dark-gray leading-relaxed max-w-3xl mx-auto">
1317            A technology-driven platform for PPA procurement and long-term energy management.
1318          </p>
1319        </div>
1320      </div>
1321
1322      <!-- Process Timeline -->
1323      <div class="max-w-5xl mx-auto">
1324        <div class="relative">
1325          <!-- Timeline Line -->
1326          <div class="hidden md:block absolute left-1/2 transform -translate-x-1/2 w-1 bg-gradient-to-b from-primary-blue to-cta-blue h-full"></div>
1327          
1328          <!-- Step 1: Our Role -->
1329          <div class="animate-on-scroll flex flex-col md:flex-row items-center mb-10" style="animation-delay: 0.1s;">
1330            <div class="md:w-1/2 md:pr-12 mb-8 md:mb-0 text-center md:text-right">
1331              <div class="bg-white rounded-lg p-6 shadow-lg border border-medium-gray/20">
1332                <div class="flex items-center justify-center md:justify-end mb-3">
1333                  <div class="w-12 h-12 bg-gradient-to-br from-primary-blue to-cta-blue rounded-full flex items-center justify-center mr-3 flex-shrink-0">
1334                    <span class="text-white font-bold text-lg">1</span>
1335                  </div>
1336                  <h3 class="text-xl font-heading font-bold text-dark-navy">Our Role</h3>
1337                </div>
1338                <p class="text-dark-gray leading-relaxed">
1339                  Open Access Energy provides a digital procurement platform, Energypro, that manages the commercial, legal, and operational steps to buy electricity from IPPs and traders.
1340                </p>
1341              </div>
1342            </div>
1343            <div class="hidden md:block w-8 h-8 bg-primary-blue rounded-full border-4 border-white shadow-lg relative z-10"></div>
1344            <div class="md:w-1/2 md:pl-12"></div>
1345          </div>
1346
1347          <!-- Step 2: Pre-Contracting Services -->
1348          <div class="animate-on-scroll flex flex-col md:flex-row items-center mb-10" style="animation-delay: 0.2s;">
1349            <div class="md:w-1/2 md:pr-12"></div>
1350            <div class="hidden md:block w-8 h-8 bg-primary-blue rounded-full border-4 border-white shadow-lg relative z-10"></div>
1351            <div class="md:w-1/2 md:pl-12 mb-8 md:mb-0 text-center md:text-left">
1352              <div class="bg-white rounded-lg p-6 shadow-lg border border-medium-gray/20">
1353                <div class="flex items-center justify-center md:justify-start mb-3">
1354                  <div class="w-12 h-12 bg-gradient-to-br from-primary-blue to-cta-blue rounded-full flex items-center justify-center mr-3 flex-shrink-0">
1355                    <span class="text-white font-bold text-lg">2</span>
1356                  </div>
1357                  <h3 class="text-xl font-heading font-bold text-dark-navy">Pre-Contracting Services</h3>
1358                </div>
1359                <p class="text-dark-gray leading-relaxed">
1360                  OAE pre-qualifies IPPs for compliance, technical capability, and financial stability. Only credible projects are presented, reducing buyer exposure to project failure.
1361                </p>
1362              </div>
1363            </div>
1364          </div>
1365
1366          <!-- Step 3: Negotiations -->
1367          <div class="animate-on-scroll flex flex-col md:flex-row items-center mb-10" style="animation-delay: 0.3s;">
1368            <div class="md:w-1/2 md:pr-12 mb-8 md:mb-0 text-center md:text-right">
1369              <div class="bg-white rounded-lg p-6 shadow-lg border border-medium-gray/20">
1370                <div class="flex items-center justify-center md:justify-end mb-3">
1371                  <div class="w-12 h-12 bg-gradient-to-br from-primary-blue to-cta-blue rounded-full flex items-center justify-center flex-shrink-0">
1372                    <span class="text-white font-bold text-lg">3</span>
1373                  </div>
1374                  <h3 class="text-xl font-heading font-bold text-dark-navy">Defining and Facilitating Negotiations</h3>
1375                </div>
1376                <p class="text-dark-gray leading-relaxed">
1377                  OAE levels the playing field by embedding industry expertise into tenders and structuring commercial terms around the buyer's parameters.
1378                </p>
1379              </div>
1380            </div>
1381            <div class="hidden md:block w-8 h-8 bg-primary-blue rounded-full border-4 border-white shadow-lg relative z-10"></div>
1382            <div class="md:w-1/2 md:pl-12"></div>
1383          </div>
1384
1385          <!-- Step 4: Post-Contracting -->
1386          <div class="animate-on-scroll flex flex-col md:flex-row items-center mb-10" style="animation-delay: 0.4s;">
1387            <div class="md:w-1/2 md:pr-12"></div>
1388            <div class="hidden md:block w-8 h-8 bg-primary-blue rounded-full border-4 border-white shadow-lg relative z-10"></div>
1389            <div class="md:w-1/2 md:pl-12 mb-8 md:mb-0 text-center md:text-left">
1390              <div class="bg-white rounded-lg p-6 shadow-lg border border-medium-gray/20">
1391                <div class="flex items-center justify-center md:justify-start mb-3">
1392                  <div class="w-12 h-12 bg-gradient-to-br from-primary-blue to-cta-blue rounded-full flex items-center justify-center mr-3 flex-shrink-0">
1393                    <span class="text-white font-bold text-lg">4</span>
1394                  </div>
1395                  <h3 class="text-xl font-heading font-bold text-dark-navy">Post-Contracting and Administration</h3>
1396                </div>
1397                <p class="text-dark-gray leading-relaxed">
1398                  Once a PPA begins, OAE acts as the single point of contact. Backed by a R55 million software platform, OAE manages reporting, verification, and analytics.
1399                </p>
1400              </div>
1401            </div>
1402          </div>
1403
1404          <!-- Step 5: Supply Volume Adjustments -->
1405          <div class="animate-on-scroll flex flex-col md:flex-row items-center" style="animation-delay: 0.5s;">
1406            <div class="md:w-1/2 md:pr-12 mb-8 md:mb-0 text-center md:text-right">
1407              <div class="bg-white rounded-lg p-6 shadow-lg border border-medium-gray/20">
1408                <div class="flex items-center justify-center md:justify-end mb-3">
1409                  <div class="w-12 h-12 bg-gradient-to-br from-primary-blue to-cta-blue rounded-full flex items-center justify-center mr-3 flex-shrink-0">
1410                    <span class="text-white font-bold text-lg">5</span>
1411                  </div>
1412                  <h3 class="text-xl font-heading font-bold text-dark-navy">Supply Volume Adjustments</h3>
1413                </div>
1414                <p class="text-dark-gray leading-relaxed">
1415                  Comprehensive historical data analysis and forward-looking projections for strategic energy planning and investment decisions.
1416                </p>
1417              </div>
1418            </div>
1419            <div class="hidden md:block w-8 h-8 bg-primary-blue rounded-full border-4 border-white shadow-lg relative z-10"></div>
1420            <div class="md:w-1/2 md:pl-12"></div>
1421          </div>
1422        </div>
1423      </div>
1424    </div>
1425  </section>
1426
1427  <!-- Marketplace Capabilities Section -->
1428  <section class="section-padding bg-white">
1429    <div class="container-custom">
1430      <!-- Section Header -->
1431      <div class="text-center mb-16">
1432        <div class="animate-on-scroll">
1433          <p class="text-sm font-semibold uppercase tracking-wide text-secondary-gold mb-3">DEMAND SIDE</p>
1434          <h2 class="text-3xl md:text-4xl font-heading font-bold text-dark-navy mb-4">
1435            Energypro Marketplace
1436          </h2>
1437        </div>
1438        <div class="animate-on-scroll" style="animation-delay: 0.1s;">
1439          <p class="text-xl text-dark-gray leading-relaxed max-w-3xl mx-auto">
1440            Where supply and demand meet
1441          </p>
1442        </div>
1443      </div>
1444
1445      <!-- Capability Cards -->
1446      <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
1447        <div class="animate-on-scroll card p-8 text-center">
1448          <div class="rounded-full flex items-center justify-center mx-auto mb-6" style="width: 90px; height: 90px; background-color: #F2BD08;">
1449            <svg class="text-dark-navy" style="width: 45px; height: 45px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1450              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"></path>
1451            </svg>
1452          </div>
1453          <h3 class="text-xl font-heading font-bold text-dark-navy mb-4">Curated pool of IPPs, traders and off-takers</h3>
1454          <p class="text-dark-gray leading-relaxed">
1455            Pre-qualified participants across the wheeling market.
1456          </p>
1457        </div>
1458
1459        <div class="animate-on-scroll card p-8 text-center" style="animation-delay: 0.1s;">
1460          <div class="rounded-full flex items-center justify-center mx-auto mb-6" style="width: 90px; height: 90px; background-color: #F2BD08;">
1461            <svg class="text-dark-navy" style="width: 45px; height: 45px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1462              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 7h6m0 10v-3m-3 3h.01M9 17h.01M9 14h.01M12 14h.01M15 11h.01M12 11h.01M9 11h.01M7 21h10a2 2 0 002-2V5a2 2 0 00-2-2H7a2 2 0 00-2 2v14a2 2 0 002 2z"></path>
1463            </svg>
1464          </div>
1465          <h3 class="text-xl font-heading font-bold text-dark-navy mb-4">Transparent tariff and offer discovery</h3>
1466          <p class="text-dark-gray leading-relaxed">
1467            Compare supply, pricing and COD timing in one view.
1468          </p>
1469        </div>
1470
1471        <div class="animate-on-scroll card p-8 text-center" style="animation-delay: 0.2s;">
1472          <div class="rounded-full flex items-center justify-center mx-auto mb-6" style="width: 90px; height: 90px; background-color: #F2BD08;">
1473            <svg class="text-dark-navy" style="width: 45px; height: 45px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1474              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"></path>
1475            </svg>
1476          </div>
1477          <h3 class="text-xl font-heading font-bold text-dark-navy mb-4">Structured matching</h3>
1478          <p class="text-dark-gray leading-relaxed">
1479            Match demand to supply by load profile and price.
1480          </p>
1481        </div>
1482
1483        <div class="animate-on-scroll card p-8 text-center" style="animation-delay: 0.3s;">
1484          <div class="rounded-full flex items-center justify-center mx-auto mb-6" style="width: 90px; height: 90px; background-color: #F2BD08;">
1485            <svg class="text-dark-navy" style="width: 45px; height: 45px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1486              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1"></path>
1487            </svg>
1488          </div>
1489          <h3 class="text-xl font-heading font-bold text-dark-navy mb-4">Proposal building and price modelling</h3>
1490          <p class="text-dark-gray leading-relaxed">
1491            Energypro-powered proposals and scenario comparisons.
1492          </p>
1493        </div>
1494
1495        <div class="animate-on-scroll card p-8 text-center" style="animation-delay: 0.4s;">
1496          <div class="rounded-full flex items-center justify-center mx-auto mb-6" style="width: 90px; height: 90px; background-color: #F2BD08;">
1497            <svg class="text-dark-navy" style="width: 45px; height: 45px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1498              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 8v8m-4-5v5m-4-2v2m-2 4h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
1499            </svg>
1500          </div>
1501          <h3 class="text-xl font-heading font-bold text-dark-navy mb-4">Deal pipeline visibility</h3>
1502          <p class="text-dark-gray leading-relaxed">
1503            Track opportunities from enquiry to signed term sheet.
1504          </p>
1505        </div>
1506      </div>
1507    </div>
1508  </section>
1509
1510  <!-- Why Use OAE Section -->
1511  <section class="section-padding bg-light-gray">
1512    <div class="container-custom">
1513      <!-- Section Header -->
1514      <div class="text-center mb-16">
1515        <div class="animate-on-scroll">
1516          <h2 class="text-3xl md:text-4xl font-heading font-bold text-dark-navy mb-6">
1517            Why use OAE?
1518          </h2>
1519        </div>
1520        <div class="animate-on-scroll" style="animation-delay: 0.1s;">
1521          <p class="text-xl text-dark-gray leading-relaxed max-w-3xl mx-auto">
1522            Comprehensive reporting suite with customisable dashboards, KPI tracking, and regulatory compliance documentation.
1523          </p>
1524        </div>
1525      </div>
1526
1527      <!-- Features Grid -->
1528      <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
1529        
1530        <!-- Feature 1: No Comparable Alternative -->
1531        <div class="animate-on-scroll card p-8 text-center">
1532          <div class="rounded-full flex items-center justify-center mx-auto mb-6" style="width: 90px; height: 90px; background-color: #F2BD08;">
1533            <svg class="text-dark-navy" style="width: 45px; height: 45px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1534              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
1535            </svg>
1536          </div>
1537          <h3 class="text-xl font-heading font-bold text-dark-navy mb-4">No Comparable Alternative</h3>
1538          <p class="text-dark-gray leading-relaxed">
1539            No other company in South Africa provides a digital platform that automates and manages end-to-end PPA procurement. Manual tenders cannot replicate OAE's modelling or commercial precision.
1540          </p>
1541        </div>
1542
1543        <!-- Feature 2: Cost Comparison in Context -->
1544        <div class="animate-on-scroll card p-8 text-center" style="animation-delay: 0.1s;">
1545          <div class="rounded-full flex items-center justify-center mx-auto mb-6" style="width: 90px; height: 90px; background-color: #F2BD08;">
1546            <svg class="text-dark-navy" style="width: 45px; height: 45px;" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
1547              <!-- Top fulcrum circle -->
1548              <circle cx="12" cy="4" r="2" fill="currentColor"/>
1549              <!-- Vertical support beam -->
1550              <line x1="12" y1="6" x2="12" y2="18"/>
1551              <!-- Horizontal balance beam -->
1552              <line x1="4" y1="8" x2="20" y2="8"/>
1553              <!-- Left scale pan -->
1554              <path d="M4 8 L2 12 L6 12 Z" fill="none" stroke="currentColor"/>
1555              <ellipse cx="4" cy="12" rx="2" ry="1" fill="none" stroke="currentColor"/>
1556              <!-- Right scale pan -->
1557              <path d="M20 8 L18 12 L22 12 Z" fill="none" stroke="currentColor"/>
1558              <ellipse cx="20" cy="12" rx="2" ry="1" fill="none" stroke="currentColor"/>
1559              <!-- Base -->
1560              <rect x="8" y="18" width="8" height="2" rx="1" fill="currentColor"/>
1561            </svg>
1562          </div>
1563          <h3 class="text-xl font-heading font-bold text-dark-navy mb-4">Cost Comparison in Context</h3>
1564          <p class="text-dark-gray leading-relaxed">
1565            Advisory firms charge once-off fees with each revision adding cost. OAE's transaction-based fee structure delivers stronger long-term outcomes and alignment of incentives.
1566          </p>
1567        </div>
1568
1569        <!-- Feature 3: Ongoing Alignment of Interests -->
1570        <div class="animate-on-scroll card p-8 text-center" style="animation-delay: 0.2s;">
1571          <div class="rounded-full flex items-center justify-center mx-auto mb-6" style="width: 90px; height: 90px; background-color: #F2BD08;">
1572            <svg class="text-dark-navy" style="width: 45px; height: 45px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1573              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"></path>
1574            </svg>
1575          </div>
1576          <h3 class="text-xl font-heading font-bold text-dark-navy mb-4">Ongoing Alignment of Interests</h3>
1577          <p class="text-dark-gray leading-relaxed">
1578            OAE remains involved throughout the PPA term, ensuring performance and value. Our success depends on the PPA's long-term viability, aligning our interests directly with the buyer's.
1579          </p>
1580        </div>
1581
1582        <!-- Feature 4: Ongoing Alignment of Interests (duplicate as requested) -->
1583        <div class="animate-on-scroll card p-8 text-center" style="animation-delay: 0.3s;">
1584          <div class="rounded-full flex items-center justify-center mx-auto mb-6" style="width: 90px; height: 90px; background-color: #F2BD08;">
1585            <svg class="text-dark-navy" style="width: 45px; height: 45px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1586              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 
15860 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"></path>
1587            </svg>
1588          </div>
1589          <h3 class="text-xl font-heading font-bold text-dark-navy mb-4">Ongoing Alignment of Interests</h3>
1590          <p class="text-dark-gray leading-relaxed">
1591            OAE remains involved throughout the PPA term, ensuring performance and value. Our success depends on the PPA's long-term viability, aligning our interests directly with the buyer's.
1592          </p>
1593        </div>
1594
1595      </div>
1596    </div>
1597  </section>
1598
1599  <!-- CTA Section -->
1600  <section class="cta-section">
1601    <!-- Background Pattern -->
1602    <div class="absolute inset-0 opacity-10">
1603      <div class="absolute inset-0" style="background-image: radial-gradient(circle at 25% 25%, rgba(255,255,255,.2) 2px, transparent 2px), radial-gradient(circle at 75% 75%, rgba(255,255,255,.2) 2px, transparent 2px); background-size: 60px 60px;"></div>
1604    </div>
1605    
1606    <div class="container-custom relative z-10">
1607      <div class="max-w-4xl mx-auto text-center">
1608        
1609        <!-- Icon -->
1610        <div class="animate-on-scroll mb-8">
1611          <div class="w-20 h-20 bg-white rounded-full flex items-center justify-center mx-auto mb-6">
1612            <svg class="w-10 h-10 text-primary-blue" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1613              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
1614            </svg>
1615          </div>
1616          <h2 class="text-3xl md:text-4xl font-heading font-bold text-white mb-6">
1617            Ready to Simplify Your Renewable Procurement?
1618          </h2>
1619        </div>
1620        
1621        <!-- Main Content -->
1622        <div class="animate-on-scroll" style="animation-delay: 0.2s;">
1623          <p class="text-xl md:text-2xl text-blue-100 leading-relaxed mb-8">
1624            Discover how OAE can help your organisation secure competitive renewable supply, faster, through the Energypro Marketplace.
1625          </p>
1626        </div>
1627        
1628        <!-- CTA -->
1629        <div class="animate-on-scroll mt-12" style="animation-delay: 0.4s;">
1630          <button @click="openEnquiryModal('energypro-marketplace')" class="btn-secondary border-2 border-white text-white hover:bg-white hover:text-primary-blue text-lg px-8 py-4 inline-flex items-center justify-center">
1631            Get Started Today
1632            <svg class="ml-2 w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1633              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"></path>
1634            </svg>
1635          </button>
1636        </div>
1637        
1638      </div>
1639    </div>
1640  </section>
1641
1642  <!-- Referral Programme CTA Section -->
1643  <section class="section-padding bg-white border-t border-medium-gray/20">
1644    <div class="container-custom">
1645      <div class="max-w-4xl mx-auto text-center">
1646        
1647        <!-- Icon -->
1648        <div class="animate-on-scroll mb-8">
1649          <div class="w-20 h-20 bg-gradient-to-br from-primary-blue to-cta-blue rounded-full flex items-center justify-center mx-auto mb-6">
1650            <svg class="w-10 h-10 text-white" fill="currentColor" viewBox="0 0 24 24">
1651              <path d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
1652            </svg>
1653          </div>
1654          <h2 class="text-3xl md:text-4xl font-heading font-bold text-dark-navy mb-6">
1655            Are You a Consultant or Industry Partner?
1656          </h2>
1657        </div>
1658        
1659        <!-- Main Content -->
1660        <div class="animate-on-scroll" style="animation-delay: 0.2s;">
1661          <p class="text-xl text-dark-gray leading-relaxed mb-8 max-w-3xl mx-auto">
1662            Earn referral commissions by introducing qualified buyers to OAE's renewable energy procurement platform. We close the deal — you make the warm introduction.
1663          </p>
1664        </div>
1665        
1666        <!-- CTA -->
1667        <div class="animate-on-scroll mt-8" style="animation-delay: 0.4s;">
1668          <button @click="openEnquiryModal('broker')" class="btn-primary text-lg px-8 py-4 inline-flex items-center justify-center">
1669            Join Our Referral Programme
1670            <svg class="ml-2 w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1671              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"></path>
1672            </svg>
1673          </button>
1674        </div>
1675        
1676      </div>
1677    </div>
1678  </section>
1679  
1680  <!-- Enquiry Modal Include -->
1681  <div data-include="/src/includes/enquiry-modal.html"></div>
1682
1683  <!-- Footer Include -->
1684  <div data-include="/src/includes/footer.html"></div>
1685</body>
1686</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.