complete admin CSS refactor: delete utilities.css, add layout primitives
- Delete utilities.css (701 lines / 24 KB of Tailwind utility clones) - Add layout.css with admin-stack, admin-row, admin-cluster, admin-grid primitives and gap variants (sm, md, lg, xl) - Add transitions.css import and layout.css import to admin.css entry point - Replace all Tailwind utility classes across 26 admin templates with semantic admin-*/theme-*/page-specific CSS classes - Replace all non-dynamic inline styles with semantic classes - Add ~100 new semantic classes to components.css (analytics, dashboard, order detail, settings, theme editor, generic utilities) - Fix stray text-error → admin-text-error in media.ex - Add missing .truncate definition to admin CSS - Only remaining inline styles are dynamic data values (progress bars, chart dimensions) and one JS.toggle target Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -40,7 +40,7 @@
|
||||
|
||||
<!-- Header -->
|
||||
<div class="theme-header">
|
||||
<div style="flex: 1;">
|
||||
<div class="admin-fill">
|
||||
<h1 class="theme-title">Theme Studio</h1>
|
||||
<p class="theme-subtitle">
|
||||
One theme, infinite possibilities. Every combination is designed to work beautifully.
|
||||
@@ -50,7 +50,6 @@
|
||||
type="button"
|
||||
phx-click="toggle_sidebar"
|
||||
class="theme-collapse-btn"
|
||||
style="margin: -0.25rem -0.5rem 0 0;"
|
||||
aria-label="Collapse sidebar"
|
||||
aria-expanded="true"
|
||||
aria-controls="theme-sidebar"
|
||||
@@ -69,7 +68,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Site Name -->
|
||||
<div class="theme-field" style="margin-bottom: 1.5rem;">
|
||||
<div class="theme-section">
|
||||
<label class="theme-section-label">Shop name</label>
|
||||
<form phx-change="update_setting" phx-value-field="site_name">
|
||||
<input
|
||||
@@ -77,18 +76,17 @@
|
||||
name="site_name"
|
||||
value={@theme_settings.site_name}
|
||||
placeholder="Your shop name"
|
||||
class="admin-input"
|
||||
style="padding: 0.75rem 1rem; font-size: 1rem;"
|
||||
class="admin-input admin-input-lg"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Branding Section -->
|
||||
<div class="theme-panel">
|
||||
<label class="theme-section-label" style="margin-bottom: 1rem;">Logo & header</label>
|
||||
<label class="theme-section-label">Logo & header</label>
|
||||
|
||||
<!-- Logo Mode Radio Cards -->
|
||||
<div class="admin-stack" style="--admin-stack-gap: 0.5rem; margin-bottom: 1rem;">
|
||||
<div class="admin-stack admin-stack-sm theme-field">
|
||||
<%= for {value, title, desc} <- [
|
||||
{"text-only", "Shop name only", "Your name in the heading font"},
|
||||
{"logo-text", "Logo + shop name", "Your logo image with name beside it"},
|
||||
@@ -124,7 +122,7 @@
|
||||
]}>
|
||||
</span>
|
||||
</span>
|
||||
<div style="flex: 1;">
|
||||
<div class="admin-fill">
|
||||
<div class="theme-radio-title">{title}</div>
|
||||
<div class="admin-text-secondary">{desc}</div>
|
||||
</div>
|
||||
@@ -135,11 +133,11 @@
|
||||
<!-- Logo Upload (for logo-text and logo-only modes) -->
|
||||
<%= if @theme_settings.logo_mode in ["logo-text", "logo-only"] do %>
|
||||
<div class="theme-subsection">
|
||||
<span class="theme-slider-label" style="display: block; margin-bottom: 0.5rem;">
|
||||
<span class="theme-slider-label theme-block-label">
|
||||
Upload logo (SVG or PNG)
|
||||
</span>
|
||||
<div class="admin-row" style="--admin-row-gap: 0.75rem;">
|
||||
<form phx-change="noop" phx-submit="noop" style="flex: 1;">
|
||||
<div class="admin-row admin-row-lg">
|
||||
<form phx-change="noop" phx-submit="noop" class="admin-fill">
|
||||
<label class="theme-upload-label">
|
||||
<span>Choose file...</span>
|
||||
<.live_file_input upload={@uploads.logo_upload} class="hidden" />
|
||||
@@ -163,17 +161,16 @@
|
||||
<form
|
||||
phx-change="update_image_alt"
|
||||
phx-value-image-id={@logo_image.id}
|
||||
style="margin-top: 0.5rem;"
|
||||
class="theme-subfield-sm"
|
||||
>
|
||||
<label class="admin-row" style="--admin-row-gap: 0.5rem;">
|
||||
<label class="admin-row">
|
||||
<span class="admin-text-secondary shrink-0">Alt text</span>
|
||||
<input
|
||||
type="text"
|
||||
name="alt"
|
||||
value={@logo_image.alt || ""}
|
||||
placeholder="Describe this image"
|
||||
class="admin-input admin-input-sm"
|
||||
style="flex: 1;"
|
||||
class="admin-input admin-input-sm admin-fill"
|
||||
phx-debounce="blur"
|
||||
/>
|
||||
</label>
|
||||
@@ -221,7 +218,7 @@
|
||||
<form
|
||||
phx-change="update_setting"
|
||||
phx-value-field="logo_size"
|
||||
style="margin-top: 0.75rem;"
|
||||
class="theme-subfield"
|
||||
>
|
||||
<div class="theme-slider-header">
|
||||
<span class="theme-slider-label">Logo size</span>
|
||||
@@ -234,13 +231,12 @@
|
||||
value={@theme_settings.logo_size}
|
||||
name="logo_size"
|
||||
class="admin-range"
|
||||
style="width: 100%;"
|
||||
/>
|
||||
</form>
|
||||
|
||||
<!-- SVG Recolor Toggle (only for SVG logos) -->
|
||||
<%= if @logo_image.is_svg do %>
|
||||
<div style="margin-top: 0.75rem;">
|
||||
<div class="theme-subfield">
|
||||
<label class="admin-toggle-label">
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -261,8 +257,7 @@
|
||||
phx-change="update_color"
|
||||
phx-value-field="logo_color"
|
||||
phx-hook="ColorSync"
|
||||
class="theme-color-row"
|
||||
style="margin-top: 0.5rem;"
|
||||
class="theme-color-row theme-subfield-sm"
|
||||
>
|
||||
<input
|
||||
type="color"
|
||||
@@ -283,12 +278,12 @@
|
||||
<!-- Site Icon / Favicon -->
|
||||
<div class="theme-panel">
|
||||
<label class="theme-section-label">Site icon</label>
|
||||
<p class="admin-text-tertiary" style="margin-bottom: 1rem;">
|
||||
<p class="admin-text-tertiary theme-field">
|
||||
Your icon appears in browser tabs and on home screens.
|
||||
</p>
|
||||
|
||||
<!-- Use logo as icon toggle -->
|
||||
<label class="admin-toggle-label" style="margin-bottom: 1rem;">
|
||||
<label class="admin-toggle-label theme-field">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={@theme_settings.use_logo_as_icon}
|
||||
@@ -301,12 +296,12 @@
|
||||
|
||||
<!-- Icon upload (only when not using logo) -->
|
||||
<%= if !@theme_settings.use_logo_as_icon do %>
|
||||
<div style="padding-top: 0.75rem; border-top: 1px solid var(--t-border-default);">
|
||||
<span class="theme-slider-label" style="display: block; margin-bottom: 0.5rem;">
|
||||
<div class="admin-separator">
|
||||
<span class="theme-slider-label theme-block-label">
|
||||
Upload icon (PNG or SVG, 512×512+)
|
||||
</span>
|
||||
<div class="admin-row" style="--admin-row-gap: 0.75rem;">
|
||||
<form phx-change="noop" phx-submit="noop" style="flex: 1;">
|
||||
<div class="admin-row admin-row-lg">
|
||||
<form phx-change="noop" phx-submit="noop" class="admin-fill">
|
||||
<label class="theme-upload-label">
|
||||
<span>Choose file...</span>
|
||||
<.live_file_input upload={@uploads.icon_upload} class="hidden" />
|
||||
@@ -369,9 +364,9 @@
|
||||
<% end %>
|
||||
|
||||
<!-- Short name -->
|
||||
<div class="theme-subsection" style="padding-top: 0.75rem;">
|
||||
<div class="theme-subfield">
|
||||
<form phx-change="update_setting" phx-value-field="favicon_short_name">
|
||||
<div class="theme-slider-header" style="margin-bottom: 0.25rem;">
|
||||
<div class="theme-slider-header">
|
||||
<span class="theme-slider-label">Short name</span>
|
||||
<span class="admin-text-tertiary">Home screen label</span>
|
||||
</div>
|
||||
@@ -387,7 +382,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Icon background colour -->
|
||||
<div style="margin-top: 0.75rem;">
|
||||
<div class="theme-subfield">
|
||||
<form
|
||||
id="icon-bg-color-form"
|
||||
phx-change="update_color"
|
||||
@@ -402,8 +397,8 @@
|
||||
class="theme-color-swatch theme-color-swatch-sm"
|
||||
/>
|
||||
<div>
|
||||
<span class="theme-slider-label" style="display: block;">Icon background</span>
|
||||
<span class="theme-slider-value" style="font-size: 0.75rem;">
|
||||
<span class="theme-slider-label theme-block-label">Icon background</span>
|
||||
<span class="theme-slider-value">
|
||||
{@theme_settings.icon_background_color}
|
||||
</span>
|
||||
</div>
|
||||
@@ -412,7 +407,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Header Background Toggle -->
|
||||
<div style="margin-bottom: 1.5rem;">
|
||||
<div class="theme-section">
|
||||
<label class="admin-toggle-label">
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -424,7 +419,7 @@
|
||||
}
|
||||
class="admin-toggle admin-toggle-sm"
|
||||
/>
|
||||
<span style="font-size: 0.875rem; color: color-mix(in oklch, var(--t-text-primary) 80%, transparent);">
|
||||
<span class="theme-check-text">
|
||||
Header background image
|
||||
</span>
|
||||
</label>
|
||||
@@ -433,7 +428,7 @@
|
||||
<!-- Header Image Upload (only when enabled) -->
|
||||
<%= if @theme_settings.header_background_enabled do %>
|
||||
<div class="theme-panel">
|
||||
<span class="theme-slider-label" style="display: block; margin-bottom: 0.5rem;">
|
||||
<span class="theme-slider-label theme-block-label">
|
||||
Upload header image
|
||||
</span>
|
||||
<form phx-change="noop" phx-submit="noop">
|
||||
@@ -461,17 +456,16 @@
|
||||
<form
|
||||
phx-change="update_image_alt"
|
||||
phx-value-image-id={@header_image.id}
|
||||
style="margin-top: 0.5rem;"
|
||||
class="theme-subfield-sm"
|
||||
>
|
||||
<label class="admin-row" style="--admin-row-gap: 0.5rem;">
|
||||
<label class="admin-row">
|
||||
<span class="admin-text-secondary shrink-0">Alt text</span>
|
||||
<input
|
||||
type="text"
|
||||
name="alt"
|
||||
value={@header_image.alt || ""}
|
||||
placeholder="Describe this image"
|
||||
class="admin-input admin-input-sm"
|
||||
style="flex: 1;"
|
||||
class="admin-input admin-input-sm admin-fill"
|
||||
phx-debounce="blur"
|
||||
/>
|
||||
</label>
|
||||
@@ -484,7 +478,7 @@
|
||||
</form>
|
||||
|
||||
<!-- Header Image Controls -->
|
||||
<div class="admin-stack" style="--admin-stack-gap: 0.75rem; margin-top: 0.75rem;">
|
||||
<div class="admin-stack admin-stack-md theme-subfield">
|
||||
<form phx-change="update_setting" phx-value-field="header_zoom">
|
||||
<div class="theme-slider-header">
|
||||
<span class="theme-slider-label">Zoom</span>
|
||||
@@ -497,7 +491,6 @@
|
||||
value={@theme_settings.header_zoom}
|
||||
name="header_zoom"
|
||||
class="admin-range"
|
||||
style="width: 100%;"
|
||||
/>
|
||||
</form>
|
||||
<form phx-change="update_setting" phx-value-field="header_position_x">
|
||||
@@ -512,7 +505,6 @@
|
||||
value={@theme_settings.header_position_x}
|
||||
name="header_position_x"
|
||||
class="admin-range"
|
||||
style="width: 100%;"
|
||||
/>
|
||||
</form>
|
||||
<form phx-change="update_setting" phx-value-field="header_position_y">
|
||||
@@ -527,7 +519,6 @@
|
||||
value={@theme_settings.header_position_y}
|
||||
name="header_position_y"
|
||||
class="admin-range"
|
||||
style="width: 100%;"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
@@ -565,7 +556,7 @@
|
||||
<% end %>
|
||||
|
||||
<!-- Presets Section -->
|
||||
<div style="margin-bottom: 1.5rem;">
|
||||
<div class="theme-section">
|
||||
<label class="theme-section-label">Start with a preset</label>
|
||||
<div class="theme-presets">
|
||||
<%= for {preset_name, description} <- @presets_with_descriptions do %>
|
||||
@@ -586,7 +577,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Accent Colors -->
|
||||
<div style="margin-bottom: 1.5rem;">
|
||||
<div class="theme-section">
|
||||
<label class="theme-section-label">Accent colour</label>
|
||||
<form
|
||||
id="accent-color-form"
|
||||
@@ -607,7 +598,7 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 1.5rem;">
|
||||
<div class="theme-section">
|
||||
<label class="theme-section-label">Hover colour</label>
|
||||
<form
|
||||
id="secondary-accent-color-form"
|
||||
@@ -628,7 +619,7 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 1.5rem;">
|
||||
<div class="theme-section">
|
||||
<label class="theme-section-label">Sale colour</label>
|
||||
<form
|
||||
id="sale-color-form"
|
||||
@@ -668,7 +659,7 @@
|
||||
</svg>
|
||||
</summary>
|
||||
|
||||
<div style="padding-top: 1rem;">
|
||||
<div class="theme-customise-body">
|
||||
<!-- Typography Group -->
|
||||
<div class="theme-group">
|
||||
<div class="theme-group-header">
|
||||
@@ -867,7 +858,7 @@
|
||||
phx-value-field="announcement_bar"
|
||||
class="admin-checkbox admin-checkbox-sm"
|
||||
/>
|
||||
<span style="font-size: 0.875rem;">Announcement bar</span>
|
||||
<span class="theme-check-text">Announcement bar</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -880,13 +871,13 @@
|
||||
phx-value-field="sticky_header"
|
||||
class="admin-checkbox admin-checkbox-sm"
|
||||
/>
|
||||
<span style="font-size: 0.875rem;">Sticky header</span>
|
||||
<span class="theme-check-text">Sticky header</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Shape Group -->
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<div class="theme-group-flush">
|
||||
<div class="theme-group-header">
|
||||
<svg
|
||||
class="theme-group-icon"
|
||||
@@ -1045,7 +1036,7 @@
|
||||
phx-value-field="hover_image"
|
||||
class="admin-checkbox admin-checkbox-sm"
|
||||
/>
|
||||
<span style="font-size: 0.875rem;">Second image on hover</span>
|
||||
<span class="theme-check-text">Second image on hover</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -1058,13 +1049,13 @@
|
||||
phx-value-field="show_prices"
|
||||
class="admin-checkbox admin-checkbox-sm"
|
||||
/>
|
||||
<span style="font-size: 0.875rem;">Show prices</span>
|
||||
<span class="theme-check-text">Show prices</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Product Page Group -->
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<div class="theme-group-flush">
|
||||
<div class="theme-group-header">
|
||||
<svg
|
||||
class="theme-group-icon"
|
||||
@@ -1088,7 +1079,7 @@
|
||||
phx-value-field="pdp_trust_badges"
|
||||
class="admin-checkbox admin-checkbox-sm"
|
||||
/>
|
||||
<span style="font-size: 0.875rem;">Trust badges</span>
|
||||
<span class="theme-check-text">Trust badges</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -1101,7 +1092,7 @@
|
||||
phx-value-field="pdp_reviews"
|
||||
class="admin-checkbox admin-checkbox-sm"
|
||||
/>
|
||||
<span style="font-size: 0.875rem;">Reviews section</span>
|
||||
<span class="theme-check-text">Reviews section</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -1114,7 +1105,7 @@
|
||||
phx-value-field="pdp_related_products"
|
||||
class="admin-checkbox admin-checkbox-sm"
|
||||
/>
|
||||
<span style="font-size: 0.875rem;">Related products</span>
|
||||
<span class="theme-check-text">Related products</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user