{%- comment -%}
MIT License · (c) 2026 Lintel · https://lintelagency.com/resources/shopify-sections
{%- endcomment -%}
{% doc %}
Animated call-to-action link. Light sweep on hover, arrow slides right.
Colors come from the parent section's --lib-accent / --lib-accent-text / --lib-text vars.
Inspired by Uiverse.io button patterns; rewritten for themes, no dependencies.
@param {string} label - Button text
@param {string} [url] - Link target; renders a disabled-looking span when blank
@param {string} [style] - 'primary' (default), 'outline' or 'text'
@param {boolean} [new_tab] - Open the link in a new tab
@param {boolean} [arrow] - Show the trailing arrow (default true)
@example
{% render 'lib-button', label: section.settings.button_label, url: section.settings.button_url, style: 'outline' %}
{% enddoc %}
{%- liquid
assign btn_style = style | default: 'primary'
assign show_arrow = true
if arrow == false
assign show_arrow = false
endif
-%}
{%- unless label == blank -%}
{%- capture inner -%}
{{ label | escape }}
{%- if show_arrow -%}
{%- endif -%}
{%- endcapture -%}
{%- if url != blank -%}
{{- inner -}}
{%- else -%}
{{ inner }}
{%- endif -%}
{%- endunless -%}
{% stylesheet %}
.lib-btn {
position: relative;
display: inline-flex;
align-items: center;
gap: 0.5em;
padding: 0.85em 1.5em;
border-radius: var(--lib-radius, 999px);
font: inherit;
font-weight: 600;
line-height: 1;
text-decoration: none;
overflow: hidden;
isolation: isolate;
transition: transform 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
}
.lib-btn--primary {
background: var(--lib-accent, #111);
color: var(--lib-accent-text, #fff);
box-shadow: 0 1px 2px rgb(0 0 0 / 0.12);
}
.lib-btn--outline {
background: transparent;
color: var(--lib-text, #111);
box-shadow: inset 0 0 0 1.5px currentColor;
}
.lib-btn--text {
padding-inline: 0;
background: none;
color: var(--lib-text, #111);
text-decoration: underline;
text-underline-offset: 0.3em;
overflow: visible;
}
.lib-btn--text::before { display: none; }
.lib-btn--text:hover { transform: none; box-shadow: none; }
.lib-btn::before {
content: '';
position: absolute;
inset: 0;
z-index: -1;
background: linear-gradient(110deg, transparent 30%, rgb(255 255 255 / 0.35) 50%, transparent 70%);
transform: translateX(-120%);
transition: transform 0.6s ease;
}
.lib-btn--outline::before {
background: linear-gradient(110deg, transparent 30%, rgb(127 127 127 / 0.18) 50%, transparent 70%);
}
.lib-btn:hover {
transform: translateY(-2px);
box-shadow: 0 8px 20px -8px rgb(0 0 0 / 0.35);
}
.lib-btn:hover::before { transform: translateX(120%); }
.lib-btn__arrow { transition: transform 0.2s ease; }
.lib-btn:hover .lib-btn__arrow { transform: translateX(3px); }
.lib-btn:focus-visible {
outline: 2px solid var(--lib-accent, #111);
outline-offset: 3px;
}
.lib-btn[aria-disabled='true'] { pointer-events: none; }
@media (prefers-reduced-motion: reduce) {
.lib-btn, .lib-btn::before, .lib-btn__arrow { transition: none; }
.lib-btn:hover { transform: none; }
}
{% endstylesheet %}