bae705aa97
- Add NFC ePassport roadmap (ICAO 9303, eIDAS) - Add TensorFlow.js edge face detection (BlazeFace) - Add structured audit logger (GDPR-compliant) - Risk scoring support Part of KYC Apple Native UX v1.1.0
342 lines
9.5 KiB
Markdown
342 lines
9.5 KiB
Markdown
# Visual Design Audit — quiXzoom & Landvex
|
||
> Production-grade. No generic observations. Every finding must be implementable.
|
||
|
||
---
|
||
|
||
## STOP CONDITION
|
||
|
||
Revisionen är inte klar förrän:
|
||
|
||
- 0 horisontella overflow-fel finns kvar
|
||
- 0 inkonsekvenser mellan header/footer-versioner finns kvar
|
||
- 0 motstridiga siffror/claims finns kvar
|
||
- alla WCAG 2.2 AA-krav passerar
|
||
- alla fynd har en implementerbar fix med exakt selector + CSS
|
||
|
||
---
|
||
|
||
## FÖRBJUDNA UTDATA
|
||
|
||
Ej tillåtet:
|
||
|
||
- "looks good"
|
||
- "consider improving"
|
||
- "might benefit from"
|
||
- "increase spacing"
|
||
- "improve responsiveness"
|
||
- "spacing could be improved"
|
||
|
||
Varje observation måste sluta i:
|
||
|
||
```
|
||
selector: <exact CSS selector>
|
||
rotorsak: <root cause>
|
||
fix: <exact CSS property + value>
|
||
breakpoint: <exact px value if responsive>
|
||
```
|
||
|
||
Annars är fyndet ogiltigt och ska inte inkluderas.
|
||
|
||
---
|
||
|
||
## FLÖDE
|
||
|
||
### Fas 1 — Rendera & dokumentera
|
||
|
||
1. Öppna sidan i browser (desktop 1440px, mobil 390px)
|
||
2. Ta screenshot av hela sidan (fullPage)
|
||
3. Kör i konsolen:
|
||
```js
|
||
// Hitta alla overflow-element
|
||
(()=>{const r=[];document.querySelectorAll('*').forEach(el=>{if(el.scrollWidth>el.offsetWidth)r.push({el:el.tagName+'.'+[...el.classList].join('.'),w:el.scrollWidth,ow:el.offsetWidth})});return r})()
|
||
```
|
||
4. Kör Lighthouse (Performance + Accessibility + SEO) via browser
|
||
5. Kör axe-core för WCAG 2.2 AA
|
||
6. Dokumentera ALLA fel innan du skriver en rad CSS
|
||
|
||
### Fas 2 — Stack-identifiering (INGEN fråga till användaren)
|
||
|
||
Identifiera stacken autonomt:
|
||
|
||
```js
|
||
// I konsolen:
|
||
window.__NEXT_DATA__ // Next.js
|
||
window.__nuxt__ // Nuxt
|
||
window.React // React
|
||
document.querySelector('[data-reactroot]') // React
|
||
document.querySelector('[class*="tw-"]') // Tailwind
|
||
document.querySelector('[class*="css-"]') // CSS-in-JS (emotion/styled)
|
||
```
|
||
|
||
Kontrollera också:
|
||
- `<link rel="stylesheet">` href-mönster
|
||
- class-namnkonventioner (BEM, atomic, utility)
|
||
- `<script src>` bundle-namn
|
||
|
||
→ Rapportera stack som del av audit-header.
|
||
→ Fråga användaren **ENDAST** om stacken är ett intern proprietary system som inte går att identifiera med ovan.
|
||
|
||
### Fas 3 — Systematisk fix
|
||
|
||
Skriv CSS-fixar i exakt prioritetsordning:
|
||
|
||
1. Overflow/layout-krascher (blocking)
|
||
2. WCAG-fel (blocking)
|
||
3. Core Web Vitals (high impact)
|
||
4. Trust/Enterprise credibility (high impact)
|
||
5. SEO surface (medium impact)
|
||
6. Kosmetik (low impact)
|
||
|
||
---
|
||
|
||
## SEKTIONER
|
||
|
||
### A — Overflow & Layout
|
||
|
||
Kör overflow-detektorn (se Fas 1, steg 3).
|
||
|
||
För varje träff:
|
||
```
|
||
element: <selector>
|
||
scrollWidth: Xpx > offsetWidth: Ypx
|
||
rotorsak: [tex. img utan max-width, pre utan overflow, grid utan min-width:0]
|
||
fix: selector { overflow: hidden; } / max-width: 100%; / min-width: 0;
|
||
breakpoint: <px>
|
||
```
|
||
|
||
### B — Typography
|
||
|
||
Kontrollera:
|
||
- Line-length > 75ch på desktop → `max-width: 65ch`
|
||
- Font-size < 16px body → läs computed style
|
||
- Font-swap synlig → `font-display: swap` + `<link rel=preload>`
|
||
- FOUT/FOIT → dokumentera med filmstrip
|
||
|
||
```
|
||
selector: body
|
||
computed font-size: Xpx (expected: ≥16px)
|
||
fix: font-size: 1rem (16px)
|
||
```
|
||
|
||
### C — Spacing & Grid
|
||
|
||
- Kontrollera att spacing följer ett konsekvent system (4px/8px grid)
|
||
- Identifiera element med magic numbers (ex. `padding: 13px 17px`)
|
||
- Rapportera med computed values, inte antaganden
|
||
|
||
### D — Color & Contrast
|
||
|
||
Mät kontrastförhållande med:
|
||
```js
|
||
// Computed contrast via APCA eller WCAG AA formula
|
||
// Minsta godkänd: 4.5:1 (normal text), 3:1 (large text ≥18pt/14pt bold)
|
||
```
|
||
|
||
Rapportera varje fel:
|
||
```
|
||
element: .nav-link
|
||
foreground: #888888
|
||
background: #0a0a0a
|
||
ratio: 2.8:1 (required: 4.5:1)
|
||
fix: color: #a8a8a8; /* ratio: 4.6:1 */
|
||
```
|
||
|
||
### E — Responsivitet
|
||
|
||
Testa exakt på: 375px, 390px, 430px, 768px, 1024px, 1280px, 1440px, 1920px
|
||
|
||
För varje breakpoint — screenshot + overflow-scan.
|
||
|
||
### F — Interactive States
|
||
|
||
Kontrollera för alla klickbara element:
|
||
- `:hover` state definierad
|
||
- `:focus-visible` state med synlig outline (WCAG 2.4.11)
|
||
- `:active` state
|
||
- Disabled-state om relevant
|
||
|
||
```js
|
||
// Testa focus-visible
|
||
document.querySelectorAll('a,button,input,select,textarea').forEach(el=>{
|
||
const s = getComputedStyle(el,':focus-visible');
|
||
if(s.outlineWidth==='0px'&&s.boxShadow==='none') console.warn('no focus style',el)
|
||
})
|
||
```
|
||
|
||
### G — Images & Media
|
||
|
||
- Alla `<img>` har `width` + `height` attribut (CLS prevention)
|
||
- `loading="lazy"` på below-fold images
|
||
- `alt`-texter är beskrivande (inte tomma, inte "image")
|
||
- SVG har `role="img"` + `aria-label` eller är `aria-hidden="true"`
|
||
|
||
### H — Header & Footer Consistency
|
||
|
||
Kontrollera att header och footer är identiska på ALLA sidor:
|
||
- Logo
|
||
- Navigation items
|
||
- CTA-knappar
|
||
- Copyright-text och år
|
||
- Juridiska länkar
|
||
|
||
Rapportera varje avvikelse:
|
||
```
|
||
page: /methodology/
|
||
element: footer
|
||
avvikelse: saknar "Privacy Policy" länk (finns på /index)
|
||
fix: lägg till <a href="/privacy/">Privacy Policy</a> i footer nav
|
||
```
|
||
|
||
---
|
||
|
||
## K.1 — Performance & Core Web Vitals
|
||
|
||
Mät och rapportera:
|
||
|
||
- **LCP** (Largest Contentful Paint) — target < 2.5s
|
||
- **CLS** (Cumulative Layout Shift) — target < 0.1
|
||
- **INP** (Interaction to Next Paint) — target < 200ms
|
||
|
||
Identifiera alla visuella orsaker till:
|
||
- Layout shifts → `width`/`height` saknas på media, font-swap, dynamiskt injicerat innehåll
|
||
- Font swaps → FOUT, FOIT, `font-display` inte satt
|
||
- Image jumps → `aspect-ratio` saknas, lazy-load utan placeholder
|
||
- Counter animations → `will-change: transform`, reducera om `prefers-reduced-motion`
|
||
|
||
För varje problem:
|
||
```
|
||
metric: CLS / LCP / INP
|
||
impact: +0.XX CLS / +XXXms LCP
|
||
selector: <element>
|
||
rotorsak: <exakt orsak>
|
||
fix: <exakt CSS/HTML-attribut>
|
||
```
|
||
|
||
---
|
||
|
||
## K.2 — Trust & Enterprise Readiness
|
||
|
||
För quiXzoom och Landvex är trovärdighet lika viktig som design.
|
||
|
||
Kontrollera närvaro och kvalitet av:
|
||
|
||
- [ ] Kontaktuppgifter (adress, e-post, telefon om relevant)
|
||
- [ ] Organisationsinformation (org.nr, registrerat land, legal entity)
|
||
- [ ] Legal footer (© år, entity-namn, jurisdiktion)
|
||
- [ ] Privacy policy (länkad från footer + cookie-banner)
|
||
- [ ] Terms of service
|
||
- [ ] Methodology/how-it-works page
|
||
- [ ] Case studies eller proof-of-concept
|
||
- [ ] Uptime/status page
|
||
- [ ] Trust-badges (GDPR, Stripe, SSL)
|
||
- [ ] Named team eller tydlig company-sida
|
||
|
||
Flagga visuella signaler som får sajten att uppfattas som:
|
||
|
||
- **Startup prototype**: placeholder-text, "lorem ipsum", "coming soon" utan datum
|
||
- **Affiliate site**: överdrivna earning-claims utan kontext, inga juridiska disclaimers
|
||
- **Landing page only**: inga sekundära sidor i navigation, ingen intern länkning
|
||
|
||
För varje enterprise credibility-brist:
|
||
```
|
||
signal: saknar org.nr i footer
|
||
impact: ser ut som anonymous affiliate site
|
||
fix: lägg till "Landvex AB · Org.nr 559141-7042 · Tyresö, Sweden" i footer
|
||
selector: footer .legal-copy
|
||
```
|
||
|
||
Föreslå exakta komponenter som höjer enterprise-känslan:
|
||
- Trust bar (logotyper av integrations/partners)
|
||
- Security certifications
|
||
- Named press mentions
|
||
- Verifierbara testimonials (namn + roll + företag)
|
||
|
||
---
|
||
|
||
## K.3 — SEO Surface Audit
|
||
|
||
Identifiera visuella element som påverkar:
|
||
|
||
**Crawlability:**
|
||
- Text gömd bakom JavaScript-tabs utan SSR → Googlebot ser det inte
|
||
- Viktigt innehåll i `display:none` utan progressiv disclosure
|
||
- Bilder utan alt-text
|
||
|
||
**Entity Recognition:**
|
||
- H1 är unik per sida (kör: `document.querySelectorAll('h1').length`)
|
||
- Brand-namn nämns i H1 eller inom första 100 ord av body-text
|
||
- Schema-relaterat innehåll är visuellt synligt (inte bara i `<script type="application/ld+json">`)
|
||
|
||
**Topical Authority:**
|
||
- Interna länkar exponeras visuellt (crawlbara anchor-taggar, inga JavaScript-only navigationer)
|
||
- Viktiga entiteter (branschtermer, produktnamn) är synliga i rubriker och brödtext
|
||
- FAQ-innehåll är synligt i DOM utan JavaScript
|
||
|
||
För varje SEO-brist:
|
||
```
|
||
issue: FAQ-svar gömt bakom JS-toggle
|
||
impact: Google ser inte FAQ-innehåll, förlorar FAQ-rich-result
|
||
selector: .faq-answer[style="display:none"]
|
||
fix: använd <details>/<summary> (native, crawlbar) eller SSR-rendera med CSS toggle
|
||
```
|
||
|
||
**Rapportera alla designbeslut som försämrar SEO-signaler.**
|
||
|
||
---
|
||
|
||
## OUTPUT FORMAT
|
||
|
||
### Audit Header
|
||
```
|
||
URL: https://www.quixzoom.com/
|
||
Date: YYYY-MM-DD
|
||
Viewport tested: 1440px desktop / 390px mobile
|
||
Stack identified: [ramverk, CSS-approach]
|
||
Lighthouse scores: Performance XX | Accessibility XX | SEO XX | BP XX
|
||
WCAG 2.2 AA violations: N
|
||
Overflow elements found: N
|
||
```
|
||
|
||
### Per Finding
|
||
```
|
||
ID: A-001
|
||
Section: A — Overflow
|
||
Severity: BLOCKING / HIGH / MEDIUM / LOW
|
||
Page: /
|
||
Viewport: 390px mobile
|
||
Screenshot: [bifogad]
|
||
|
||
Observation: [exakt vad som är fel]
|
||
selector: nav .nav-links
|
||
rotorsak: flex-wrap: nowrap på container med overflow: visible
|
||
fix: .nav-links { flex-wrap: wrap; } eller overflow: hidden på parent
|
||
breakpoint: < 768px
|
||
metric impact: CLS +0.05 (layout reflow vid render)
|
||
```
|
||
|
||
### Summary Table
|
||
```
|
||
| ID | Sida | Severity | Sektion | Status |
|
||
|-------|------|----------|---------|--------|
|
||
| A-001 | / | BLOCKING | Overflow| OPEN |
|
||
| B-002 | / | HIGH | Typography | OPEN |
|
||
```
|
||
|
||
---
|
||
|
||
## SAJTER ATT AUDITERAS
|
||
|
||
1. https://www.quixzoom.com/ (alla undersidor i sitemap)
|
||
2. https://www.landvex.com/ (alla undersidor i sitemap)
|
||
|
||
Börja med startsidor desktop → mobil, sedan sub-sidor med `<200` ms LCP.
|
||
|
||
---
|
||
|
||
## NOTES
|
||
|
||
- quiXzoom: CloudFront CDN framför origin — testa med `curl -H "Cache-Control: no-cache"` för att se origin-svar vs cached
|
||
- Landvex: Direct nginx → test mot origin direkt via `curl -H "Host: www.landvex.com" http://127.0.0.1/`
|
||
- Valuta: **aldrig SEK** i copy — rapportera som BLOCKING om hittat
|
||
- Credits-siffror: 12–80 per mission är canonical — rapportera avvikelse som HIGH
|