Mobile traffic was breaking on narrow viewports because the header nav overflowed and several pages used desktop-only spacing. This adds a shared phone breakpoint, a hamburger menu, and scroll-to-top on route changes so footer and menu navigation always land at the top of the page. - Add --page-gutter and max-width 639px rules in base.css - AppHeader: hamburger panel on small screens; flat account links on mobile - AppFooter: stack footer links vertically on phones - Home, compose, edit order, orders, auth, and legal pages: tighter gutters and responsive layout (orders card actions stack; home grids single-column) - Router scrollBehavior: scroll to top on navigation; restore on browser back - Tests: AppHeader menu toggle, Router scrollBehavior, mobile Playwright checks Admin page is intentionally unchanged. Co-authored-by: Cursor <cursoragent@cursor.com>
1182 lines
31 KiB
Vue
1182 lines
31 KiB
Vue
<script setup lang="ts">
|
|
import { ref } from 'vue'
|
|
import { RouterLink } from 'vue-router'
|
|
import PlateInput from '@/components/PlateInput.vue'
|
|
import VehicleInfo from '@/components/VehicleInfo.vue'
|
|
import type { VehicleInfo as VehicleData } from '@/components/VehicleInfo.vue'
|
|
import { lookupVehicle } from '@/api/vehicles'
|
|
|
|
const useCases = [
|
|
{
|
|
variant: 'buy',
|
|
title: 'Vill köpa bilen',
|
|
description:
|
|
'Lämna ett vänligt bud eller dina kontaktuppgifter om du är intresserad av att köpa bilen, utan att stå kvar på parkeringen och vänta.',
|
|
templateName: 'Köpförfrågan',
|
|
},
|
|
{
|
|
variant: 'praise',
|
|
title: 'Vill säga något fint',
|
|
description:
|
|
'Beröm någon som uppenbarligen tar hand om sin bil. Ett oväntat brev som ofta uppskattas mer än man tror.',
|
|
templateName: 'Komplimang',
|
|
},
|
|
{
|
|
variant: 'tip',
|
|
title: 'Vill tipsa om något',
|
|
description:
|
|
'Säg till om trasig baklykta, slitna däck eller annat du märkt som ägaren kanske inte sett själv.',
|
|
templateName: 'Tips / servicebehov',
|
|
},
|
|
{
|
|
variant: 'driving',
|
|
title: 'Reagerade på körbeteende',
|
|
description:
|
|
'Om något i trafiken upprörde dig kan du nå föraren med ett sakligt och respektfullt meddelande, utan att eskalera på plats.',
|
|
templateName: 'Körbeteende',
|
|
},
|
|
{
|
|
variant: 'frustration',
|
|
title: 'Efter tuta eller irritation',
|
|
description:
|
|
'När det hettade till i trafiken kan ett lugnt brev vara bättre än att tuta eller gestikulera. Mallen hjälper dig att formulera det neutralt.',
|
|
templateName: 'Tuta / frustration',
|
|
},
|
|
{
|
|
variant: 'damage',
|
|
title: 'Orsakat en parkeringsskada',
|
|
description:
|
|
'Om du råkat skada bilen när du parkerade kan du be om ursäkt och lämna dina uppgifter så ni kan lösa det tillsammans.',
|
|
templateName: 'Mindre parkeringsskada',
|
|
},
|
|
] as const
|
|
|
|
const steps = [
|
|
{
|
|
number: 1,
|
|
variant: 'lookup',
|
|
title: 'Verifiera registreringsnumret',
|
|
description:
|
|
'Ange nummerplåten och kontrollera att märke och modell stämmer. Vi använder uppgifterna för att hitta rätt mottagare.',
|
|
},
|
|
{
|
|
number: 2,
|
|
variant: 'compose',
|
|
title: 'Skriv, granska och betala',
|
|
description:
|
|
'Välj en mall eller skriv fritt, justera texten och betala 49 kr via Swish. Du ser hela brevet innan det skickas.',
|
|
},
|
|
{
|
|
number: 3,
|
|
variant: 'send',
|
|
title: 'Vi postar brevet',
|
|
description:
|
|
'Efter betalning tar vi hand om utskick manuellt. Brevet postas vanligtvis inom några vardagar. I Mina beställningar ser du status och får spårningsnummer när det skickats.',
|
|
},
|
|
] as const
|
|
|
|
const trustPoints = [
|
|
{
|
|
variant: 'privacy',
|
|
title: 'Anonymt om du vill',
|
|
description:
|
|
'Du når bilägaren utan att automatiskt lämna ut namn, telefon eller adress. Vill du att de ska kunna svara lägger du till det i brevet.',
|
|
},
|
|
{
|
|
variant: 'convenience',
|
|
title: 'Registreringsnummer räcker',
|
|
description:
|
|
'Du behöver inte veta vem som äger bilen eller var personen bor. Skriv brevet här så sköter vi utskicket.',
|
|
},
|
|
{
|
|
variant: 'letter',
|
|
title: 'Fysiskt brev med spårning',
|
|
description:
|
|
'Meddelandet skickas som riktigt brev med posten, inte som SMS eller mejl. När brevet skickats kan du följa det med spårningsnummer.',
|
|
},
|
|
] as const
|
|
|
|
const plate = ref('')
|
|
const vehicle = ref<VehicleData | null>(null)
|
|
const notFound = ref(false)
|
|
const lookingUp = ref(false)
|
|
|
|
async function handleLookup(lookedUpPlate: string) {
|
|
lookingUp.value = true
|
|
notFound.value = false
|
|
vehicle.value = null
|
|
|
|
try {
|
|
const result = await lookupVehicle(lookedUpPlate)
|
|
vehicle.value = result
|
|
} catch (err: unknown) {
|
|
if (err instanceof Error && err.message.includes('Inget fordon')) {
|
|
notFound.value = true
|
|
} else {
|
|
vehicle.value = null
|
|
notFound.value = true
|
|
}
|
|
} finally {
|
|
lookingUp.value = false
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="home">
|
|
<section class="home__hero">
|
|
<div class="home__hero-glow" aria-hidden="true" />
|
|
|
|
<div class="home__hero-content">
|
|
<p class="home__eyebrow">Post till registreringsnummer</p>
|
|
<h1 class="home__headline">
|
|
Skicka ett brev<br />
|
|
<span class="home__headline-accent">till bilägaren</span>
|
|
</h1>
|
|
<p class="home__lead">
|
|
Skriv ditt meddelande och nå bilägaren via registreringsnumret, utan
|
|
att du behöver leta upp adress eller kontaktuppgifter själv.
|
|
</p>
|
|
<ul class="home__highlights">
|
|
<li>
|
|
<span class="home__highlight-icon" aria-hidden="true">
|
|
<svg viewBox="0 0 24 24" fill="none">
|
|
<path
|
|
d="M3 8l7.89 5.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"
|
|
stroke="currentColor"
|
|
stroke-width="1.75"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
/>
|
|
</svg>
|
|
</span>
|
|
Brev skickas med posten och kan spåras
|
|
</li>
|
|
<li>
|
|
<span class="home__highlight-icon" aria-hidden="true">
|
|
<svg viewBox="0 0 24 24" fill="none">
|
|
<path
|
|
d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
|
|
stroke="currentColor"
|
|
stroke-width="1.75"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
/>
|
|
</svg>
|
|
</span>
|
|
Anonymt åt båda håll. Bara det ni skriver i brevet delas
|
|
</li>
|
|
<li>
|
|
<span class="home__highlight-icon" aria-hidden="true">
|
|
<svg viewBox="0 0 24 24" fill="none">
|
|
<path
|
|
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
stroke="currentColor"
|
|
stroke-width="1.75"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
/>
|
|
</svg>
|
|
</span>
|
|
Enkelt att skriva och betala här. Vi sköter utskick och postgång
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="home__card">
|
|
<div class="home__card-head">
|
|
<p class="home__card-label">Kom igång</p>
|
|
<span class="home__price">49 kr</span>
|
|
</div>
|
|
<p class="home__card-hint">
|
|
Kontrollera att registreringsnumret stämmer. Vi slår upp bilen och
|
|
förbereder utskick till ägaren.
|
|
</p>
|
|
|
|
<PlateInput v-model="plate" @lookup="handleLookup" />
|
|
|
|
<VehicleInfo
|
|
:vehicle="vehicle"
|
|
:loading="lookingUp"
|
|
:not-found="notFound"
|
|
:plate="plate"
|
|
/>
|
|
|
|
<RouterLink
|
|
v-if="vehicle"
|
|
:to="{ name: 'compose', query: { plate } }"
|
|
class="btn btn--primary btn--lg home__cta"
|
|
>
|
|
Fortsätt till brevet
|
|
</RouterLink>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="home__uses">
|
|
<div class="home__uses-inner">
|
|
<p class="home__section-eyebrow">Varför folk skriver</p>
|
|
<h2 class="home__section-title">Vanliga anledningar</h2>
|
|
<p class="home__section-lead">
|
|
När du skriver brevet kan du välja en färdig mall och anpassa texten.
|
|
Här är vanliga situationer, kopplade till mallarna i tjänsten.
|
|
</p>
|
|
<div class="home__uses-grid">
|
|
<article
|
|
v-for="item in useCases"
|
|
:key="item.templateName"
|
|
class="home__use"
|
|
:class="`home__use--${item.variant}`"
|
|
>
|
|
<div
|
|
class="home__use-icon"
|
|
:class="`home__use-icon--${item.variant}`"
|
|
aria-hidden="true"
|
|
>
|
|
<svg
|
|
v-if="item.variant === 'buy'"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
>
|
|
<path
|
|
d="M7 17h10M7 17a2 2 0 01-2-2V9a2 2 0 012-2h10a2 2 0 012 2v6a2 2 0 01-2 2M7 17l-1 3m11-3l1 3M9 9h.01M15 9h.01"
|
|
stroke="currentColor"
|
|
stroke-width="1.75"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
/>
|
|
</svg>
|
|
<svg
|
|
v-else-if="item.variant === 'praise'"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
>
|
|
<path
|
|
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"
|
|
stroke="currentColor"
|
|
stroke-width="1.75"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
/>
|
|
</svg>
|
|
<svg
|
|
v-else-if="item.variant === 'tip'"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
>
|
|
<path
|
|
d="M9 18h6M10 22h4M12 2a7 7 0 017 7c0 2.38-1.19 4.47-3 5.74V17H8v-2.26C6.19 13.47 5 11.38 5 9a7 7 0 017-7z"
|
|
stroke="currentColor"
|
|
stroke-width="1.75"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
/>
|
|
</svg>
|
|
<svg
|
|
v-else-if="item.variant === 'driving'"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
>
|
|
<path
|
|
d="M12 2v4m0 12v4M4.93 4.93l2.83 2.83m8.48 8.48l2.83 2.83M2 12h4m12 0h4M4.93 19.07l2.83-2.83m8.48-8.48l2.83-2.83"
|
|
stroke="currentColor"
|
|
stroke-width="1.75"
|
|
stroke-linecap="round"
|
|
/>
|
|
</svg>
|
|
<svg
|
|
v-else-if="item.variant === 'frustration'"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
>
|
|
<path
|
|
d="M8 9h8M8 13h6M12 3a9 9 0 100 18 9 9 0 000-18z"
|
|
stroke="currentColor"
|
|
stroke-width="1.75"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
/>
|
|
</svg>
|
|
<svg v-else viewBox="0 0 24 24" fill="none">
|
|
<path
|
|
d="M12 9v2m0 4h.01M5.07 19h13.86c1.54 0 2.5-1.67 1.73-3L13.73 4c-.77-1.33-2.69-1.33-3.46 0L3.34 16c-.77 1.33.19 3 1.73 3z"
|
|
stroke="currentColor"
|
|
stroke-width="1.75"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
<h3>{{ item.title }}</h3>
|
|
<p>{{ item.description }}</p>
|
|
<p class="home__use-template">
|
|
<span class="home__use-template-label">Mall</span>
|
|
{{ item.templateName }}
|
|
</p>
|
|
</article>
|
|
|
|
<article class="home__use home__use--custom home__use--wide">
|
|
<div
|
|
class="home__use-icon home__use-icon--custom"
|
|
aria-hidden="true"
|
|
>
|
|
<svg viewBox="0 0 24 24" fill="none">
|
|
<path
|
|
d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"
|
|
stroke="currentColor"
|
|
stroke-width="1.75"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
<div class="home__use-wide-content">
|
|
<h3>Något helt annat?</h3>
|
|
<p>
|
|
Passar ingen mall? Välj
|
|
<strong>Fritt meddelande</strong> och skriv precis det du vill,
|
|
till exempel om parkering, grannskap eller något vi inte har en
|
|
färdig mall för. Du kan också utgå från valfri mall och ändra
|
|
texten fritt.
|
|
</p>
|
|
<p class="home__use-template">
|
|
<span class="home__use-template-label">Mall</span>
|
|
Fritt meddelande
|
|
</p>
|
|
</div>
|
|
</article>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="home__steps">
|
|
<div class="home__steps-inner">
|
|
<p class="home__section-eyebrow">Tre steg</p>
|
|
<h2 class="home__section-title">Så fungerar det</h2>
|
|
<p class="home__section-lead">
|
|
Du skriver och betalar här på några minuter. Därefter tar vi hand om
|
|
utskick och post, och håller dig uppdaterad under tiden.
|
|
</p>
|
|
<ol class="home__steps-list">
|
|
<li
|
|
v-for="step in steps"
|
|
:key="step.number"
|
|
class="home__step"
|
|
:class="`home__step--${step.variant}`"
|
|
>
|
|
<div class="home__step-head">
|
|
<div
|
|
class="home__step-icon"
|
|
:class="`home__step-icon--${step.variant}`"
|
|
aria-hidden="true"
|
|
>
|
|
<svg
|
|
v-if="step.variant === 'lookup'"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
>
|
|
<path
|
|
d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-4.172 4.172a2 2 0 01-2.828 0l-7-7A2 2 0 013 8v5c0 .512.195 1.024.586 1.414M7 7l3 3"
|
|
stroke="currentColor"
|
|
stroke-width="1.75"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
/>
|
|
</svg>
|
|
<svg
|
|
v-else-if="step.variant === 'compose'"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
>
|
|
<path
|
|
d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"
|
|
stroke="currentColor"
|
|
stroke-width="1.75"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
/>
|
|
</svg>
|
|
<svg v-else viewBox="0 0 24 24" fill="none">
|
|
<path
|
|
d="M3 8l7.89 5.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"
|
|
stroke="currentColor"
|
|
stroke-width="1.75"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
<span class="home__step-number">Steg {{ step.number }}</span>
|
|
</div>
|
|
<h3>{{ step.title }}</h3>
|
|
<p>{{ step.description }}</p>
|
|
</li>
|
|
</ol>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="home__trust">
|
|
<div class="home__trust-inner">
|
|
<p class="home__section-eyebrow home__trust-eyebrow">Integritet</p>
|
|
<h2 class="home__trust-title">Trygg hantering</h2>
|
|
<p class="home__section-lead home__trust-lead">
|
|
Bilhej är byggt för svenska registreringsnummer och svensk post. Här
|
|
är vad tjänsten faktiskt gör för dig.
|
|
</p>
|
|
<div class="home__trust-grid">
|
|
<article
|
|
v-for="point in trustPoints"
|
|
:key="point.title"
|
|
class="home__trust-item"
|
|
:class="`home__trust-item--${point.variant}`"
|
|
>
|
|
<div
|
|
class="home__trust-icon"
|
|
:class="`home__trust-icon--${point.variant}`"
|
|
aria-hidden="true"
|
|
>
|
|
<svg
|
|
v-if="point.variant === 'privacy'"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
>
|
|
<path
|
|
d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
|
|
stroke="currentColor"
|
|
stroke-width="1.75"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
/>
|
|
</svg>
|
|
<svg
|
|
v-else-if="point.variant === 'convenience'"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
>
|
|
<path
|
|
d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-4.172 4.172a2 2 0 01-2.828 0l-7-7A2 2 0 013 8v5c0 .512.195 1.024.586 1.414M7 7l3 3"
|
|
stroke="currentColor"
|
|
stroke-width="1.75"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
/>
|
|
</svg>
|
|
<svg v-else viewBox="0 0 24 24" fill="none">
|
|
<path
|
|
d="M3 8l7.89 5.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"
|
|
stroke="currentColor"
|
|
stroke-width="1.75"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
<h3>{{ point.title }}</h3>
|
|
<p>{{ point.description }}</p>
|
|
</article>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.home__hero {
|
|
position: relative;
|
|
display: grid;
|
|
grid-template-columns: 1.05fr 0.95fr;
|
|
gap: var(--space-3xl);
|
|
align-items: center;
|
|
max-width: 72rem;
|
|
margin: var(--space-lg) auto 0;
|
|
padding: var(--space-3xl) var(--space-xl);
|
|
background: linear-gradient(
|
|
145deg,
|
|
var(--color-surface) 0%,
|
|
#f8faff 45%,
|
|
var(--color-paper) 100%
|
|
);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: calc(var(--radius-xl) + 0.25rem);
|
|
box-shadow: var(--shadow-lg);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.home__hero-glow {
|
|
position: absolute;
|
|
top: -30%;
|
|
right: -5%;
|
|
width: 22rem;
|
|
height: 22rem;
|
|
background: radial-gradient(
|
|
circle,
|
|
rgba(29, 78, 216, 0.12) 0%,
|
|
transparent 70%
|
|
);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.home__hero-content {
|
|
position: relative;
|
|
}
|
|
|
|
.home__eyebrow {
|
|
display: inline-block;
|
|
font-size: 0.8125rem;
|
|
font-weight: 600;
|
|
letter-spacing: 0.04em;
|
|
text-transform: uppercase;
|
|
color: var(--color-primary-dark);
|
|
background: var(--color-primary-soft);
|
|
border: 1px solid #bfdbfe;
|
|
padding: 0.35rem 0.75rem;
|
|
border-radius: var(--radius-full);
|
|
margin: 0 0 var(--space-lg) 0;
|
|
}
|
|
|
|
.home__headline {
|
|
font-size: clamp(2.125rem, 5vw, 3.25rem);
|
|
font-weight: 800;
|
|
line-height: 1.08;
|
|
letter-spacing: -0.02em;
|
|
color: var(--color-ink);
|
|
margin: 0 0 var(--space-lg) 0;
|
|
}
|
|
|
|
.home__headline-accent {
|
|
color: var(--color-primary);
|
|
}
|
|
|
|
.home__lead {
|
|
font-size: 1.125rem;
|
|
color: var(--color-muted);
|
|
line-height: 1.75;
|
|
margin: 0 0 var(--space-xl) 0;
|
|
max-width: 32rem;
|
|
}
|
|
|
|
.home__highlights {
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.home__highlights li {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-sm);
|
|
font-size: 0.9375rem;
|
|
color: var(--color-ink);
|
|
}
|
|
|
|
.home__highlight-icon {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 1.75rem;
|
|
height: 1.75rem;
|
|
background: var(--color-surface);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: var(--radius-full);
|
|
color: var(--color-primary);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.home__highlight-icon svg {
|
|
width: 0.9375rem;
|
|
height: 0.9375rem;
|
|
}
|
|
|
|
.home__card {
|
|
position: relative;
|
|
background: var(--color-surface);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: var(--radius-xl);
|
|
padding: var(--space-xl);
|
|
box-shadow: var(--shadow-xl);
|
|
}
|
|
|
|
.home__card-head {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
gap: var(--space-md);
|
|
margin-bottom: var(--space-sm);
|
|
}
|
|
|
|
.home__card-label {
|
|
margin: 0;
|
|
font-size: 0.8125rem;
|
|
font-weight: 700;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.06em;
|
|
color: var(--color-muted);
|
|
}
|
|
|
|
.home__price {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
padding: 0.25rem 0.75rem;
|
|
font-size: 0.875rem;
|
|
font-weight: 700;
|
|
color: var(--color-primary-dark);
|
|
background: var(--color-primary-soft);
|
|
border: 1px solid #bfdbfe;
|
|
border-radius: var(--radius-full);
|
|
}
|
|
|
|
.home__card-hint {
|
|
margin: 0 0 var(--space-lg) 0;
|
|
font-size: 0.9375rem;
|
|
color: var(--color-muted);
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.home__cta {
|
|
display: flex;
|
|
margin-top: var(--space-lg);
|
|
}
|
|
|
|
.home__uses {
|
|
padding: var(--space-3xl) var(--space-lg);
|
|
}
|
|
|
|
.home__uses-inner,
|
|
.home__steps-inner {
|
|
max-width: 72rem;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.home__section-eyebrow {
|
|
margin: 0 0 var(--space-sm) 0;
|
|
text-align: center;
|
|
font-size: 0.8125rem;
|
|
font-weight: 600;
|
|
letter-spacing: 0.06em;
|
|
text-transform: uppercase;
|
|
color: var(--color-primary);
|
|
}
|
|
|
|
.home__section-title {
|
|
font-size: clamp(1.5rem, 3vw, 1.875rem);
|
|
font-weight: 800;
|
|
letter-spacing: -0.02em;
|
|
text-align: center;
|
|
margin: 0 0 var(--space-md) 0;
|
|
color: var(--color-ink);
|
|
}
|
|
|
|
.home__section-lead {
|
|
max-width: 36rem;
|
|
margin: 0 auto var(--space-2xl);
|
|
text-align: center;
|
|
font-size: 1rem;
|
|
color: var(--color-muted);
|
|
line-height: 1.7;
|
|
}
|
|
|
|
.home__uses-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, 1fr);
|
|
gap: var(--space-lg);
|
|
}
|
|
|
|
.home__use {
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
background: var(--color-surface);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: var(--radius-xl);
|
|
padding: var(--space-xl);
|
|
box-shadow: var(--shadow-card);
|
|
overflow: hidden;
|
|
transition:
|
|
transform var(--transition-base),
|
|
box-shadow var(--transition-base),
|
|
border-color var(--transition-base);
|
|
}
|
|
|
|
.home__use::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 4px;
|
|
background: var(--use-accent);
|
|
}
|
|
|
|
.home__use:hover {
|
|
transform: translateY(-3px);
|
|
box-shadow: var(--shadow-lg);
|
|
border-color: var(--use-border);
|
|
}
|
|
|
|
.home__use--buy {
|
|
--use-accent: linear-gradient(90deg, #1d4ed8, #60a5fa);
|
|
--use-border: #93c5fd;
|
|
}
|
|
|
|
.home__use--praise {
|
|
--use-accent: linear-gradient(90deg, #0f766e, #2dd4bf);
|
|
--use-border: #5eead4;
|
|
}
|
|
|
|
.home__use--tip {
|
|
--use-accent: linear-gradient(90deg, #b45309, #fbbf24);
|
|
--use-border: #fcd34d;
|
|
}
|
|
|
|
.home__use--driving {
|
|
--use-accent: linear-gradient(90deg, #4338ca, #818cf8);
|
|
--use-border: #a5b4fc;
|
|
}
|
|
|
|
.home__use--frustration {
|
|
--use-accent: linear-gradient(90deg, #c2410c, #fb923c);
|
|
--use-border: #fdba74;
|
|
}
|
|
|
|
.home__use--damage {
|
|
--use-accent: linear-gradient(90deg, #be123c, #fb7185);
|
|
--use-border: #fda4af;
|
|
}
|
|
|
|
.home__use--custom {
|
|
--use-accent: linear-gradient(90deg, #475569, #94a3b8);
|
|
--use-border: #cbd5e1;
|
|
}
|
|
|
|
.home__use--wide {
|
|
grid-column: 1 / -1;
|
|
flex-direction: row;
|
|
align-items: flex-start;
|
|
gap: var(--space-lg);
|
|
}
|
|
|
|
.home__use-wide-content {
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
|
|
.home__use-icon {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 3.5rem;
|
|
height: 3.5rem;
|
|
border-radius: 1rem;
|
|
margin-bottom: var(--space-md);
|
|
flex-shrink: 0;
|
|
box-shadow: 0 10px 24px rgba(15, 23, 42, 0.12);
|
|
}
|
|
|
|
.home__use--wide .home__use-icon {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.home__use-icon svg {
|
|
width: 1.625rem;
|
|
height: 1.625rem;
|
|
}
|
|
|
|
.home__use-icon--buy {
|
|
background: linear-gradient(135deg, #dbeafe 0%, #eff6ff 100%);
|
|
color: #1d4ed8;
|
|
border: 1px solid #93c5fd;
|
|
}
|
|
|
|
.home__use-icon--praise {
|
|
background: linear-gradient(135deg, #ccfbf1 0%, #ecfeff 100%);
|
|
color: #0f766e;
|
|
border: 1px solid #5eead4;
|
|
}
|
|
|
|
.home__use-icon--tip {
|
|
background: linear-gradient(135deg, #fef3c7 0%, #fffbeb 100%);
|
|
color: #b45309;
|
|
border: 1px solid #fcd34d;
|
|
}
|
|
|
|
.home__use-icon--driving {
|
|
background: linear-gradient(135deg, #e0e7ff 0%, #eef2ff 100%);
|
|
color: #4338ca;
|
|
border: 1px solid #a5b4fc;
|
|
}
|
|
|
|
.home__use-icon--frustration {
|
|
background: linear-gradient(135deg, #ffedd5 0%, #fff7ed 100%);
|
|
color: #c2410c;
|
|
border: 1px solid #fdba74;
|
|
}
|
|
|
|
.home__use-icon--damage {
|
|
background: linear-gradient(135deg, #ffe4e6 0%, #fff1f2 100%);
|
|
color: #be123c;
|
|
border: 1px solid #fda4af;
|
|
}
|
|
|
|
.home__use-icon--custom {
|
|
background: linear-gradient(135deg, #e2e8f0 0%, #f8fafc 100%);
|
|
color: #475569;
|
|
border: 1px solid #cbd5e1;
|
|
}
|
|
|
|
.home__use h3 {
|
|
margin: 0 0 var(--space-sm) 0;
|
|
font-size: 1.0625rem;
|
|
color: var(--color-ink);
|
|
}
|
|
|
|
.home__use p {
|
|
margin: 0;
|
|
font-size: 0.9375rem;
|
|
color: var(--color-muted);
|
|
line-height: 1.65;
|
|
}
|
|
|
|
.home__use-template {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--space-sm);
|
|
margin-top: auto;
|
|
padding-top: var(--space-md);
|
|
font-size: 0.8125rem;
|
|
font-weight: 600;
|
|
color: var(--color-ink);
|
|
}
|
|
|
|
.home__use-template-label {
|
|
display: inline-flex;
|
|
padding: 0.15rem 0.5rem;
|
|
font-size: 0.6875rem;
|
|
font-weight: 700;
|
|
letter-spacing: 0.05em;
|
|
text-transform: uppercase;
|
|
color: var(--color-primary-dark);
|
|
background: var(--color-primary-soft);
|
|
border: 1px solid #bfdbfe;
|
|
border-radius: var(--radius-full);
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.home__uses-grid {
|
|
grid-template-columns: repeat(3, 1fr);
|
|
}
|
|
}
|
|
|
|
.home__steps {
|
|
padding: var(--space-3xl) var(--space-lg);
|
|
background: linear-gradient(
|
|
180deg,
|
|
transparent 0%,
|
|
rgba(219, 234, 254, 0.22) 50%,
|
|
transparent 100%
|
|
);
|
|
}
|
|
|
|
.home__steps-list {
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 0;
|
|
display: grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
gap: var(--space-lg);
|
|
}
|
|
|
|
.home__step {
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
background: var(--color-surface);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: var(--radius-xl);
|
|
padding: var(--space-xl);
|
|
text-align: left;
|
|
box-shadow: var(--shadow-card);
|
|
overflow: hidden;
|
|
transition:
|
|
transform var(--transition-base),
|
|
box-shadow var(--transition-base),
|
|
border-color var(--transition-base);
|
|
}
|
|
|
|
.home__step::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 4px;
|
|
background: var(--step-accent);
|
|
}
|
|
|
|
.home__step:hover {
|
|
transform: translateY(-3px);
|
|
box-shadow: var(--shadow-lg);
|
|
border-color: var(--step-border);
|
|
}
|
|
|
|
.home__step--lookup {
|
|
--step-accent: linear-gradient(90deg, #1d4ed8, #60a5fa);
|
|
--step-border: #93c5fd;
|
|
}
|
|
|
|
.home__step--compose {
|
|
--step-accent: linear-gradient(90deg, #4338ca, #818cf8);
|
|
--step-border: #a5b4fc;
|
|
}
|
|
|
|
.home__step--send {
|
|
--step-accent: linear-gradient(90deg, #0f766e, #2dd4bf);
|
|
--step-border: #5eead4;
|
|
}
|
|
|
|
.home__step-head {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: var(--space-md);
|
|
margin-bottom: var(--space-md);
|
|
}
|
|
|
|
.home__step-icon {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 3.25rem;
|
|
height: 3.25rem;
|
|
border-radius: 1rem;
|
|
box-shadow: 0 10px 24px rgba(15, 23, 42, 0.12);
|
|
}
|
|
|
|
.home__step-icon svg {
|
|
width: 1.5rem;
|
|
height: 1.5rem;
|
|
}
|
|
|
|
.home__step-icon--lookup {
|
|
background: linear-gradient(135deg, #dbeafe 0%, #eff6ff 100%);
|
|
color: #1d4ed8;
|
|
border: 1px solid #93c5fd;
|
|
}
|
|
|
|
.home__step-icon--compose {
|
|
background: linear-gradient(135deg, #e0e7ff 0%, #eef2ff 100%);
|
|
color: #4338ca;
|
|
border: 1px solid #a5b4fc;
|
|
}
|
|
|
|
.home__step-icon--send {
|
|
background: linear-gradient(135deg, #ccfbf1 0%, #ecfeff 100%);
|
|
color: #0f766e;
|
|
border: 1px solid #5eead4;
|
|
}
|
|
|
|
.home__step-number {
|
|
display: inline-flex;
|
|
padding: 0.25rem 0.75rem;
|
|
font-size: 0.75rem;
|
|
font-weight: 700;
|
|
letter-spacing: 0.04em;
|
|
text-transform: uppercase;
|
|
color: var(--color-primary-dark);
|
|
background: var(--color-primary-soft);
|
|
border: 1px solid #bfdbfe;
|
|
border-radius: var(--radius-full);
|
|
}
|
|
|
|
.home__step h3 {
|
|
margin: 0 0 var(--space-sm) 0;
|
|
font-size: 1.0625rem;
|
|
color: var(--color-ink);
|
|
}
|
|
|
|
.home__step p {
|
|
margin: 0;
|
|
font-size: 0.9375rem;
|
|
color: var(--color-muted);
|
|
line-height: 1.65;
|
|
}
|
|
|
|
.home__trust {
|
|
padding: 0 var(--space-lg) var(--space-3xl);
|
|
}
|
|
|
|
.home__trust-inner {
|
|
max-width: 72rem;
|
|
margin: 0 auto;
|
|
padding: var(--space-2xl);
|
|
background: linear-gradient(
|
|
135deg,
|
|
var(--color-primary-soft) 0%,
|
|
#eef2ff 100%
|
|
);
|
|
border: 1px solid #bfdbfe;
|
|
border-radius: var(--radius-xl);
|
|
}
|
|
|
|
.home__trust-eyebrow {
|
|
color: var(--color-primary-dark);
|
|
}
|
|
|
|
.home__trust-title {
|
|
margin: 0 0 var(--space-md) 0;
|
|
text-align: center;
|
|
font-size: clamp(1.5rem, 3vw, 1.875rem);
|
|
font-weight: 800;
|
|
letter-spacing: -0.02em;
|
|
color: var(--color-primary-dark);
|
|
}
|
|
|
|
.home__trust-lead {
|
|
margin-bottom: var(--space-2xl);
|
|
color: var(--color-primary-dark);
|
|
opacity: 0.85;
|
|
}
|
|
|
|
.home__trust-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
gap: var(--space-lg);
|
|
}
|
|
|
|
.home__trust-item {
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
gap: 0;
|
|
background: var(--color-surface);
|
|
border: 1px solid var(--color-border);
|
|
border-radius: var(--radius-xl);
|
|
padding: var(--space-xl);
|
|
box-shadow: var(--shadow-card);
|
|
overflow: hidden;
|
|
transition:
|
|
transform var(--transition-base),
|
|
box-shadow var(--transition-base),
|
|
border-color var(--transition-base);
|
|
}
|
|
|
|
.home__trust-item::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 4px;
|
|
background: var(--trust-accent);
|
|
}
|
|
|
|
.home__trust-item:hover {
|
|
transform: translateY(-3px);
|
|
box-shadow: var(--shadow-lg);
|
|
border-color: var(--trust-border);
|
|
}
|
|
|
|
.home__trust-item--privacy {
|
|
--trust-accent: linear-gradient(90deg, #4338ca, #818cf8);
|
|
--trust-border: #a5b4fc;
|
|
}
|
|
|
|
.home__trust-item--convenience {
|
|
--trust-accent: linear-gradient(90deg, #1d4ed8, #60a5fa);
|
|
--trust-border: #93c5fd;
|
|
}
|
|
|
|
.home__trust-item--letter {
|
|
--trust-accent: linear-gradient(90deg, #0f766e, #2dd4bf);
|
|
--trust-border: #5eead4;
|
|
}
|
|
|
|
.home__trust-icon {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 3.25rem;
|
|
height: 3.25rem;
|
|
border-radius: 1rem;
|
|
margin-bottom: var(--space-md);
|
|
box-shadow: 0 10px 24px rgba(15, 23, 42, 0.12);
|
|
}
|
|
|
|
.home__trust-icon svg {
|
|
width: 1.5rem;
|
|
height: 1.5rem;
|
|
}
|
|
|
|
.home__trust-icon--privacy {
|
|
background: linear-gradient(135deg, #e0e7ff 0%, #eef2ff 100%);
|
|
color: #4338ca;
|
|
border: 1px solid #a5b4fc;
|
|
}
|
|
|
|
.home__trust-icon--convenience {
|
|
background: linear-gradient(135deg, #dbeafe 0%, #eff6ff 100%);
|
|
color: #1d4ed8;
|
|
border: 1px solid #93c5fd;
|
|
}
|
|
|
|
.home__trust-icon--letter {
|
|
background: linear-gradient(135deg, #ccfbf1 0%, #ecfeff 100%);
|
|
color: #0f766e;
|
|
border: 1px solid #5eead4;
|
|
}
|
|
|
|
.home__trust-item h3 {
|
|
margin: 0 0 var(--space-sm) 0;
|
|
font-size: 1.0625rem;
|
|
color: var(--color-ink);
|
|
}
|
|
|
|
.home__trust-item p {
|
|
margin: 0;
|
|
font-size: 0.9375rem;
|
|
color: var(--color-muted);
|
|
line-height: 1.65;
|
|
}
|
|
|
|
@media (max-width: 639px) {
|
|
.home__hero {
|
|
grid-template-columns: 1fr;
|
|
gap: var(--space-xl);
|
|
padding: var(--space-xl) var(--page-gutter);
|
|
margin-top: 0;
|
|
border-radius: 0;
|
|
border-left: none;
|
|
border-right: none;
|
|
}
|
|
|
|
.home__headline {
|
|
font-size: clamp(1.875rem, 6vw, 2.75rem);
|
|
}
|
|
|
|
.home__uses-grid,
|
|
.home__steps-list,
|
|
.home__trust-grid {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.home__use--wide {
|
|
flex-direction: column;
|
|
}
|
|
|
|
.home__use--wide .home__use-icon {
|
|
margin-bottom: var(--space-md);
|
|
}
|
|
|
|
.home__uses,
|
|
.home__steps,
|
|
.home__trust {
|
|
padding-inline: var(--page-gutter);
|
|
}
|
|
|
|
.home__trust-inner {
|
|
padding: var(--space-lg);
|
|
}
|
|
}
|
|
</style>
|