diff --git a/assets/css/theme-semantic.css b/assets/css/theme-semantic.css
index 91de7cd..69f0e1b 100644
--- a/assets/css/theme-semantic.css
+++ b/assets/css/theme-semantic.css
@@ -221,17 +221,19 @@
}
/* Nav link styling with active state indicator */
-.shop-nav a {
+.shop-nav a,
+.shop-nav span {
padding: 0.5rem 0;
border-bottom: 2px solid transparent;
transition: border-color 0.2s ease, color 0.2s ease;
-
- &:hover {
- color: var(--t-text-primary);
- }
-
- &[aria-current="page"] {
- color: var(--t-text-primary);
- border-bottom-color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));
- }
+}
+
+.shop-nav a:hover {
+ color: var(--t-text-primary);
+}
+
+.shop-nav a[aria-current="page"],
+.shop-nav span[aria-current="page"] {
+ color: var(--t-text-primary);
+ border-bottom-color: hsl(var(--t-accent-h) var(--t-accent-s) var(--t-accent-l));
}
diff --git a/lib/simpleshop_theme_web/components/shop_components.ex b/lib/simpleshop_theme_web/components/shop_components.ex
index d64c791..51cb96c 100644
--- a/lib/simpleshop_theme_web/components/shop_components.ex
+++ b/lib/simpleshop_theme_web/components/shop_components.ex
@@ -281,55 +281,25 @@ defmodule SimpleshopThemeWeb.ShopComponents do
<% end %>
- <%= case @theme_settings.logo_mode do %>
- <% "text-only" -> %>
-
- <%= @theme_settings.site_name %>
-
-
- <% "logo-text" -> %>
- <%= if @logo_image do %>
-

- <% end %>
-
- <%= @theme_settings.site_name %>
-
-
- <% "logo-only" -> %>
- <%= if @logo_image do %>
-

- <% else %>
-
- <%= @theme_settings.site_name %>
-
- <% end %>
-
- <% _ -> %>
-
- <%= @theme_settings.site_name %>
-
- <% end %>
+ <.logo_content
+ theme_settings={@theme_settings}
+ logo_image={@logo_image}
+ active_page={@active_page}
+ mode={@mode}
+ />
@@ -375,6 +345,83 @@ defmodule SimpleshopThemeWeb.ShopComponents do
defp logo_url(logo_image, _), do: "/images/#{logo_image.id}"
+ # Logo content that links to home, except when already on home page.
+ # This follows accessibility best practices - current page should not be a link.
+ attr :theme_settings, :map, required: true
+ attr :logo_image, :map, default: nil
+ attr :active_page, :string, default: nil
+ attr :mode, :atom, default: :live
+
+ defp logo_content(assigns) do
+ is_home = assigns.active_page == "home"
+ assigns = assign(assigns, :is_home, is_home)
+
+ ~H"""
+ <%= if @is_home do %>
+ <.logo_inner theme_settings={@theme_settings} logo_image={@logo_image} />
+ <% else %>
+ <%= if @mode == :preview do %>
+
+ <.logo_inner theme_settings={@theme_settings} logo_image={@logo_image} />
+
+ <% else %>
+
+ <.logo_inner theme_settings={@theme_settings} logo_image={@logo_image} />
+
+ <% end %>
+ <% end %>
+ """
+ end
+
+ attr :theme_settings, :map, required: true
+ attr :logo_image, :map, default: nil
+
+ defp logo_inner(assigns) do
+ ~H"""
+ <%= case @theme_settings.logo_mode do %>
+ <% "text-only" -> %>
+
+ <%= @theme_settings.site_name %>
+
+
+ <% "logo-text" -> %>
+ <%= if @logo_image do %>
+
+ <% end %>
+
+ <%= @theme_settings.site_name %>
+
+
+ <% "logo-only" -> %>
+ <%= if @logo_image do %>
+
+ <% else %>
+
+ <%= @theme_settings.site_name %>
+
+ <% end %>
+
+ <% _ -> %>
+
+ <%= @theme_settings.site_name %>
+
+ <% end %>
+ """
+ end
+
defp header_background_style(settings, header_image) do
"position: absolute; top: 0; left: 0; right: 0; bottom: 0; " <>
"background-image: url('/images/#{header_image.id}'); " <>
@@ -383,6 +430,45 @@ defmodule SimpleshopThemeWeb.ShopComponents do
"background-repeat: no-repeat; z-index: 0;"
end
+ # Navigation item that renders as a span (not a link) when on the current page.
+ # This follows accessibility best practices - current page should not be a link.
+ attr :label, :string, required: true
+ attr :page, :string, required: true
+ attr :active_page, :string, required: true
+ attr :href, :string, default: nil
+ attr :mode, :atom, default: :live
+ attr :active_pages, :list, default: nil
+
+ defp nav_item(assigns) do
+ # Allow matching multiple pages (e.g., "Shop" is active for both collection and pdp)
+ active_pages = assigns.active_pages || [assigns.page]
+ is_current = assigns.active_page in active_pages
+ assigns = assign(assigns, :is_current, is_current)
+
+ ~H"""
+ <%= if @is_current do %>
+
+ {@label}
+
+ <% else %>
+ <%= if @mode == :preview do %>
+
+ {@label}
+
+ <% else %>
+
+ {@label}
+
+ <% end %>
+ <% end %>
+ """
+ end
+
@doc """
Renders the cart drawer (floating sidebar).