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:
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user