242 lines
13 KiB
Plaintext
242 lines
13 KiB
Plaintext
<% content_for :title, "#{@listing[:title]} | Forecourt" %>
|
|
|
|
<div data-controller="listing-puzzle" class="min-h-screen bg-zinc-50 text-zinc-900">
|
|
<div data-listing-puzzle-target="hintPanel" class="fixed bottom-5 right-5 z-50 hidden w-[22rem] rounded-3xl border border-zinc-200 bg-white p-5 shadow-2xl shadow-zinc-900/15">
|
|
<div class="flex items-start justify-between gap-4">
|
|
<div>
|
|
<p class="text-xs font-semibold uppercase tracking-[0.24em] text-zinc-500">QA Drawer</p>
|
|
<h2 class="mt-1 text-lg font-semibold text-zinc-950">Subtle nudge unlocked</h2>
|
|
</div>
|
|
<button type="button" data-action="listing-puzzle#dismissHint" class="rounded-full border border-zinc-200 px-2.5 py-1 text-sm text-zinc-500 transition hover:border-zinc-300 hover:text-zinc-700">Close</button>
|
|
</div>
|
|
<p class="mt-3 text-sm leading-6 text-zinc-600">
|
|
The stock page has clues in captions, checklists, page data, and repeating IDs. Devtools will help, and one local-only review path is still wired into the page controller:
|
|
<span data-listing-puzzle-target="reviewPath" class="font-mono text-xs text-zinc-900"></span>
|
|
</p>
|
|
<p class="mt-3 text-xs text-zinc-500">Logo taps tracked: <span data-listing-puzzle-target="progress">0/5</span></p>
|
|
</div>
|
|
|
|
<header class="border-b border-zinc-200 bg-white/90 backdrop-blur">
|
|
<div class="mx-auto flex max-w-7xl items-center justify-between px-6 py-4 lg:px-8">
|
|
<button type="button" data-action="listing-puzzle#tapLogo" class="inline-flex items-center gap-3 rounded-full border border-zinc-200 px-4 py-2 text-left transition hover:border-zinc-300 hover:bg-zinc-50">
|
|
<span class="flex h-9 w-9 items-center justify-center rounded-full bg-zinc-950 text-sm font-semibold text-white">M</span>
|
|
<span>
|
|
<span class="block text-sm font-semibold text-zinc-950">Forecourt</span>
|
|
<span class="block text-xs text-zinc-500">Specialist sports and GT stock</span>
|
|
</span>
|
|
</button>
|
|
|
|
<div class="hidden items-center gap-3 md:flex">
|
|
<span class="rounded-full border border-emerald-200 bg-emerald-50 px-3 py-1 text-xs font-medium text-emerald-700">Dealer approved</span>
|
|
<span class="rounded-full border border-zinc-200 px-3 py-1 text-xs font-medium text-zinc-600">Price reduced this week</span>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<main class="mx-auto max-w-7xl px-6 py-8 lg:px-8 lg:py-10">
|
|
<section class="border-b border-zinc-200 pb-10">
|
|
<div class="flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between">
|
|
<div>
|
|
<p class="text-xs font-semibold uppercase tracking-[0.24em] text-zinc-500">Stock FC-718-421</p>
|
|
<h1 class="mt-2 text-4xl font-semibold tracking-tight text-zinc-950"><%= @listing[:title] %></h1>
|
|
<p class="mt-3 max-w-3xl text-sm leading-6 text-zinc-600"><%= @listing[:subtitle] %></p>
|
|
</div>
|
|
<div class="flex flex-wrap gap-3">
|
|
<div class="rounded-2xl border border-zinc-200 bg-white px-4 py-3">
|
|
<p class="text-xs font-medium uppercase tracking-[0.2em] text-zinc-500">Mileage</p>
|
|
<p class="mt-1 text-sm font-semibold text-zinc-900"><%= @listing[:mileage] %></p>
|
|
</div>
|
|
<div class="rounded-2xl border border-zinc-200 bg-white px-4 py-3">
|
|
<p class="text-xs font-medium uppercase tracking-[0.2em] text-zinc-500">Location</p>
|
|
<p class="mt-1 text-sm font-semibold text-zinc-900"><%= @listing[:location] %></p>
|
|
</div>
|
|
<div class="rounded-2xl border border-zinc-200 bg-white px-4 py-3">
|
|
<p class="text-xs font-medium uppercase tracking-[0.2em] text-zinc-500">MOT</p>
|
|
<p class="mt-1 text-sm font-semibold text-zinc-900"><%= @listing[:mot_status] %></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-8 grid gap-10 lg:grid-cols-[minmax(0,1.6fr)_minmax(18rem,0.95fr)]">
|
|
<div>
|
|
<figure>
|
|
<img
|
|
src="<%= @listing[:hero_image] %>"
|
|
alt="Front three-quarter studio view of the graphite blue 2021 Porsche 718 Cayman S"
|
|
class="aspect-[16/10] w-full rounded-3xl object-cover shadow-xl shadow-zinc-900/10"
|
|
>
|
|
<figcaption class="mt-3 text-sm text-zinc-500"><%= @listing[:image_caption] %></figcaption>
|
|
</figure>
|
|
|
|
<div class="mt-4 grid gap-3 sm:grid-cols-3">
|
|
<% @listing[:gallery].each_with_index do |image, index| %>
|
|
<img
|
|
src="<%= image %>"
|
|
alt="Gallery photo <%= index + 1 %> of the 2021 Porsche 718 Cayman S"
|
|
loading="lazy"
|
|
class="aspect-[4/3] w-full rounded-2xl object-cover"
|
|
>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
|
|
<aside class="lg:pl-4">
|
|
<div class="sticky top-6 rounded-3xl border border-zinc-200 bg-white p-6 shadow-xl shadow-zinc-900/5">
|
|
<div class="flex items-baseline justify-between gap-4">
|
|
<div>
|
|
<p class="text-xs font-semibold uppercase tracking-[0.24em] text-zinc-500">Price</p>
|
|
<p class="mt-2 text-4xl font-semibold tracking-tight text-zinc-950"><%= @listing[:price] %></p>
|
|
</div>
|
|
<p class="text-sm font-medium text-zinc-500"><%= @listing[:payment] %></p>
|
|
</div>
|
|
|
|
<div class="mt-6 space-y-3">
|
|
<button class="inline-flex w-full items-center justify-center rounded-full bg-zinc-950 px-5 py-3 text-sm font-semibold text-white transition hover:bg-zinc-800">Book a viewing</button>
|
|
<button class="inline-flex w-full items-center justify-center rounded-full border border-zinc-200 px-5 py-3 text-sm font-semibold text-zinc-900 transition hover:border-zinc-300 hover:bg-zinc-50">Request video walkaround</button>
|
|
</div>
|
|
|
|
<dl class="mt-6 grid gap-4 border-t border-zinc-200 pt-6 text-sm text-zinc-600">
|
|
<div class="flex items-center justify-between gap-4">
|
|
<dt>VIN</dt>
|
|
<dd class="font-medium text-zinc-900"><%= @listing[:vin] %></dd>
|
|
</div>
|
|
<div class="flex items-center justify-between gap-4">
|
|
<dt>Stock</dt>
|
|
<dd class="font-medium text-zinc-900"><%= @listing[:stock_number] %></dd>
|
|
</div>
|
|
<div class="flex items-center justify-between gap-4">
|
|
<dt>Exterior</dt>
|
|
<dd class="font-medium text-zinc-900"><%= @listing[:exterior] %></dd>
|
|
</div>
|
|
<div class="flex items-center justify-between gap-4">
|
|
<dt>Interior</dt>
|
|
<dd class="font-medium text-zinc-900"><%= @listing[:interior] %></dd>
|
|
</div>
|
|
</dl>
|
|
|
|
<div class="mt-6 border-t border-zinc-200 pt-6">
|
|
<p class="text-xs font-semibold uppercase tracking-[0.24em] text-zinc-500">Dealership</p>
|
|
<p class="mt-2 text-lg font-semibold text-zinc-950"><%= @listing[:dealer_name] %></p>
|
|
<p class="mt-1 text-sm text-zinc-600"><%= @listing[:dealer_tagline] %></p>
|
|
<div class="mt-4 space-y-2 text-sm text-zinc-600">
|
|
<p><%= @listing[:dealer_since] %></p>
|
|
<p><%= @listing[:dealer_hours] %></p>
|
|
<p><%= @listing[:dealer_address] %></p>
|
|
<p class="font-medium text-zinc-900"><%= @listing[:dealer_contact] %></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="grid gap-12 border-b border-zinc-200 py-10 lg:grid-cols-[minmax(0,1.25fr)_minmax(18rem,0.75fr)]">
|
|
<div>
|
|
<p class="text-xs font-semibold uppercase tracking-[0.24em] text-zinc-500">Overview</p>
|
|
<div class="mt-4 space-y-4 text-sm leading-7 text-zinc-700">
|
|
<% @listing[:overview].each do |paragraph| %>
|
|
<p><%= paragraph %></p>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<p class="text-xs font-semibold uppercase tracking-[0.24em] text-zinc-500">Highlights</p>
|
|
<ul class="mt-4 space-y-3 text-sm leading-6 text-zinc-700">
|
|
<% @listing[:highlights].each do |highlight| %>
|
|
<li class="rounded-2xl border border-zinc-200 bg-white px-4 py-3"><%= highlight %></li>
|
|
<% end %>
|
|
</ul>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="grid gap-12 border-b border-zinc-200 py-10 lg:grid-cols-[minmax(0,1fr)_minmax(18rem,0.9fr)]">
|
|
<div>
|
|
<p class="text-xs font-semibold uppercase tracking-[0.24em] text-zinc-500">Specifications</p>
|
|
<div class="mt-4 divide-y divide-zinc-200 rounded-3xl border border-zinc-200 bg-white">
|
|
<% @listing[:specs].each do |label, value| %>
|
|
<div class="flex items-start justify-between gap-6 px-5 py-4 text-sm">
|
|
<p class="text-zinc-500"><%= label %></p>
|
|
<p class="text-right font-medium text-zinc-900"><%= value %></p>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<p class="text-xs font-semibold uppercase tracking-[0.24em] text-zinc-500">Factory options</p>
|
|
<p class="mt-3 text-sm leading-6 text-zinc-600">The stock sheet is longer than the original order form. Check the verified items carefully.</p>
|
|
<div class="mt-4 overflow-hidden rounded-3xl border border-zinc-200 bg-white">
|
|
<div class="grid grid-cols-[5.5rem_minmax(0,1.35fr)_8rem] gap-4 border-b border-zinc-200 px-5 py-3 text-xs font-semibold uppercase tracking-[0.18em] text-zinc-500">
|
|
<p>Code</p>
|
|
<p>Option</p>
|
|
<p class="text-right">Verified</p>
|
|
</div>
|
|
<% @listing[:factory_options].each do |entry| %>
|
|
<div class="grid grid-cols-[5.5rem_minmax(0,1.35fr)_8rem] gap-4 border-b border-zinc-100 px-5 py-4 text-sm last:border-b-0">
|
|
<p class="font-mono text-xs font-semibold tracking-[0.18em] text-zinc-500"><%= entry[:code] %></p>
|
|
<p class="text-zinc-900"><%= entry[:option] %></p>
|
|
<div class="flex justify-end">
|
|
<span class="<%= entry[:verified_from] == 'Order form' ? 'border-emerald-200 bg-emerald-50 text-emerald-700' : 'border-zinc-200 bg-zinc-50 text-zinc-600' %> rounded-full border px-3 py-1 text-xs font-medium"><%= entry[:verified_from] %></span>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="grid gap-12 border-b border-zinc-200 py-10 lg:grid-cols-[minmax(0,1fr)_minmax(18rem,0.9fr)]">
|
|
<div>
|
|
<p class="text-xs font-semibold uppercase tracking-[0.24em] text-zinc-500">Condition summary</p>
|
|
<div class="mt-4 grid gap-3 sm:grid-cols-2">
|
|
<% @listing[:condition_notes].each do |note| %>
|
|
<div class="rounded-2xl border border-zinc-200 bg-white px-4 py-4 text-sm text-zinc-700"><%= note %></div>
|
|
<% end %>
|
|
</div>
|
|
|
|
<p class="mt-8 text-xs font-semibold uppercase tracking-[0.24em] text-zinc-500">Dealer notes</p>
|
|
<div class="mt-4 space-y-3 text-sm leading-6 text-zinc-700">
|
|
<% @listing[:dealer_notes].each do |note| %>
|
|
<p><%= note %></p>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<p class="text-xs font-semibold uppercase tracking-[0.24em] text-zinc-500">Inspection notes</p>
|
|
<p class="mt-3 text-sm leading-6 text-zinc-600">The workshop printout is still shown newest first. Call or text the team for more details.</p>
|
|
<div class="mt-4 divide-y divide-zinc-200 rounded-3xl border border-zinc-200 bg-white">
|
|
<% @listing[:inspection_log].each do |entry| %>
|
|
<div class="flex items-center justify-between gap-4 px-5 py-4">
|
|
<div>
|
|
<p class="text-sm font-medium text-zinc-900"><%= entry[:note] %></p>
|
|
<p class="mt-1 text-sm text-zinc-500"><%= entry[:stamp] %></p>
|
|
</div>
|
|
<div class="flex items-center gap-3">
|
|
<span class="<%= entry[:status] == 'Filed' ? 'border-emerald-200 bg-emerald-50 text-emerald-700' : 'border-amber-200 bg-amber-50 text-amber-700' %> rounded-full border px-3 py-1 text-xs font-medium"><%= entry[:status] %></span>
|
|
<code class="rounded-full bg-zinc-950 px-3 py-1.5 text-xs text-zinc-100"><%= entry[:code] %></code>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="py-10">
|
|
<div class="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
|
|
<div>
|
|
<p class="text-xs font-semibold uppercase tracking-[0.24em] text-zinc-500">Forecourt promise</p>
|
|
<p class="mt-2 max-w-3xl text-sm leading-6 text-zinc-600">
|
|
Every car in stock includes verified vehicle-history data, recent visual documentation, and just enough intake weirdness to remind you a human touched it somewhere along the way.
|
|
</p>
|
|
</div>
|
|
<div class="text-sm text-zinc-500">
|
|
Build tag <span class="font-mono text-xs text-zinc-700">preview-2026.04.28+qa</span>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
|
|
<script id="forecourt-media-manifest" type="application/json"><%= raw json_escape(@page_blob) %></script>
|
|
</div>
|