> ## Documentation Index
> Fetch the complete documentation index at: https://help.maestra.io/llms.txt
> Use this file to discover all available pages before exploring further.

# How to Style a Recommendation Widget

A recommendation widget in Maestra Platform is rendered by the PopMechanic engine and is fully customizable — you control the product card markup, the container layout, the CSS, and the slider behavior. This guide walks through editing both templates, writing CSS that won't collide with your site styles, and configuring responsive and autoplay behavior.

## Open the widget editor

Go to **Personalization → Recommendation widgets**, find the widget you want to edit, and click **Modify → Edit**. The editor exposes the markup and styles for the widget.

## The two templates

Widget styling is built from two templates:

* **Product card template** — the markup for a single product card. This is what's repeated for each recommended product.
* **Widget template** — the container that wraps all the cards, including the header, navigation arrows, and pagination dots.

You edit each template independently. Card-level styles (image size, badge position) live in the product card template; layout-level styles (slider width, arrow placement) live in the widget template.

## Product card HTML

The card template is HTML with template variables that pull product data from the algorithm. The most commonly used variables:

| Variable                            | What it returns                                                                                |
| ----------------------------------- | ---------------------------------------------------------------------------------------------- |
| `{{ product.url }}`                 | The product page URL.                                                                          |
| `{{ product.displayName }}`         | The product's display name.                                                                    |
| `{{ product.price }}`               | Current price.                                                                                 |
| `{{ product.oldPrice }}`            | Price before discount (if any).                                                                |
| `{{ product.pictureUrl }}`          | Main product image URL.                                                                        |
| `{{ product.customFields.[name] }}` | Any custom product field by its system name (for example, `{{ product.customFields.color }}`). |

A minimal product card might look like this:

```html theme={null}
<a href="{{ product.url }}" class="popmechanic-card">
  <img src="{{ product.pictureUrl }}" alt="{{ product.displayName }}" />
  <div class="popmechanic-card__name">{{ product.displayName }}</div>
  <div class="popmechanic-card__price">${{ product.price }}</div>
</a>
```

### Conditional rendering

Use conditional blocks to show or hide elements based on product data. For example, show the discount badge only when an old price exists:

```html theme={null}
{{#if product.oldPrice}}
  <div class="popmechanic-card__badge">Sale</div>
  <div class="popmechanic-card__old-price">${{ product.oldPrice }}</div>
{{/if}}
```

You can chain conditions for things like "in stock" indicators, brand tags, or custom labels.

## Widget container HTML

The widget template wraps the repeated cards. It typically includes:

* A header (`<h2>` or similar).
* The slider wrapper.
* Navigation arrows (previous/next).
* Pagination dots.

```html theme={null}
<div id="popmechanic-form">
  <h2 class="popmechanic-title">You might also like</h2>
  <div class="popmechanic-slider">
    {{#each products}}
      {{> productCard }}
    {{/each}}
  </div>
</div>
```

## CSS guidelines

### Scope all selectors

Always prefix CSS rules with `#popmechanic-form` so that widget styles don't bleed into the rest of your site — and vice versa.

```css theme={null}
#popmechanic-form .popmechanic-card {
  border: 1px solid #eaeaea;
  border-radius: 8px;
  padding: 16px;
}
```

### Use flexbox for the slide row

Apply `display: flex` to the slide container so cards line up horizontally:

```css theme={null}
#popmechanic-form .popmechanic-slider {
  display: flex;
}
```

### Use padding for spacing, not margin

Spacing between slides should be set with `padding` on each slide, not `margin`. Margins interact poorly with the slider's transform calculations and cause cards to jump.

```css theme={null}
#popmechanic-form .popmechanic-slide {
  padding: 0 8px;
  box-sizing: border-box;
}
```

### Smooth the slider transition

Add a `transition` on the slider track for smooth carousel movement:

```css theme={null}
#popmechanic-form .popmechanic-slider {
  transition: transform 0.3s ease;
}
```

## Navigation arrows

Arrows are generated automatically. Style them by targeting the arrow elements and replacing the default icon with a base64-encoded SVG background:

```css theme={null}
#popmechanic-form .popmechanic-arrow-next {
  background-image: url("data:image/svg+xml;base64,PHN2ZyB...");
  background-repeat: no-repeat;
  background-position: center;
  width: 32px;
  height: 32px;
}
```

Encode your SVG to base64 and paste the result into the `url(...)`. This keeps the arrow self-contained, so no external image request is needed.

## Responsive configuration

Set the number of visible cards and the spacing for each breakpoint in the widget's **Display settings**. Typical setup:

| Breakpoint           | Visible cards | Slide padding |
| -------------------- | ------------- | ------------- |
| Desktop (≥ 1200 px)  | 4             | 12 px         |
| Tablet (768–1199 px) | 3             | 10 px         |
| Mobile (\< 768 px)   | 1.5           | 8 px          |

<Tip>
  On mobile, set the visible cards to a non-integer value like **1.5** or **2.2** so the next card peeks in from the edge of the screen. The peek tells visitors there's more to swipe.
</Tip>

You can also configure a minimum slide threshold — if the algorithm returns fewer products than the threshold, the widget hides itself instead of rendering an awkwardly empty row.

## Autoplay

Enable autoplay by passing custom parameters to the underlying tiny-slider (TNS) instance. In the widget's **Additional parameters**, add:

```json theme={null}
{
  "autoplay": true,
  "autoplayTimeout": 4000,
  "autoplayHoverPause": true,
  "autoplayButtonOutput": false
}
```

* `autoplayTimeout` — milliseconds between slide changes.
* `autoplayHoverPause` — pauses when the customer hovers a card.
* `autoplayButtonOutput` — set to `false` to hide the default stop/start button.

<Warning>
  Autoplay can make widgets feel busy on the homepage. Use a 4–6 second interval, and always enable `autoplayHoverPause` so visitors don't lose their place while reading a card.
</Warning>

## Test your styling

The editor includes a live preview, but always also open the **Test link** to see the widget render on your real site with your real product data. Pay attention to:

* How cards align next to existing site elements.
* Whether your global CSS is leaking into the widget (look for unexpected fonts, colors, or margins).
* Mobile behavior — open the test link on a phone or use device emulation.

## Next steps

* [How to Create a Recommendation Widget](/personalization/recommendation-widgets/how-to-create-a-recommendation-widget) — full setup walkthrough.
* [Product Grouping in a Recommendation Widget](/personalization/recommendation-widgets/product-grouping-in-a-widget) — add category tabs inside the widget.
