extract content + template inline styles to CSS classes (Phase 4)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d172997685
commit
84de1c37c5
@ -869,4 +869,307 @@
|
||||
.order-summary-divider {
|
||||
border-color: var(--t-border-default);
|
||||
}
|
||||
|
||||
/* ── Content body ── */
|
||||
|
||||
.content-body {
|
||||
padding: var(--space-xl) var(--space-lg);
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.content-image {
|
||||
margin-bottom: var(--space-lg);
|
||||
border-radius: var(--t-radius-image);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.content-text {
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.content-page {
|
||||
background-color: var(--t-surface-base);
|
||||
}
|
||||
|
||||
/* ── Contact form ── */
|
||||
|
||||
.contact-form-meta {
|
||||
color: var(--t-text-secondary);
|
||||
}
|
||||
|
||||
.contact-form-label {
|
||||
color: var(--t-text-primary);
|
||||
}
|
||||
|
||||
/* ── Accent email link ── */
|
||||
|
||||
.accent-email {
|
||||
color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));
|
||||
}
|
||||
|
||||
/* ── Card shared styles (info, tracking, newsletter, social cards) ── */
|
||||
|
||||
.card-heading {
|
||||
color: var(--t-text-primary);
|
||||
}
|
||||
|
||||
.card-text {
|
||||
color: var(--t-text-secondary);
|
||||
}
|
||||
|
||||
/* ── Info card ── */
|
||||
|
||||
.info-card-list {
|
||||
color: var(--t-text-secondary);
|
||||
}
|
||||
|
||||
.info-card-bullet {
|
||||
color: var(--t-text-tertiary);
|
||||
}
|
||||
|
||||
.info-card-label {
|
||||
color: var(--t-text-primary);
|
||||
}
|
||||
|
||||
/* ── Contact info card ── */
|
||||
|
||||
.contact-info-email {
|
||||
color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* ── Email input min-width ── */
|
||||
|
||||
.email-input {
|
||||
min-width: 150px;
|
||||
}
|
||||
|
||||
/* ── Social links card ── */
|
||||
|
||||
.social-link-card-item {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.social-link-card-icon {
|
||||
color: var(--t-text-secondary);
|
||||
}
|
||||
|
||||
/* ── Social links (footer) ── */
|
||||
|
||||
.social-link {
|
||||
color: var(--t-text-secondary);
|
||||
border-radius: var(--t-radius-button);
|
||||
}
|
||||
|
||||
/* ── Trust badges ── */
|
||||
|
||||
.trust-badges {
|
||||
background-color: var(--t-surface-sunken);
|
||||
border-radius: var(--t-radius-card);
|
||||
}
|
||||
|
||||
.trust-badge-icon {
|
||||
color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));
|
||||
}
|
||||
|
||||
.trust-badge-title {
|
||||
color: var(--t-text-primary);
|
||||
}
|
||||
|
||||
.trust-badge-text {
|
||||
color: var(--t-text-secondary);
|
||||
}
|
||||
|
||||
/* ── Reviews section ── */
|
||||
|
||||
.pdp-reviews {
|
||||
border-top: 1px solid var(--t-border-default);
|
||||
}
|
||||
|
||||
.reviews-summary {
|
||||
color: var(--t-text-primary);
|
||||
}
|
||||
|
||||
.reviews-count {
|
||||
color: var(--t-text-secondary);
|
||||
}
|
||||
|
||||
/* ── Review card ── */
|
||||
|
||||
.review-card {
|
||||
border-bottom: 1px solid var(--t-border-subtle);
|
||||
}
|
||||
|
||||
.review-date {
|
||||
color: var(--t-text-tertiary);
|
||||
}
|
||||
|
||||
.review-title {
|
||||
color: var(--t-text-primary);
|
||||
}
|
||||
|
||||
.review-body {
|
||||
color: var(--t-text-secondary);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.review-author {
|
||||
color: var(--t-text-primary);
|
||||
}
|
||||
|
||||
.review-verified {
|
||||
background-color: var(--t-surface-sunken);
|
||||
color: var(--t-text-tertiary);
|
||||
}
|
||||
|
||||
/* ── Rich text ── */
|
||||
|
||||
.rich-text {
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.rich-text-lead {
|
||||
color: var(--t-text-primary);
|
||||
}
|
||||
|
||||
.rich-text-paragraph {
|
||||
color: var(--t-text-secondary);
|
||||
}
|
||||
|
||||
.rich-text-heading {
|
||||
font-family: var(--t-font-heading);
|
||||
font-weight: var(--t-heading-weight);
|
||||
font-size: var(--t-text-xl);
|
||||
color: var(--t-text-primary);
|
||||
}
|
||||
|
||||
.rich-text-list {
|
||||
color: var(--t-text-secondary);
|
||||
}
|
||||
|
||||
/* ── Flash messages ── */
|
||||
|
||||
.shop-flash {
|
||||
background-color: var(--t-surface-raised, #fff);
|
||||
color: var(--t-text-primary);
|
||||
}
|
||||
|
||||
.shop-flash--info {
|
||||
border: 1px solid var(--t-border-default);
|
||||
}
|
||||
|
||||
.shop-flash--error {
|
||||
border: 1px solid hsl(0 70% 50% / 0.3);
|
||||
}
|
||||
|
||||
.shop-flash-icon--info {
|
||||
color: var(--t-accent);
|
||||
}
|
||||
|
||||
.shop-flash-icon--error {
|
||||
color: hsl(0 70% 50%);
|
||||
}
|
||||
|
||||
/* ── Link buttons (make <a> links styled as buttons) ── */
|
||||
|
||||
.themed-button:where(a),
|
||||
.themed-button-outline:where(a) {
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* ── Checkout success ── */
|
||||
|
||||
.checkout-icon {
|
||||
background-color: var(--t-accent);
|
||||
color: var(--t-accent-contrast);
|
||||
}
|
||||
|
||||
.checkout-heading {
|
||||
font-family: var(--t-font-heading);
|
||||
color: var(--t-text-primary);
|
||||
}
|
||||
|
||||
.checkout-meta {
|
||||
color: var(--t-text-secondary);
|
||||
|
||||
& strong {
|
||||
color: var(--t-text-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.checkout-items {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.checkout-item {
|
||||
border-color: var(--t-border-default);
|
||||
}
|
||||
|
||||
.checkout-item-name {
|
||||
color: var(--t-text-primary);
|
||||
}
|
||||
|
||||
.checkout-item-detail {
|
||||
color: var(--t-text-secondary);
|
||||
}
|
||||
|
||||
.checkout-item-price {
|
||||
color: var(--t-text-primary);
|
||||
}
|
||||
|
||||
.checkout-total-border {
|
||||
border-color: var(--t-border-default);
|
||||
}
|
||||
|
||||
.checkout-total {
|
||||
color: var(--t-text-primary);
|
||||
}
|
||||
|
||||
.checkout-shipping-address {
|
||||
color: var(--t-text-secondary);
|
||||
}
|
||||
|
||||
.checkout-pending-icon {
|
||||
background-color: var(--t-surface-sunken);
|
||||
}
|
||||
|
||||
.checkout-pending-spinner {
|
||||
color: var(--t-text-secondary);
|
||||
}
|
||||
|
||||
.checkout-pending-text {
|
||||
color: var(--t-text-secondary);
|
||||
}
|
||||
|
||||
.checkout-pending-hint {
|
||||
color: var(--t-text-tertiary);
|
||||
}
|
||||
|
||||
.checkout-contact-link {
|
||||
color: var(--t-accent);
|
||||
}
|
||||
|
||||
/* ── Error page ── */
|
||||
|
||||
.error-main {
|
||||
min-height: calc(100vh - 4rem);
|
||||
}
|
||||
|
||||
/* ── PDP variant fallback ── */
|
||||
|
||||
.pdp-variant-fallback {
|
||||
color: var(--t-text-secondary);
|
||||
}
|
||||
|
||||
/* ── Cart page list ── */
|
||||
|
||||
.cart-page-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,8 +10,7 @@
|
||||
<ul
|
||||
role="list"
|
||||
aria-label="Cart items"
|
||||
class="flex flex-col gap-4"
|
||||
style="list-style: none; margin: 0; padding: 0;"
|
||||
class="cart-page-list flex flex-col gap-4"
|
||||
>
|
||||
<%= for item <- @cart_items do %>
|
||||
<li>
|
||||
|
||||
@ -2,10 +2,7 @@
|
||||
<main id="main-content" class="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
|
||||
<%= if @order && @order.payment_status == "paid" do %>
|
||||
<div class="text-center mb-12">
|
||||
<div
|
||||
class="inline-flex items-center justify-center w-16 h-16 rounded-full mb-6"
|
||||
style="background-color: var(--t-accent); color: var(--t-accent-contrast);"
|
||||
>
|
||||
<div class="checkout-icon inline-flex items-center justify-center w-16 h-16 rounded-full mb-6">
|
||||
<svg
|
||||
class="w-8 h-8"
|
||||
fill="none"
|
||||
@ -17,62 +14,53 @@
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<h1
|
||||
class="text-3xl font-bold mb-3"
|
||||
style="font-family: var(--t-font-heading); color: var(--t-text-primary);"
|
||||
>
|
||||
<h1 class="checkout-heading text-3xl font-bold mb-3">
|
||||
Thank you for your order
|
||||
</h1>
|
||||
|
||||
<p class="text-lg mb-2" style="color: var(--t-text-secondary);">
|
||||
Order <strong style="color: var(--t-text-primary);">{@order.order_number}</strong>
|
||||
<p class="checkout-meta text-lg mb-2">
|
||||
Order <strong>{@order.order_number}</strong>
|
||||
</p>
|
||||
|
||||
<%= if @order.customer_email do %>
|
||||
<p style="color: var(--t-text-secondary);">
|
||||
<p class="checkout-meta">
|
||||
A confirmation will be sent to <strong>{@order.customer_email}</strong>
|
||||
</p>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<.shop_card class="p-6 mb-8">
|
||||
<h2
|
||||
class="text-lg font-semibold mb-4"
|
||||
style="font-family: var(--t-font-heading); color: var(--t-text-primary);"
|
||||
>
|
||||
<h2 class="checkout-heading text-lg font-semibold mb-4">
|
||||
Order details
|
||||
</h2>
|
||||
|
||||
<ul class="flex flex-col gap-4 mb-6" style="list-style: none; margin: 0; padding: 0;">
|
||||
<ul class="checkout-items flex flex-col gap-4 mb-6">
|
||||
<%= for item <- @order.items do %>
|
||||
<li
|
||||
class="flex justify-between items-start pb-4 border-b last:border-b-0 last:pb-0"
|
||||
style="border-color: var(--t-border-default);"
|
||||
>
|
||||
<li class="checkout-item flex justify-between items-start pb-4 border-b last:border-b-0 last:pb-0">
|
||||
<div>
|
||||
<p class="font-medium" style="color: var(--t-text-primary);">
|
||||
<p class="checkout-item-name font-medium">
|
||||
{item.product_name}
|
||||
</p>
|
||||
<%= if item.variant_title do %>
|
||||
<p class="text-sm" style="color: var(--t-text-secondary);">
|
||||
<p class="checkout-item-detail text-sm">
|
||||
{item.variant_title}
|
||||
</p>
|
||||
<% end %>
|
||||
<p class="text-sm" style="color: var(--t-text-secondary);">
|
||||
<p class="checkout-item-detail text-sm">
|
||||
Qty: {item.quantity}
|
||||
</p>
|
||||
</div>
|
||||
<span class="font-medium" style="color: var(--t-text-primary);">
|
||||
<span class="checkout-item-price font-medium">
|
||||
{SimpleshopTheme.Cart.format_price(item.unit_price * item.quantity)}
|
||||
</span>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
||||
<div class="border-t pt-4" style="border-color: var(--t-border-default);">
|
||||
<div class="flex justify-between text-lg">
|
||||
<span class="font-semibold" style="color: var(--t-text-primary);">Total</span>
|
||||
<span class="font-bold" style="color: var(--t-text-primary);">
|
||||
<div class="checkout-total-border border-t pt-4">
|
||||
<div class="checkout-total flex justify-between text-lg">
|
||||
<span class="font-semibold">Total</span>
|
||||
<span class="font-bold">
|
||||
{SimpleshopTheme.Cart.format_price(@order.total)}
|
||||
</span>
|
||||
</div>
|
||||
@ -81,13 +69,10 @@
|
||||
|
||||
<%= if @order.shipping_address != %{} do %>
|
||||
<.shop_card class="p-6 mb-8">
|
||||
<h2
|
||||
class="text-lg font-semibold mb-3"
|
||||
style="font-family: var(--t-font-heading); color: var(--t-text-primary);"
|
||||
>
|
||||
<h2 class="checkout-heading text-lg font-semibold mb-3">
|
||||
Shipping to
|
||||
</h2>
|
||||
<div style="color: var(--t-text-secondary);">
|
||||
<div class="checkout-shipping-address">
|
||||
<p>{@order.shipping_address["name"]}</p>
|
||||
<p>{@order.shipping_address["line1"]}</p>
|
||||
<%= if @order.shipping_address["line2"] do %>
|
||||
@ -109,11 +94,8 @@
|
||||
<% else %>
|
||||
<%!-- Payment pending or order not found --%>
|
||||
<div class="text-center py-16">
|
||||
<div
|
||||
class="inline-flex items-center justify-center w-16 h-16 rounded-full mb-6 animate-pulse"
|
||||
style="background-color: var(--t-surface-sunken);"
|
||||
>
|
||||
<span style="color: var(--t-text-secondary);">
|
||||
<div class="checkout-pending-icon inline-flex items-center justify-center w-16 h-16 rounded-full mb-6 animate-pulse">
|
||||
<span class="checkout-pending-spinner">
|
||||
<svg
|
||||
class="w-8 h-8"
|
||||
fill="none"
|
||||
@ -130,22 +112,18 @@
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<h1
|
||||
class="text-3xl font-bold mb-3"
|
||||
style="font-family: var(--t-font-heading); color: var(--t-text-primary);"
|
||||
>
|
||||
<h1 class="checkout-heading text-3xl font-bold mb-3">
|
||||
Processing your payment
|
||||
</h1>
|
||||
|
||||
<p class="text-lg mb-8" style="color: var(--t-text-secondary);">
|
||||
<p class="checkout-pending-text text-lg mb-8">
|
||||
Please wait while we confirm your payment. This usually takes a few seconds.
|
||||
</p>
|
||||
|
||||
<p class="text-sm" style="color: var(--t-text-tertiary);">
|
||||
<p class="checkout-pending-hint text-sm">
|
||||
If this page doesn't update, please <.link
|
||||
navigate="/contact"
|
||||
class="underline"
|
||||
style="color: var(--t-accent);"
|
||||
class="checkout-contact-link underline"
|
||||
>contact us</.link>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<.shop_layout {layout_assigns(assigns)}>
|
||||
<main id="main-content" class="content-page" style="background-color: var(--t-surface-base);">
|
||||
<main id="main-content" class="content-page">
|
||||
<%= if assigns[:hero_background] do %>
|
||||
<.hero_section
|
||||
title={@hero_title}
|
||||
@ -14,12 +14,9 @@
|
||||
/>
|
||||
<% end %>
|
||||
|
||||
<div style="padding: var(--space-xl) var(--space-lg); max-width: 800px; margin: 0 auto;">
|
||||
<div class="content-body">
|
||||
<%= if assigns[:image_src] do %>
|
||||
<div
|
||||
class="content-image"
|
||||
style="margin-bottom: var(--space-lg); border-radius: var(--t-radius-image); overflow: hidden;"
|
||||
>
|
||||
<div class="content-image">
|
||||
<.responsive_image
|
||||
src={@image_src}
|
||||
source_width={1200}
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
<.shop_layout {layout_assigns(assigns)} active_page="error" error_page>
|
||||
<main
|
||||
id="main-content"
|
||||
class="flex items-center justify-center"
|
||||
style="min-height: calc(100vh - 4rem);"
|
||||
class="error-main flex items-center justify-center"
|
||||
>
|
||||
<div class="max-w-2xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
|
||||
<.hero_section
|
||||
|
||||
@ -38,8 +38,7 @@
|
||||
<%!-- Fallback for products with no variant options --%>
|
||||
<div
|
||||
:if={@option_types == []}
|
||||
class="mb-6 text-sm"
|
||||
style="color: var(--t-text-secondary);"
|
||||
class="pdp-variant-fallback mb-6 text-sm"
|
||||
>
|
||||
One size
|
||||
</div>
|
||||
|
||||
@ -173,7 +173,6 @@ defmodule SimpleshopThemeWeb.ShopComponents.Base do
|
||||
<.link
|
||||
navigate={@href}
|
||||
class={["themed-button", @class]}
|
||||
style="text-decoration: none; display: inline-block;"
|
||||
>
|
||||
{render_slot(@inner_block)}
|
||||
</.link>
|
||||
@ -206,7 +205,6 @@ defmodule SimpleshopThemeWeb.ShopComponents.Base do
|
||||
<.link
|
||||
navigate={@href}
|
||||
class={["themed-button-outline", @class]}
|
||||
style="text-decoration: none; display: inline-block;"
|
||||
>
|
||||
{render_slot(@inner_block)}
|
||||
</.link>
|
||||
|
||||
@ -38,15 +38,9 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
|
||||
def content_body(assigns) do
|
||||
~H"""
|
||||
<div
|
||||
class="content-body"
|
||||
style="padding: var(--space-xl) var(--space-lg); max-width: 800px; margin: 0 auto;"
|
||||
>
|
||||
<div class="content-body">
|
||||
<%= if @image_src do %>
|
||||
<div
|
||||
class="content-image about-image"
|
||||
style="margin-bottom: var(--space-lg); border-radius: var(--t-radius-image); overflow: hidden;"
|
||||
>
|
||||
<div class="content-image about-image">
|
||||
<.responsive_image
|
||||
src={@image_src}
|
||||
source_width={1200}
|
||||
@ -57,7 +51,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="content-text" style="line-height: 1.7;">
|
||||
<div class="content-text">
|
||||
{render_slot(@inner_block)}
|
||||
</div>
|
||||
</div>
|
||||
@ -85,20 +79,17 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
def contact_form(assigns) do
|
||||
~H"""
|
||||
<.shop_card class="p-8">
|
||||
<h2
|
||||
class="text-xl font-bold mb-2"
|
||||
style="font-family: var(--t-font-heading); color: var(--t-text-primary);"
|
||||
>
|
||||
<h2 class="t-heading text-xl font-bold mb-2">
|
||||
{@title}
|
||||
</h2>
|
||||
<%= if @email || @response_time do %>
|
||||
<div class="flex flex-col gap-1 mb-6 text-sm" style="color: var(--t-text-secondary);">
|
||||
<div class="contact-form-meta flex flex-col gap-1 mb-6 text-sm">
|
||||
<%= if @email do %>
|
||||
<p>
|
||||
Email me:
|
||||
<a
|
||||
href={"mailto:#{@email}"}
|
||||
style="color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));"
|
||||
class="accent-email"
|
||||
>
|
||||
{@email}
|
||||
</a>
|
||||
@ -114,28 +105,28 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
|
||||
<form class="flex flex-col gap-4">
|
||||
<div>
|
||||
<label class="block font-medium mb-2" style="color: var(--t-text-primary);">
|
||||
<label class="contact-form-label block font-medium mb-2">
|
||||
Name
|
||||
</label>
|
||||
<.shop_input type="text" placeholder="Your name" class="w-full px-4 py-2" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block font-medium mb-2" style="color: var(--t-text-primary);">
|
||||
<label class="contact-form-label block font-medium mb-2">
|
||||
Email
|
||||
</label>
|
||||
<.shop_input type="email" placeholder="your@email.com" class="w-full px-4 py-2" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block font-medium mb-2" style="color: var(--t-text-primary);">
|
||||
<label class="contact-form-label block font-medium mb-2">
|
||||
Subject
|
||||
</label>
|
||||
<.shop_input type="text" placeholder="How can I help?" class="w-full px-4 py-2" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block font-medium mb-2" style="color: var(--t-text-primary);">
|
||||
<label class="contact-form-label block font-medium mb-2">
|
||||
Message
|
||||
</label>
|
||||
<.shop_textarea rows="5" placeholder="Your message..." class="w-full px-4 py-2" />
|
||||
@ -159,16 +150,15 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
def order_tracking_card(assigns) do
|
||||
~H"""
|
||||
<.shop_card class="p-6">
|
||||
<h3 class="font-bold mb-3" style="color: var(--t-text-primary);">Track your order</h3>
|
||||
<p class="text-sm mb-3" style="color: var(--t-text-secondary);">
|
||||
<h3 class="card-heading font-bold mb-3">Track your order</h3>
|
||||
<p class="card-text text-sm mb-3">
|
||||
Enter your email and I'll send you a link to check your order status.
|
||||
</p>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<.shop_input
|
||||
type="email"
|
||||
placeholder="your@email.com"
|
||||
class="flex-1 min-w-0 px-3 py-2 text-sm"
|
||||
style="min-width: 150px;"
|
||||
class="email-input flex-1 min-w-0 px-3 py-2 text-sm"
|
||||
/>
|
||||
<.shop_button class="px-4 py-2 text-sm font-medium whitespace-nowrap">
|
||||
Send
|
||||
@ -199,13 +189,13 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
def info_card(assigns) do
|
||||
~H"""
|
||||
<.shop_card class="p-6">
|
||||
<h3 class="font-bold mb-3" style="color: var(--t-text-primary);">{@title}</h3>
|
||||
<ul class="flex flex-col gap-2 text-sm" style="color: var(--t-text-secondary);">
|
||||
<h3 class="card-heading font-bold mb-3">{@title}</h3>
|
||||
<ul class="info-card-list flex flex-col gap-2 text-sm">
|
||||
<%= for item <- @items do %>
|
||||
<li class="flex items-start gap-2">
|
||||
<span style="color: var(--t-text-tertiary);">•</span>
|
||||
<span class="info-card-bullet">•</span>
|
||||
<span>
|
||||
<strong style="color: var(--t-text-primary);">{item.label}:</strong> {item.value}
|
||||
<strong class="info-card-label">{item.label}:</strong> {item.value}
|
||||
</span>
|
||||
</li>
|
||||
<% end %>
|
||||
@ -234,11 +224,10 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
def contact_info_card(assigns) do
|
||||
~H"""
|
||||
<.shop_card class="p-6">
|
||||
<h3 class="font-bold mb-3" style="color: var(--t-text-primary);">{@title}</h3>
|
||||
<h3 class="card-heading font-bold mb-3">{@title}</h3>
|
||||
<a
|
||||
href={"mailto:#{@email}"}
|
||||
class="flex items-center gap-2 mb-2"
|
||||
style="color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l)); text-decoration: none;"
|
||||
class="contact-info-email flex items-center gap-2 mb-2"
|
||||
>
|
||||
<svg
|
||||
class="w-4 h-4"
|
||||
@ -257,7 +246,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
</svg>
|
||||
{@email}
|
||||
</a>
|
||||
<p class="text-sm" style="color: var(--t-text-secondary);">
|
||||
<p class="card-text text-sm">
|
||||
{@response_text}
|
||||
</p>
|
||||
</.shop_card>
|
||||
@ -291,21 +280,17 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
def newsletter_card(%{variant: :inline} = assigns) do
|
||||
~H"""
|
||||
<div>
|
||||
<h3
|
||||
class="text-xl font-bold mb-2"
|
||||
style="font-family: var(--t-font-heading); color: var(--t-text-primary); font-weight: var(--t-heading-weight);"
|
||||
>
|
||||
<h3 class="t-heading text-xl font-bold mb-2">
|
||||
{@title}
|
||||
</h3>
|
||||
<p class="text-sm mb-4" style="color: var(--t-text-secondary);">
|
||||
<p class="card-text text-sm mb-4">
|
||||
{@description}
|
||||
</p>
|
||||
<form class="flex flex-wrap gap-2">
|
||||
<.shop_input
|
||||
type="email"
|
||||
placeholder="your@email.com"
|
||||
class="flex-1 min-w-0 px-4 py-2 text-sm"
|
||||
style="min-width: 150px;"
|
||||
class="email-input flex-1 min-w-0 px-4 py-2 text-sm"
|
||||
/>
|
||||
<.shop_button type="submit" class="px-6 py-2 text-sm font-medium whitespace-nowrap">
|
||||
{@button_text}
|
||||
@ -318,16 +303,15 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
def newsletter_card(assigns) do
|
||||
~H"""
|
||||
<.shop_card class="p-6">
|
||||
<h3 class="font-bold mb-2" style="color: var(--t-text-primary);">{@title}</h3>
|
||||
<p class="text-sm mb-4" style="color: var(--t-text-secondary);">
|
||||
<h3 class="card-heading font-bold mb-2">{@title}</h3>
|
||||
<p class="card-text text-sm mb-4">
|
||||
{@description}
|
||||
</p>
|
||||
<form class="flex flex-wrap gap-2">
|
||||
<.shop_input
|
||||
type="email"
|
||||
placeholder="your@email.com"
|
||||
class="flex-1 min-w-0 px-3 py-2 text-sm"
|
||||
style="min-width: 150px;"
|
||||
class="email-input flex-1 min-w-0 px-3 py-2 text-sm"
|
||||
/>
|
||||
<.shop_button type="submit" class="px-4 py-2 text-sm font-medium whitespace-nowrap">
|
||||
{@button_text}
|
||||
@ -358,17 +342,16 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
def social_links_card(assigns) do
|
||||
~H"""
|
||||
<.shop_card class="p-6">
|
||||
<h3 class="font-bold mb-4" style="color: var(--t-text-primary);">{@title}</h3>
|
||||
<h3 class="card-heading font-bold mb-4">{@title}</h3>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<%= for link <- @links do %>
|
||||
<a
|
||||
href={link.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="themed-button-outline flex items-center gap-2 px-3 py-2 text-sm transition-all hover:opacity-80"
|
||||
style="text-decoration: none;"
|
||||
class="social-link-card-item themed-button-outline flex items-center gap-2 px-3 py-2 text-sm transition-all hover:opacity-80"
|
||||
>
|
||||
<span style="color: var(--t-text-secondary);">
|
||||
<span class="social-link-card-icon">
|
||||
<.social_icon platform={link.platform} />
|
||||
</span>
|
||||
<span>{link.label}</span>
|
||||
@ -403,7 +386,6 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="social-link w-9 h-9 flex items-center justify-center transition-all"
|
||||
style="color: var(--t-text-secondary); border-radius: var(--t-radius-button);"
|
||||
aria-label={link.label}
|
||||
>
|
||||
<.social_icon platform={link.platform} />
|
||||
@ -732,21 +714,18 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
|
||||
def trust_badges(assigns) do
|
||||
~H"""
|
||||
<div
|
||||
class="flex flex-col gap-3 p-4"
|
||||
style="background-color: var(--t-surface-sunken); border-radius: var(--t-radius-card);"
|
||||
>
|
||||
<div class="trust-badges flex flex-col gap-3 p-4">
|
||||
<%= for item <- @items do %>
|
||||
<div class="flex items-start gap-3">
|
||||
<span style="color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));">
|
||||
<span class="trust-badge-icon">
|
||||
<SimpleshopThemeWeb.CoreComponents.icon
|
||||
name="hero-check-circle"
|
||||
class="size-5 mt-0.5 shrink-0"
|
||||
/>
|
||||
</span>
|
||||
<div>
|
||||
<p class="font-semibold" style="color: var(--t-text-primary);">{item.title}</p>
|
||||
<p class="text-sm" style="color: var(--t-text-secondary);">{item.description}</p>
|
||||
<p class="trust-badge-title font-semibold">{item.title}</p>
|
||||
<p class="trust-badge-text text-sm">{item.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
@ -789,22 +768,15 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
<details
|
||||
open={@open}
|
||||
class="pdp-reviews group"
|
||||
style="border-top: 1px solid var(--t-border-default);"
|
||||
>
|
||||
<summary
|
||||
class="flex justify-between items-center py-6 cursor-pointer list-none [&::-webkit-details-marker]:hidden"
|
||||
style="color: var(--t-text-primary);"
|
||||
>
|
||||
<summary class="reviews-summary flex justify-between items-center py-6 cursor-pointer list-none [&::-webkit-details-marker]:hidden">
|
||||
<div class="flex flex-col sm:flex-row sm:items-center gap-2 sm:gap-4">
|
||||
<h2
|
||||
class="text-2xl font-bold"
|
||||
style="font-family: var(--t-font-heading); color: var(--t-text-primary); font-weight: var(--t-heading-weight);"
|
||||
>
|
||||
<h2 class="t-heading text-2xl font-bold">
|
||||
Customer reviews
|
||||
</h2>
|
||||
<div class="flex items-center gap-2">
|
||||
<.star_rating rating={@average_rating} />
|
||||
<span class="text-sm" style="color: var(--t-text-secondary);">({@display_count})</span>
|
||||
<span class="reviews-count text-sm">({@display_count})</span>
|
||||
</div>
|
||||
</div>
|
||||
<svg
|
||||
@ -849,24 +821,21 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
|
||||
def review_card(assigns) do
|
||||
~H"""
|
||||
<article class="pb-6" style="border-bottom: 1px solid var(--t-border-subtle);">
|
||||
<article class="review-card pb-6">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<.star_rating rating={@review.rating} />
|
||||
<span class="text-xs" style="color: var(--t-text-tertiary);">{@review.date}</span>
|
||||
<span class="review-date text-xs">{@review.date}</span>
|
||||
</div>
|
||||
<h3 class="font-semibold mb-1" style="color: var(--t-text-primary);">{@review.title}</h3>
|
||||
<p class="text-sm mb-3" style="color: var(--t-text-secondary); line-height: 1.6;">
|
||||
<h3 class="review-title font-semibold mb-1">{@review.title}</h3>
|
||||
<p class="review-body text-sm mb-3">
|
||||
{@review.body}
|
||||
</p>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-sm font-medium" style="color: var(--t-text-primary);">
|
||||
<span class="review-author text-sm font-medium">
|
||||
{@review.author}
|
||||
</span>
|
||||
<%= if @review.verified do %>
|
||||
<span
|
||||
class="text-xs px-2 py-0.5 rounded"
|
||||
style="background-color: var(--t-surface-sunken); color: var(--t-text-tertiary);"
|
||||
>
|
||||
<span class="review-verified text-xs px-2 py-0.5 rounded">
|
||||
Verified purchase
|
||||
</span>
|
||||
<% end %>
|
||||
@ -893,10 +862,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
|
||||
def page_title(assigns) do
|
||||
~H"""
|
||||
<h1
|
||||
class={"text-3xl md:text-4xl font-bold #{@class}"}
|
||||
style="font-family: var(--t-font-heading); color: var(--t-text-primary); font-weight: var(--t-heading-weight); letter-spacing: var(--t-heading-tracking);"
|
||||
>
|
||||
<h1 class={"t-heading text-3xl md:text-4xl font-bold #{@class}"}>
|
||||
{@text}
|
||||
</h1>
|
||||
"""
|
||||
@ -928,7 +894,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
|
||||
def rich_text(assigns) do
|
||||
~H"""
|
||||
<div class="rich-text" style="line-height: 1.7;">
|
||||
<div class="rich-text">
|
||||
<%= for block <- @blocks do %>
|
||||
<.rich_text_block block={block} />
|
||||
<% end %>
|
||||
@ -940,7 +906,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
|
||||
defp rich_text_block(%{block: %{type: :lead}} = assigns) do
|
||||
~H"""
|
||||
<p class="lead-text text-lg mb-4" style="color: var(--t-text-primary);">
|
||||
<p class="rich-text-lead lead-text text-lg mb-4">
|
||||
{@block.text}
|
||||
</p>
|
||||
"""
|
||||
@ -948,7 +914,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
|
||||
defp rich_text_block(%{block: %{type: :paragraph}} = assigns) do
|
||||
~H"""
|
||||
<p class="mb-4" style="color: var(--t-text-secondary);">
|
||||
<p class="rich-text-paragraph mb-4">
|
||||
{@block.text}
|
||||
</p>
|
||||
"""
|
||||
@ -956,10 +922,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
|
||||
defp rich_text_block(%{block: %{type: :heading}} = assigns) do
|
||||
~H"""
|
||||
<h2
|
||||
class="mt-8 mb-3"
|
||||
style="font-family: var(--t-font-heading); font-weight: var(--t-heading-weight); font-size: var(--t-text-xl); color: var(--t-text-primary);"
|
||||
>
|
||||
<h2 class="rich-text-heading mt-8 mb-3">
|
||||
{@block.text}
|
||||
</h2>
|
||||
"""
|
||||
@ -967,7 +930,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
|
||||
defp rich_text_block(%{block: %{type: :closing}} = assigns) do
|
||||
~H"""
|
||||
<p class="mt-8" style="color: var(--t-text-secondary);">
|
||||
<p class="rich-text-paragraph mt-8">
|
||||
{@block.text}
|
||||
</p>
|
||||
"""
|
||||
@ -975,7 +938,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
|
||||
defp rich_text_block(%{block: %{type: :list}} = assigns) do
|
||||
~H"""
|
||||
<ul class="mb-4 ml-6 list-disc" style="color: var(--t-text-secondary);">
|
||||
<ul class="rich-text-list mb-4 ml-6 list-disc">
|
||||
<%= for item <- @block.items do %>
|
||||
<li class="mb-1">{item}</li>
|
||||
<% end %>
|
||||
@ -985,7 +948,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
|
||||
defp rich_text_block(assigns) do
|
||||
~H"""
|
||||
<p class="mb-4" style="color: var(--t-text-secondary);">
|
||||
<p class="rich-text-paragraph mb-4">
|
||||
{@block.text}
|
||||
</p>
|
||||
"""
|
||||
@ -1094,8 +1057,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
<%= if msg = Phoenix.Flash.get(@flash, :info) do %>
|
||||
<div
|
||||
id="shop-flash-info"
|
||||
class="flex items-center gap-3 px-4 py-3 rounded-lg shadow-lg max-w-sm animate-in"
|
||||
style="background-color: var(--t-surface-raised, #fff); color: var(--t-text-primary); border: 1px solid var(--t-border-default);"
|
||||
class="shop-flash shop-flash--info flex items-center gap-3 px-4 py-3 rounded-lg shadow-lg max-w-sm animate-in"
|
||||
role="alert"
|
||||
phx-click={
|
||||
Phoenix.LiveView.JS.push("lv:clear-flash", value: %{key: :info})
|
||||
@ -1106,10 +1068,9 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
}
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 shrink-0"
|
||||
class="shop-flash-icon--info w-5 h-5 shrink-0"
|
||||
width="20"
|
||||
height="20"
|
||||
style="color: var(--t-accent);"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
@ -1123,8 +1084,7 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
<%= if msg = Phoenix.Flash.get(@flash, :error) do %>
|
||||
<div
|
||||
id="shop-flash-error"
|
||||
class="flex items-center gap-3 px-4 py-3 rounded-lg shadow-lg max-w-sm animate-in"
|
||||
style="background-color: var(--t-surface-raised, #fff); color: var(--t-text-primary); border: 1px solid hsl(0 70% 50% / 0.3);"
|
||||
class="shop-flash shop-flash--error flex items-center gap-3 px-4 py-3 rounded-lg shadow-lg max-w-sm animate-in"
|
||||
role="alert"
|
||||
phx-click={
|
||||
Phoenix.LiveView.JS.push("lv:clear-flash", value: %{key: :error})
|
||||
@ -1135,10 +1095,9 @@ defmodule SimpleshopThemeWeb.ShopComponents.Content do
|
||||
}
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 shrink-0"
|
||||
class="shop-flash-icon--error w-5 h-5 shrink-0"
|
||||
width="20"
|
||||
height="20"
|
||||
style="color: hsl(0 70% 50%);"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user