# Gumirom v3 — Sell Like Crazy + Hormozi, magazin anvelope (MVP) și remedieri

Data: 2026-10-06 · Proiect: `gumirom/v3/app` (HTML + CSS + JS vanilla, fără build, urcat pe FTP)

## 1. Ce s-a cerut și ce presupun

**Cerut (utilizator):**
1. Inspectează aplicația și aplică metoda „Sell Like Crazy" (Sabri Suby) și metoda Hormozi.
2. Rezolvă tot ce e de rezolvat în aplicație.
3. MVP: magazin online pentru anvelope noi și second-hand — planificat și implementat.

**Presupuneri (sesiune în mod goal; nu am oprit lucrul pentru întrebări):**
- „Metoda" înseamnă aplicarea pe site: structura în 17 pași, Oferta Godfather, HVCO, garanții (Suby) + Ecuația valorii, Grand Slam Offer, denumire MAGIC, urgență/raritate reală (Hormozi).
- Site-ul rămâne static (fără server, fără bază de date), ca până acum: se urcă pe FTP. Comenzile din magazin pleacă pe **WhatsApp** (canal deja folosit pentru programări) sau telefon. Fără plată online în MVP.
- **Nu inventăm fapte.** Folosim doar ce e pe pagină: 4,4★/125 recenzii Google, prețuri, servicii, program, adresă, telefoane. Promisiunile noi (garanția «Fără vibrații») sunt marcate în cod și în documentație ca *PROPUNERE — de confirmat cu proprietarul*.
- Stocul de anvelope nu există încă: magazinul pornește cu un **catalog demonstrativ** marcat vizibil pe site („stoc demonstrativ") până la înlocuirea cu stocul real (un singur fișier: `js/stoc.js`).

Audit complet: `docs/audit-sell-like-crazy-hormozi.md` (scor actual 38/100).

## 2. Abordări pentru magazin (decizie)

| Abordare | Pro | Contra |
|---|---|---|
| **A. Static: catalog în `js/stoc.js` + coș în browser + comandă pe WhatsApp** (recomandat) | Aceeași arhitectură ca site-ul, fără server, fără risc de securitate, gata azi; proprietarul primește comanda direct pe telefon | Stocul se editează într-un fișier; fără plată online |
| B. PHP + admin + bază de date | Stoc editabil din browser, comenzi salvate | Necesită hosting PHP, autentificare, securitate; mult peste un MVP |
| C. Platformă externă (Shopify/WooCommerce) | Plăți, facturi | Cost lunar, alt design, iese din proiect |

**Ales: A.** Calea de upgrade spre B rămâne deschisă: datele au deja forma unui API (`{ demo, actualizat, produse: [...] }`).

## 3. Arhitectură

```
app/
  index.html          landing page restructurat pe cei 17 pași
  magazin.html        catalog + filtre + coș + finalizare comandă
  css/style.css       sistem de design existent + secțiuni noi
  css/shop.css        stiluri doar pentru magazin
  js/core.js          CONFIG + funcții pure partajate (UMD → window.Gumirom)
  js/stoc.js          datele catalogului (window.GUMIROM_STOC)
  js/main.js          interacțiuni pagină (header, meniu, hero, calculator, programare…)
  js/quiz.js          Testul de 60 de secunde (logică pură + DOM)
  js/shop.js          logică magazin (filtre, coș, totaluri, mesaj) + DOM
tests/                teste node:test pentru logica pură (în afara app/, nu se urcă)
docs/                 audit, spec, plan
```

Regula de izolare: **logica pură** (prețuri, program, sezon, filtre, coș, mesaje WhatsApp, scor test) stă în funcții fără DOM, expuse pe `window.Gumirom.*`, testate în Node. Partea de DOM doar citește/scrie elemente și apelează logica. Fiecare `init*()` iese liniștit dacă elementul lipsește, așa că `main.js` rulează pe ambele pagini.

Stil cod: ES5 (`var`, `function`), IIFE, comentarii scurte în română — ca în codul existent.

### 3.1 `core.js` — CONFIG și funcții partajate
- `CONFIG`: telefoane, WhatsApp, program, tarife (mutate din `main.js`), `offer` (nume sezoniere, garanții), `seasons`, `company` (gol → ascuns).
- `openState(date)` (mutat din main.js), `season(date)` → `'iarna' | 'vara' | 'drum'`.
- `quote({vehicle, service, rim, qty})` → `{ unit, total }` (logica calculatorului).
- `rimClass(inch)` → `'r1' | 'r2' | 'r3'` (13–16, 17–18, 19–21+), folosit de magazin pentru prețul montajului.
- `waUrl(text)` → `https://wa.me/<nr>?text=<encodeURIComponent(text)>` (o singură codare, corectă).
- `formatLei(n)` → „1.234 lei".
- `track(event, props)` → `dataLayer.push` dacă există + `CustomEvent('gumirom:track')`; altfel nimic.
- `storage.get/set` cu try/catch (modul privat / stocare blocată).

### 3.2 Sezon (urgență reală, Hormozi „seasonal urgency")
| Interval | Cheie | Nume ofertă (MAGIC) | Mesaj |
|---|---|---|---|
| 1 oct – 15 dec | `iarna` | Pachetul «Gata de Iarnă» | Sezonul anvelopelor de iarnă a început — programează-te acum, nu în ziua primei ninsori. |
| 15 mar – 15 mai | `vara` | Pachetul «Gata de Vară» | Sezonul anvelopelor de vară — programează schimbul înainte de aglomerație. |
| restul | `drum` | Pachetul «Gata de Drum» | Pană sau jantă îndoită? Sună — îți spunem prețul înainte. |

Fără cronometre, fără „ultimele locuri" inventate (practici comerciale incorecte, interzise în UE).

## 4. Landing page — structura nouă (17 pași)

| Ordine | Secțiune | Pași SLC / Hormozi | Ce conține |
|---|---|---|---|
| Hero | existent, rescris | 1–4, 16 | Apel: „Pentru șoferii din Gherla și împrejurimi"; H1 „Roți sigure. Preț spus dinainte."; subtitlu-mecanism; 3 bife (echilibrare inclusă, presiune verificată gratuit inclusiv rezerva, anvelope noi & SH pe stoc); CTA „Sună acum" + „Programează-te pe WhatsApp"; „Ce urmează" în 3 pași; rating + status live + mesaj sezon |
| 01 Te recunoști? | NOU | 5 | 4 scene concrete (prima ninsoare, vibrații, pană dimineața, jantă îndoită) + agitare + punte „Există o cale mai simplă" |
| 02 Servicii | existent | 6, 8 | Metoda «Gata de drum» în 3 pași (coloana fixă) + servicii cu beneficiu „ceea ce înseamnă" |
| 03 Oferta | NOU | 10–14 | Pachetul sezonier: stiva de valoare cu prețul real din CONFIG (4 roți × montaj), rațiunea, bonusuri, urgență sezon, CTA |
| 04 Garanții | NOU | 15 | «Prețul spus», «Roată verificată», «Fără vibrații» (propunere) + „de ce putem promite" |
| 05 Tarife | existent | 13 | Calculatorul (remediat) |
| 06 Magazin | NOU | 10, 14, I | Anvelope pe stoc: numărători (noi / SH), 3 produse recomandate, link spre `magazin.html` |
| 07 Testul de 60 de secunde | NOU | 4, I (HVCO) | 6 întrebări da/nu → verdict + recomandări + „Trimite rezultatul pe WhatsApp" + „Memento în calendar (.ics)" |
| 08 Recenzii | existent | 7, 9 | 4,4★ / 125 + credențiale reale |
| 09 Program | existent | 14 | Status live (se reîmprospătează) |
| 10 Programare | existent | 16 | Formular remediat, CTA „Trimite-mi programarea pe WhatsApp", „ce urmează" |
| 11 Întrebări | NOU | obiecții | 6 întrebări-răspuns din fapte existente (`<details>`) |
| 12 Contact | existent | — | Link direcții corect, hartă pe adresă |
| CTA final | existent, extins | 17 | Avertisment (costul amânării) + P.S. (ofertă + garanție + sezon) |
| Bară CTA mobil | NOU | 16 | Fixă jos pe < 768px după hero: „Sună" + „WhatsApp" |

Navigare desktop: Oferta · Servicii · Tarife · Magazin · Recenzii · Contact. Meniu mobil: + Test anvelope, Programare.

### 4.1 Testul de 60 de secunde (HVCO)
Întrebări (da/nu), fiecare cu greutate și sfat (conținut general, adevărat):
1. Profilul e aproape la nivelul indicatorilor de uzură (TWI)? — minimul legal e 1,6 mm; pentru iarnă se recomandă cel puțin 4 mm. (greutate 3)
2. Anvelopele au peste 6 ani (ultimele 4 cifre din codul DOT = săptămâna și anul)? — cauciucul se întărește și aderă mai slab pe frig. (2)
3. Vezi umflături, tăieturi sau fisuri pe flanc? — risc de explozie, verificare urgentă. (3)
4. Simți vibrații în volan la viteză? — de obicei echilibrare sau jantă îndoită. (2)
5. Umfli vreo roată mai des de o dată pe lună? — posibil cui, valvă sau jantă. (2)
6. Ai anvelope fără marcaj de iarnă (M+S / fulg de zăpadă) și vine iarna? — pe zăpadă, gheață sau polei sunt obligatorii în România. (2) — întrebarea apare doar în sezonul `iarna`.

Verdict după scor: 0 → „Totul pare în regulă" (memento de sezon); 1–3 → „Merită o verificare"; ≥ 4 sau orice întrebare cu greutate 3 → „Treci pe la vulcanizare cât mai repede". Mențiune: testul nu înlocuiește verificarea la atelier.
Ieșiri: mesaj WhatsApp precompletat cu problemele bifate; fișier `.ics` (memento all-day la următorul început de sezon strict după data curentă — 15 martie sau 1 octombrie — cu telefonul Gumirom în descriere).

## 5. Magazin (`magazin.html`)

**Date** (`js/stoc.js`):
```js
window.GUMIROM_STOC = {
  demo: true,                 // true → banner „stoc demonstrativ"
  actualizat: '2026-10-06',
  produse: [
    { id: 'sh-205-55-16-01', stare: 'sh', marca: 'Continental', model: 'WinterContact TS 860',
      latime: 205, profil: 55, janta: 16, sezon: 'iarna', indice: '91H',
      pret: 180, buc: 4, dot: 2022, profilMm: 6.5, note: 'Set de 4, uzură uniformă' }
  ]
};
```
Câmpuri: `stare` `'nou'|'sh'`, `sezon` `'vara'|'iarna'|'all'`, `pret` lei/bucată, `buc` stoc, `dot` an (opțional la noi), `profilMm` (obligatoriu la SH).

**Logica pură (`Gumirom.shop`)**:
- `normalize(produse)` → elimină intrările invalide (fără id/preț/dimensiune), adaugă `marime` „205/55 R16".
- `filter(produse, f)` cu `f = { stare, sezon, latime, profil, janta, q, sort }`; `sort`: `pret-asc` | `pret-desc` | `profil-desc`.
- `facets(produse)` → valorile disponibile pentru selecturi (lățimi/profile/jante sortate).
- Coș: `cartAdd(cart, produs, qty)`, `cartSet`, `cartRemove`, `cartReconcile(cart, produse)` (scoate ce nu mai există, limitează la stoc).
- `totals(cart, produse, { montaj })` → `{ linii, anvelope, montaj, total, buc }`; montaj = `CONFIG.prices.mount[rimClass(janta)]` × bucăți, doar dacă e bifat.
- `orderText(cart, produse, opts, client)` → text WhatsApp (linii, total, montaj, nume, telefon, zi preferată, „plata la atelier, după confirmare").
- `fromQuery(search)` / `toQuery(f)` → filtrele în URL (linkuri partajabile, linkuri din index).

**Interfață:**
- Antet cu titlu-promisiune: „Anvelope noi și second-hand, verificate. Cu montaj inclus în preț, dacă vrei." + banner demo (dacă `demo`).
- Bară filtre: Stare (Toate / Noi / SH), Sezon, Lățime / Profil / Jantă (selecturi din fațete), Sortare, buton „Resetează"; ajutor „Unde găsesc dimensiunea?" (`<details>`: 205/55 R16 pe flanc).
- Card produs: ilustrație SVG anvelopă cu dimensiunea (fără poze false), insigne Nou/SH + sezon, marcă/model, dimensiune + indice; la SH: „Profil X mm · DOT an · măsurat de noi"; preț/buc + preț pentru 4 (dacă stoc ≥ 4); raritate reală din date: „Ultimele N bucăți" dacă `buc ≤ 2`, „Set complet de 4" dacă `buc = 4` la SH; selector cantitate (1…stoc); „Adaugă în coș".
- Coș (sertar lateral, `role="dialog"`, Esc, focus): linii cu cantitate, bifă **„Cu montaj + echilibrare la Gumirom"** (implicit bifată — oferta Hormozi: pachet complet), bonusuri incluse (verificare presiune + valve), garanția «Prețul spus», total.
- Finalizare: nume, telefon, zi preferată (dacă montaj), detalii → „Trimite comanda pe WhatsApp" (+ link de rezervă dacă fereastra e blocată) sau „Comandă telefonic". Text: „Comanda devine fermă după confirmarea noastră. Plata se face la atelier."
- Coșul persistă în `localStorage` (try/catch; funcționează și fără).
- Stări goale: niciun rezultat → „Nu avem acum dimensiunea asta pe stoc — o aducem la comandă" + buton WhatsApp cu dimensiunea căutată (anvelope noi la comandă = promisiune existentă pe site).

## 6. Remedieri (bug-uri și calitate) — verificate în cod / browser

| # | Problemă | Dovadă | Remediere |
|---|---|---|---|
| F1 | Fără JS pagina e acoperită de preloader și conținutul `[data-reveal]` e invizibil | CSS: `.preloader` fix, `[data-reveal]{opacity:0}` ascunse doar de JS | Clasa `js` pe `<html>` setată inline în `<head>`; stilurile de ascundere doar sub `.js` |
| F2 | Rating afișat „0.0" / „0" fără JS sau înainte de animație | HTML `data-count` cu text `0.0` | Valorile reale în HTML („4,4", „125"); JS animează de la 0 doar când intră în ecran |
| F3 | Titlul hero spart pe caractere cu spații ` ` → nu se poate rupe pe rânduri; cititorul de ecran citește literă cu literă | `od -c` pe `main.js:96` | Spargere pe cuvinte (wrapper `nowrap`) cu spații normale; `aria-label` pe H1, conținut spart `aria-hidden` |
| F4 | `splitWords` șterge elementele inline din titluri | `main.js:102-123` | Elementele se păstrează |
| F5 | La 320px butonul CTA final iese din ecran (344px) și titlul final e tăiat | măsurat în browser | Butoane cu rupere de rând pe ecrane mici; `clamp` mai mic la titlul CTA |
| F6 | Mesajul WhatsApp e codat parțial (diacritice și spații necodate) | `main.js:683-690` | `Gumirom.waUrl(text)` cu o singură codare + link de rezervă |
| F7 | Formular: erorile nu sunt legate de câmpuri (a11y); se poate alege duminica (închis) | `main.js:649-677` | `aria-invalid` + `aria-describedby`; validare zi închisă din `CONFIG.schedule` |
| F8 | Calculator: pastilele „dezactivate" rămân accesibile din tastatură; „Număr roți" și la jante | `main.js:592-593` | `disabled` + `aria-pressed`; eticheta devine „Număr jante" |
| F9 | Statusul „Deschis/Închis" nu se actualizează dacă pagina rămâne deschisă | calculat o singură dată | Reîmprospătare la 60 s |
| F10 | JSON-LD cu `aggregateRating` pentru propria firmă (recenzii auto-servite / preluate din Google — neeligibile, risc de acțiune manuală) | `index.html:46-50` | Eliminat; adăugat `sameAs` (Facebook) |
| F11 | „Direcții" duce la linkul de partajare, nu la navigare; harta caută după nume | `index.html:491, 504` | URL Google Maps Directions cu adresa; harta caută „Gumirom, Strada Liviu Rebreanu 56, Gherla" |
| F12 | Meniul mobil lasă `body{overflow:hidden}` dacă fereastra trece pe desktop | `initMenu` | Închidere la `resize` ≥ 768px |
| F13 | Bucla de parallax rulează permanent (și după hero) | `initHeroParallax` | Calcul doar cât hero e vizibil |
| F14 | Preloaderul blochează conținutul până la 2,5 s la fiecare vizită (viteza = conversii) | `setTimeout(…, 2500)` | Maxim 1,2 s; sărit la vizitele repetate în aceeași sesiune |
| F15 | `html:focus-within` duplicat; ancorele intră sub headerul fix | `style.css:53-54` | Eliminat; `scroll-padding-top` |
| F16 | Anul din footer hardcodat | `index.html:537` | Setat din JS (fallback 2026 în HTML) |

## 7. Tratarea erorilor
- `stoc.js` lipsă sau invalid → magazinul afișează „Catalogul nu s-a putut încărca — sună-ne" + telefon; produsele invalide sunt ignorate individual.
- `localStorage` indisponibil → coș doar în memorie.
- `window.open` blocat → linkul WhatsApp apare în nota formularului.
- Fără JS → conținutul landing page-ului e complet vizibil; magazinul arată un mesaj `<noscript>` cu telefonul.

## 8. Testare
- **Unitar (Node 22, `node --test tests/`)**: `openState`, `season`, `quote`, `rimClass`, `waUrl` (diacritice, linii noi), `formatLei`; test: scor/verdict, `.ics`; magazin: `normalize`, `filter`, `facets`, coș (adăugare peste stoc, reconciliere), `totals` cu/fără montaj, `orderText`, `fromQuery/toQuery`.
- **Browser (Chrome, localhost:8082)**: fără erori în consolă pe ambele pagini; overflow la 320/375/768/1280 px; flux complet: test → WhatsApp URL; calculator; programare (validare duminică); magazin: filtrare, coș, montaj, comandă (URL WhatsApp generat — nu se trimite nimic); pagina cu JS dezactivat (conținut vizibil).

## 9. În afara scopului (YAGNI)
Plată online, cont de client, panou de administrare, livrare prin curier, pagini separate per produs, A/B testing automat, analytics de la terți. Toate rămân drumuri de upgrade documentate.
