@ai.all/ds7 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/01-architecture/ATOMIC-DESIGN.md +48 -42
- package/01-architecture/COMPONENT-ANATOMY.md +14 -30
- package/01-architecture/MODIFIER-SYSTEM.md +24 -35
- package/02-design-system/BRANDBOOK-SANDBOX.md +34 -34
- package/02-design-system/NAMING-CONVENTIONS.md +21 -19
- package/02-design-system/TOKENS-SPEC.md +65 -51
- package/03-performance-web-vitals/ASSETS-PIPELINE.md +40 -49
- package/03-performance-web-vitals/CRITICAL-CSS.md +20 -27
- package/03-performance-web-vitals/FONTS-ZERO-CLS.md +30 -34
- package/03-performance-web-vitals/HYDRATION-STRATEGY.md +38 -21
- package/04-seo-ai-optimization/AEO-GEO-AI-SEARCH.md +28 -45
- package/04-seo-ai-optimization/GOOGLE-LOCAL-EEAT.md +20 -25
- package/04-seo-ai-optimization/STRUCTURED-DATA.md +42 -37
- package/05-internationalization/I18N-ARCHITECTURE.md +27 -25
- package/05-internationalization/LOCALE-TEMPLATE.json +23 -22
- package/06-business-conversion/B2C-B2B-MODELS.md +22 -21
- package/06-business-conversion/CONTEXTUAL-LEADS.md +17 -22
- package/06-business-conversion/EV-SOLAR-ECOSYSTEM.md +21 -21
- package/07-testing/TESTING-STRATEGY.md +45 -83
- package/08-token-optimization/TOKEN-STRATEGY.md +54 -103
- package/ALL.md +203 -52
- package/CHANGELOG.md +27 -0
- package/README.md +92 -97
- package/SPEC.md +81 -37
- package/bin/ds7.js +183 -100
- package/package.json +10 -11
- package/templates/component.vue +10 -16
- package/templates/nuxt.config.ts +19 -25
- package/templates/theme.css +17 -10
- package/ANDALUSIA.md +0 -89
- package/ff.md +0 -112
|
@@ -1,70 +1,53 @@
|
|
|
1
|
-
# 04
|
|
1
|
+
# 04 · AEO and GEO: writing for AI search engines
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Answer Engine Optimization (AEO) and Generative Engine Optimization (GEO) make a site easy to quote in AI answers: ChatGPT search, Perplexity, Gemini overviews and similar systems.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
## 1.
|
|
7
|
+
## 1. What changed
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
Современные нейросети (SearchGPT, Gemini, Perplexity) считывают **семантические утверждения и факты**. Они ищут лаконичные, точные, проверяемые ответы на вопросы пользователя.
|
|
9
|
+
Classic search matched words. AI search extracts **claims and facts** that answer a question, then cites the source. Pages that state a question, answer it in a few precise sentences, and back it with structured data are quoted more often.
|
|
11
10
|
|
|
12
11
|
---
|
|
13
12
|
|
|
14
|
-
## 2.
|
|
13
|
+
## 2. Direct answer block
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
Each informational section begins with its question as an `h2` and a short factual answer of 40–50 words:
|
|
17
16
|
|
|
18
17
|
```html
|
|
19
|
-
|
|
20
|
-
<h2 id="faq-cost">¿Cuánto cuesta instalar placas solares en una casa en Sevilla?</h2>
|
|
18
|
+
<h2 id="cost-4kw">How much does a 4 kW home solar system cost?</h2>
|
|
21
19
|
|
|
22
|
-
<!-- 2. Блок прямого ответа: 40–50 слов, точные цифры, без вводных фраз -->
|
|
23
20
|
<p class="direct-answer">
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
del IBI en Sevilla y la deducción de hasta el 40% en el IRPF, el coste neto final se sitúa
|
|
27
|
-
entre <strong>2.600 € y 3.300 €</strong>, con un retorno de inversión en 3,8 años.
|
|
21
|
+
A standard 4 kW system costs <strong>[range from your price list]</strong> before grants.
|
|
22
|
+
Replace the placeholder with a figure you can source, and state the date and the region.
|
|
28
23
|
</p>
|
|
29
24
|
```
|
|
30
25
|
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
Rules for the answer:
|
|
27
|
+
- No introduction ("Great question…"). The first words answer the question.
|
|
28
|
+
- Numbers come with units, a date and a region.
|
|
29
|
+
- Every figure has a source in the page or in linked official documents.
|
|
33
30
|
|
|
34
31
|
---
|
|
35
32
|
|
|
36
|
-
## 3.
|
|
33
|
+
## 3. Tables for comparisons
|
|
37
34
|
|
|
38
|
-
|
|
35
|
+
Assistants parse tables faster than prose. Use real `<table>` markup with `<thead>`:
|
|
39
36
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
<tbody>
|
|
52
|
-
<tr>
|
|
53
|
-
<td>Panel Monocristalino N-Type</td>
|
|
54
|
-
<td>450 W</td>
|
|
55
|
-
<td>22,5 %</td>
|
|
56
|
-
<td>25 años</td>
|
|
57
|
-
<td>139 €</td>
|
|
58
|
-
</tr>
|
|
59
|
-
</tbody>
|
|
60
|
-
</table>
|
|
61
|
-
```
|
|
37
|
+
| Model | Power | Efficiency | Warranty |
|
|
38
|
+
|---|---|---|---|
|
|
39
|
+
| [example] | [value] | [value] | [value] |
|
|
40
|
+
|
|
41
|
+
Fill in values from your product data, not from this example.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 4. Sources
|
|
46
|
+
|
|
47
|
+
Name primary sources: the law, the official gazette, the grant programme page. Link them. A claim with a link to the regulation is quoted more often than one without.
|
|
62
48
|
|
|
63
49
|
---
|
|
64
50
|
|
|
65
|
-
##
|
|
51
|
+
## 5. Measurement
|
|
66
52
|
|
|
67
|
-
|
|
68
|
-
* **RD 244/2019** — закон Испании о компенсации излишков и коллективном потреблении;
|
|
69
|
-
* **BOE (Boletín Oficial del Estado)** — регламент налоговых вычетов IRPF;
|
|
70
|
-
* **Plan MOVES III** — государственная субсидия на зарядные станции для электрокаров.
|
|
53
|
+
Track which pages appear in AI answers with a manual check each month, and record it in the project's `docs/METRICS.md`. Do not record a figure you did not observe.
|
|
@@ -1,41 +1,36 @@
|
|
|
1
|
-
# 04
|
|
1
|
+
# 04 · Local search, E-E-A-T and behavioural signals
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
For businesses that serve a region, most new customers find them through a map listing. This document lists what the site controls.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
## 1.
|
|
7
|
+
## 1. Local pack
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Google's local results use the business profile and the website together.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
2. **Живые отзывы:**
|
|
15
|
-
Регулярное пополнение отзывов от реальных клиентов с прикрепленными фотографиями установленных панелей на крышах.
|
|
16
|
-
3. **Гео-привязка сервисных зон:**
|
|
17
|
-
В коде страницы и в микроразметке четко указываются города обслуживания: `Sevilla`, `Málaga`, `Marbella`, `Cádiz`, `Estepona`.
|
|
11
|
+
1. **NAP consistency.** Name, address and phone are identical on the website, in `LocalBusiness` structured data and in the business profile. Same spelling, same format.
|
|
12
|
+
2. **Reviews.** Real customer reviews, requested after each job. Do not write reviews for customers and do not ask for reviews only from happy customers.
|
|
13
|
+
3. **Service areas.** The towns or regions served are listed in the page content and in the structured data (`areaServed`).
|
|
18
14
|
|
|
19
15
|
---
|
|
20
16
|
|
|
21
|
-
## 2.
|
|
17
|
+
## 2. E-E-A-T
|
|
22
18
|
|
|
23
|
-
|
|
19
|
+
Google rates the trustworthiness of pages that affect money or safety more strictly.
|
|
24
20
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
- **Legal identity:** full legal name, company registration number, registered address. Shown in the footer and on a legal page.
|
|
22
|
+
- **Qualifications:** the licences and certifications the staff hold, with the issuing body named.
|
|
23
|
+
- **Partnerships:** only partner logos the business is authorised to use, with a link to the partner's confirmation where one exists.
|
|
24
|
+
- **Named authors** for guides, with their role.
|
|
25
|
+
|
|
26
|
+
Placeholders in this standard (`[Legal name]`, `[Registration number]`) must be replaced with real data by the business.
|
|
28
27
|
|
|
29
28
|
---
|
|
30
29
|
|
|
31
|
-
## 3.
|
|
30
|
+
## 3. Behavioural signals
|
|
32
31
|
|
|
33
|
-
|
|
32
|
+
Google observes what visitors do after a result.
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
Интерактивный калькулятор заставляет пользователя провести на странице **3–5 минут** (двигает ползунок, выбирает аккумулятор, смотрит график окупаемости).
|
|
39
|
-
3. **Отсутствие возврата в поиск (Zero Pogo-Sticking):**
|
|
40
|
-
Клиент нажимает кнопку перехода в WhatsApp или скачивает PDF-смету. Его потребность полностью закрыта. Он **не возвращается в поиск Google** продолжать поиски.
|
|
41
|
-
Для поисковика это доказательство высшего качества страницы: сайт автоматически поднимается на первые позиции.
|
|
34
|
+
- **Fast first content.** A visitor who sees content at once stays. See `03-performance-web-vitals/`.
|
|
35
|
+
- **Useful interaction.** A calculator or configurator keeps a visitor on the page to finish a task.
|
|
36
|
+
- **Completed intent.** A visitor who reaches the contact action or downloads what they came for does not need to search again. Design the contact action to be the obvious next step.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
# 04
|
|
1
|
+
# 04 · Structured data (Schema.org JSON-LD)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Structured data is a machine-readable description of the business, its products and its pages. Search engines and AI assistants use it to identify entities and to show rich results.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
## 1.
|
|
7
|
+
## 1. One graph per site
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Describe all entities in a single `@graph` that links them by `@id`, instead of scattered fragments:
|
|
10
10
|
|
|
11
11
|
```json
|
|
12
12
|
{
|
|
@@ -14,64 +14,61 @@
|
|
|
14
14
|
"@graph": [
|
|
15
15
|
{
|
|
16
16
|
"@type": "Organization",
|
|
17
|
-
"@id": "https://
|
|
18
|
-
"name": "
|
|
19
|
-
"legalName": "
|
|
20
|
-
"url": "https://
|
|
21
|
-
"logo": "https://
|
|
22
|
-
"email": "
|
|
17
|
+
"@id": "https://example.com/#organization",
|
|
18
|
+
"name": "[Brand name]",
|
|
19
|
+
"legalName": "[Legal name]",
|
|
20
|
+
"url": "https://example.com",
|
|
21
|
+
"logo": "https://example.com/brand/logo.svg",
|
|
22
|
+
"email": "[contact email]",
|
|
23
23
|
"address": {
|
|
24
24
|
"@type": "PostalAddress",
|
|
25
|
-
"addressLocality": "
|
|
26
|
-
"addressRegion": "
|
|
27
|
-
"addressCountry": "
|
|
25
|
+
"addressLocality": "[City]",
|
|
26
|
+
"addressRegion": "[Region]",
|
|
27
|
+
"addressCountry": "[ISO country code]"
|
|
28
28
|
},
|
|
29
|
-
"areaServed": ["
|
|
29
|
+
"areaServed": ["[Region 1]", "[Region 2]"]
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
32
|
"@type": "WebSite",
|
|
33
|
-
"@id": "https://
|
|
34
|
-
"url": "https://
|
|
35
|
-
"name": "
|
|
36
|
-
"publisher": { "@id": "https://
|
|
33
|
+
"@id": "https://example.com/#website",
|
|
34
|
+
"url": "https://example.com",
|
|
35
|
+
"name": "[Brand name]",
|
|
36
|
+
"publisher": { "@id": "https://example.com/#organization" },
|
|
37
37
|
"inLanguage": ["es", "en", "uk"]
|
|
38
38
|
}
|
|
39
39
|
]
|
|
40
|
-
|
|
40
|
+
}
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
Name, address and phone must match the business profile exactly (see `GOOGLE-LOCAL-EEAT.md`).
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
---
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
## 2. Products and offers
|
|
48
48
|
|
|
49
49
|
```json
|
|
50
50
|
{
|
|
51
51
|
"@type": "Product",
|
|
52
|
-
"name": "
|
|
53
|
-
"image": "https://
|
|
54
|
-
"description": "
|
|
55
|
-
"brand": {
|
|
56
|
-
"@type": "Brand",
|
|
57
|
-
"name": "V2C"
|
|
58
|
-
},
|
|
52
|
+
"name": "[Product name]",
|
|
53
|
+
"image": "https://example.com/images/p/product.webp",
|
|
54
|
+
"description": "[One factual sentence]",
|
|
55
|
+
"brand": { "@type": "Brand", "name": "[Brand]" },
|
|
59
56
|
"offers": {
|
|
60
57
|
"@type": "Offer",
|
|
61
|
-
"price": "
|
|
58
|
+
"price": "[price]",
|
|
62
59
|
"priceCurrency": "EUR",
|
|
63
|
-
"priceValidUntil": "
|
|
60
|
+
"priceValidUntil": "[date the price is valid until]",
|
|
64
61
|
"availability": "https://schema.org/InStock",
|
|
65
|
-
"seller": { "@id": "https://
|
|
62
|
+
"seller": { "@id": "https://example.com/#organization" }
|
|
66
63
|
}
|
|
67
64
|
}
|
|
68
65
|
```
|
|
69
66
|
|
|
70
|
-
|
|
67
|
+
Only publish a price that is current on the page. Update `priceValidUntil` when you update the price.
|
|
71
68
|
|
|
72
|
-
|
|
69
|
+
---
|
|
73
70
|
|
|
74
|
-
|
|
71
|
+
## 3. FAQ
|
|
75
72
|
|
|
76
73
|
```json
|
|
77
74
|
{
|
|
@@ -79,12 +76,20 @@
|
|
|
79
76
|
"mainEntity": [
|
|
80
77
|
{
|
|
81
78
|
"@type": "Question",
|
|
82
|
-
"name": "
|
|
79
|
+
"name": "[Question as the visitor asks it]",
|
|
83
80
|
"acceptedAnswer": {
|
|
84
81
|
"@type": "Answer",
|
|
85
|
-
"text": "
|
|
82
|
+
"text": "[The same answer as on the page]"
|
|
86
83
|
}
|
|
87
84
|
}
|
|
88
85
|
]
|
|
89
86
|
}
|
|
90
87
|
```
|
|
88
|
+
|
|
89
|
+
The FAQ text in structured data must match the visible text on the page.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 4. Validation
|
|
94
|
+
|
|
95
|
+
Check every page with a structured-data validator before release. A validator error counts as a failed gate.
|
|
@@ -1,34 +1,31 @@
|
|
|
1
|
-
# 05
|
|
1
|
+
# 05 · Internationalisation: one hub
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
All interface text lives in one place. Adding a language is one file and one configuration entry.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
## 1.
|
|
7
|
+
## 1. Principle
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
Do not keep text in several places: partly in `i18n/`, partly in inline `{ es, en }` objects inside components, partly typed into templates.
|
|
10
|
+
|
|
11
|
+
Structure:
|
|
11
12
|
|
|
12
|
-
✅ **Как устроено в DS7:**
|
|
13
|
-
Все системные строки интерфейса хранятся **строго в одном месте**:
|
|
14
13
|
```
|
|
15
14
|
i18n/
|
|
16
15
|
└── locales/
|
|
17
|
-
├── es.ts
|
|
18
|
-
├── en.ts
|
|
19
|
-
├── uk.ts
|
|
20
|
-
|
|
21
|
-
└── fr.ts # Французский (новый)
|
|
16
|
+
├── es.ts # base language
|
|
17
|
+
├── en.ts
|
|
18
|
+
├── uk.ts
|
|
19
|
+
└── [code].ts # any new language
|
|
22
20
|
```
|
|
23
21
|
|
|
24
22
|
---
|
|
25
23
|
|
|
26
|
-
## 2.
|
|
24
|
+
## 2. Adding a language
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
1. Copy the base locale file to `[code].ts` and translate every value. Keys stay the same.
|
|
27
|
+
2. Register the language:
|
|
30
28
|
|
|
31
|
-
### Шаг 2: Зарегистрировать язык в `nuxt.config.ts`:
|
|
32
29
|
```ts
|
|
33
30
|
// nuxt.config.ts
|
|
34
31
|
i18n: {
|
|
@@ -38,20 +35,25 @@ i18n: {
|
|
|
38
35
|
{ code: 'es', language: 'es-ES', name: 'Español', file: 'es.ts' },
|
|
39
36
|
{ code: 'en', language: 'en-GB', name: 'English', file: 'en.ts' },
|
|
40
37
|
{ code: 'uk', language: 'uk-UA', name: 'Українська', file: 'uk.ts' },
|
|
41
|
-
{ code: '
|
|
38
|
+
{ code: '[code]', language: '[bcp47]', name: '[name]', file: '[code].ts' },
|
|
42
39
|
],
|
|
43
|
-
langDir: '../i18n/locales'
|
|
40
|
+
langDir: '../i18n/locales',
|
|
44
41
|
}
|
|
45
42
|
```
|
|
46
43
|
|
|
47
|
-
|
|
44
|
+
Routes, language switcher, `hreflang` and sitemap entries for the new language are generated from this list.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 3. Keys
|
|
49
|
+
|
|
50
|
+
- Grouped by component or section: `businessScreens.night.title`.
|
|
51
|
+
- Named by meaning, never by appearance (`hero.title`, not `big.red.title`).
|
|
52
|
+
- The same key set in every locale. The parity check fails the build when a key is missing.
|
|
48
53
|
|
|
49
54
|
---
|
|
50
55
|
|
|
51
|
-
##
|
|
56
|
+
## 4. UI strings versus business data
|
|
52
57
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
* **`app/data/*.ts`** — отвечает **за бизнес-данные и каталог**:
|
|
56
|
-
Список товаров, технические характеристики, список городов, база статей блога.
|
|
57
|
-
* **Типизация:** Данные из `app/data/` проверяются TypeScript-интерфейсами. Если пропущен перевод на один из языков, компилятор не пропустит билд в продакшн.
|
|
58
|
+
- `i18n/locales/*.ts`: interface text only. Button labels, form labels, navigation, error messages.
|
|
59
|
+
- `app/data/*.ts`: business data. Products, specifications, service areas, articles. Typed. Text fields that differ by language use an object keyed by locale, validated by the schema, so a missing translation breaks the build.
|
|
@@ -1,32 +1,33 @@
|
|
|
1
1
|
{
|
|
2
|
+
"_comment": "Locale template. Copy to i18n/locales/<code>.ts in your project and translate every value. Keys must match the base locale exactly.",
|
|
2
3
|
"nav": {
|
|
3
|
-
"home": "
|
|
4
|
-
"residential": "
|
|
5
|
-
"business": "
|
|
6
|
-
"mobility": "
|
|
7
|
-
"equipment": "
|
|
8
|
-
"service": "
|
|
9
|
-
"contact": "
|
|
4
|
+
"home": "Home",
|
|
5
|
+
"residential": "Residential",
|
|
6
|
+
"business": "Business",
|
|
7
|
+
"mobility": "Mobility",
|
|
8
|
+
"equipment": "Equipment",
|
|
9
|
+
"service": "Service",
|
|
10
|
+
"contact": "Contact"
|
|
10
11
|
},
|
|
11
12
|
"common": {
|
|
12
|
-
"viewProduct": "
|
|
13
|
-
"requestQuote": "
|
|
14
|
-
"calculate": "
|
|
15
|
-
"fromPrice": "
|
|
16
|
-
"close": "
|
|
17
|
-
"send": "
|
|
18
|
-
"success": "
|
|
13
|
+
"viewProduct": "View product",
|
|
14
|
+
"requestQuote": "Request a quote",
|
|
15
|
+
"calculate": "Calculate savings",
|
|
16
|
+
"fromPrice": "from",
|
|
17
|
+
"close": "Close",
|
|
18
|
+
"send": "Send",
|
|
19
|
+
"success": "Your request was sent"
|
|
19
20
|
},
|
|
20
21
|
"calc": {
|
|
21
|
-
"title": "
|
|
22
|
-
"billLabel": "
|
|
23
|
-
"yearlySavings": "
|
|
24
|
-
"recommendedPower": "
|
|
25
|
-
"paybackTime": "
|
|
22
|
+
"title": "Calculate your solar savings",
|
|
23
|
+
"billLabel": "How much do you pay for electricity per month?",
|
|
24
|
+
"yearlySavings": "Estimated yearly savings",
|
|
25
|
+
"recommendedPower": "Recommended capacity",
|
|
26
|
+
"paybackTime": "Estimated payback period"
|
|
26
27
|
},
|
|
27
28
|
"badges": {
|
|
28
|
-
"top": "
|
|
29
|
-
"new": "
|
|
30
|
-
"sale": "
|
|
29
|
+
"top": "Best seller",
|
|
30
|
+
"new": "New",
|
|
31
|
+
"sale": "Offer"
|
|
31
32
|
}
|
|
32
33
|
}
|
|
@@ -1,36 +1,37 @@
|
|
|
1
|
-
# 06
|
|
1
|
+
# 06 · Commercial models for energy projects (example)
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Example document from a Spanish solar company, 2025–2026. Market rules, subsidies and prices change. Verify every figure against current official sources before use.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
## 1.
|
|
7
|
+
## 1. Residential (B2C)
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
* В солнечные месяцы (май–сентябрь) в Андалусии панели производят больше, чем потребляет дом.
|
|
11
|
-
* Излишки отправляются в сеть, а энергокомпания (Octopus, Repsol, Próxima) начисляет евро на виртуальный счет;
|
|
12
|
-
* Зимой эти накопленные евро списываются в счет оплаты ночного электричества.
|
|
13
|
-
* **Результат для клиента:** Круглогодичный счет **0,00 € в фактуре**.
|
|
9
|
+
**Virtual battery.** In sunny months a home system produces more than the household uses. The surplus goes to the grid and is credited on the customer's account. In winter the credit offsets night-time consumption.
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
**Result for the customer:** a bill close to zero over the year, when credits match consumption.
|
|
12
|
+
|
|
13
|
+
**Energy communities.** Spanish rules (RD 244/2019) allow shared self-consumption between nearby homes. Offer it to terraced houses and communities as a shared installation with a per-home discount.
|
|
18
14
|
|
|
19
15
|
---
|
|
20
16
|
|
|
21
|
-
## 2.
|
|
17
|
+
## 2. Business (B2B)
|
|
18
|
+
|
|
19
|
+
**Power purchase agreement (PPA).** A company that does not want to spend its own capital can have a third party install the system on its roof. The company buys the energy at a fixed rate, below the grid tariff.
|
|
20
|
+
|
|
21
|
+
Explain the contract length, the rate, the escalation clause and who owns the system at the end. Do not present the rate as a saving without the tariff it is compared to.
|
|
22
|
+
|
|
23
|
+
**Solar carports.** Panels over car parks for hotels, warehouses and shops. Shade for customers and staff, plus charging points for fleet vehicles.
|
|
24
|
+
|
|
25
|
+
---
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
* Главная проблема директоров компаний: нежелание тратить 50 000 – 100 000 € оборотных средств;
|
|
25
|
-
* **Решение PPA:** Инвестор или Mi Luz Solar устанавливает электростанцию на крыше предприятия **за 0 € капиталовложений**.
|
|
26
|
-
* Предприятие просто покупает чистую энергию со своей же крыши по фиксированной низкой ставке (например, 0.08 €/кВт·ч вместо 0.19 €/кВт·ч из сети), экономя сотни тысяч евро.
|
|
27
|
+
## 3. Community and public buildings (B2A)
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
* Навесы из панелей над открытыми парковками отелей, складов, гипермаркетов и спорткомплексов;
|
|
30
|
-
* Тень для автомобилей клиентов от андалузского солнца + встроенные зарядные станции V2C для сотрудников и автопарка.
|
|
29
|
+
Public programmes can fund a large share of installations for shared buildings (lifts, garages, stairwell lighting). The share and the eligibility change by programme and year. State the programme name, the year and the source.
|
|
31
30
|
|
|
32
31
|
---
|
|
33
32
|
|
|
34
|
-
##
|
|
33
|
+
## 4. Rules for any offer
|
|
35
34
|
|
|
36
|
-
|
|
35
|
+
- Name the programme, the year and the official source.
|
|
36
|
+
- Show the price before and after any grant as two separate figures.
|
|
37
|
+
- Do not make a promise about a grant that is not yet approved.
|
|
@@ -1,50 +1,45 @@
|
|
|
1
|
-
# 06
|
|
1
|
+
# 06 · Contextual leads
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A visitor who has already used a calculator knows what they want. Contact actions should carry that context, so the first message is useful to both sides.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
## 1.
|
|
7
|
+
## 1. Contact link with context
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
### Стандарт DS7:
|
|
12
|
-
При клике на любую кнопку связи («Consultar en WhatsApp», «Pedir estudio») скрипт формирует динамическую ссылку с **полным контекстом расчета**:
|
|
9
|
+
A plain `wa.me/<number>` link leaves the visitor to write the first message, and many leave. Build the message from the visitor's last action:
|
|
13
10
|
|
|
14
11
|
```ts
|
|
15
|
-
const
|
|
12
|
+
const contactLink = (context: {
|
|
16
13
|
page: string
|
|
17
14
|
monthlyBill?: number
|
|
18
15
|
powerKw?: number
|
|
19
16
|
productId?: string
|
|
20
17
|
}) => {
|
|
21
|
-
const phone = '
|
|
22
|
-
let text = '
|
|
18
|
+
const phone = '[international number, digits only]'
|
|
19
|
+
let text = 'Hello, I would like information. '
|
|
23
20
|
if (context.monthlyBill) {
|
|
24
|
-
text += `
|
|
21
|
+
text += `My monthly bill is about ${context.monthlyBill} €; the estimate was ${context.powerKw} kW. `
|
|
25
22
|
}
|
|
26
23
|
if (context.productId) {
|
|
27
|
-
text += `
|
|
24
|
+
text += `I am interested in: ${context.productId}. `
|
|
28
25
|
}
|
|
29
|
-
text += '
|
|
30
|
-
|
|
26
|
+
text += 'Could you confirm availability and the grants that apply?'
|
|
31
27
|
return `https://wa.me/${phone}?text=${encodeURIComponent(text)}`
|
|
32
28
|
}
|
|
33
29
|
```
|
|
34
30
|
|
|
35
|
-
|
|
31
|
+
The visitor only has to press send. The message is in the visitor's language (from the i18n layer, not hard-coded).
|
|
36
32
|
|
|
37
33
|
---
|
|
38
34
|
|
|
39
|
-
## 2.
|
|
35
|
+
## 2. Summary document
|
|
40
36
|
|
|
41
|
-
|
|
42
|
-
* Прямо в браузере за 1 секунду формируется брендированный PDF с графиком окупаемости, перечнем оборудования и контактами;
|
|
43
|
-
* Условие получения — ввод телефона или email;
|
|
44
|
-
* Конверсия возрастает в 2–3 раза по сравнению с обычной формой обратного звонка.
|
|
37
|
+
After a calculation, offer a summary the visitor can keep: the inputs, the result, the equipment and the contact. Generate it in the browser. Ask for a phone number or email before the download, and say why.
|
|
45
38
|
|
|
46
39
|
---
|
|
47
40
|
|
|
48
|
-
## 3.
|
|
41
|
+
## 3. Offline queue
|
|
42
|
+
|
|
43
|
+
If the connection drops during a form submission, keep the data in `IndexedDB` (or `localStorage` for very small forms), show a neutral "saved, will be sent" message, and send it when the connection returns. A lead must not be lost because of a dropped connection.
|
|
49
44
|
|
|
50
|
-
|
|
45
|
+
Remove stored leads after the server confirms receipt.
|