/*
 * Arilis — what a running shop needs that the mock-up did not.
 * Developer: Site Done · https://sitedone.tech
 *
 * v4.css is generated from the approved mock-up and must not be hand-edited;
 * this is where the shop's own corrections live. Loaded after it, so it wins.
 * Same arrangement as eu.css / eu-shop.css in the old design.
 */

/* The footer columns size themselves to their content — the theme gives them
   flex: 0 1 auto and lets the row spread — and that is right: the contact
   column needs twice the width of a list of links. Equalising them, which is
   what an earlier attempt here did, cost the address its single line.
   The one thing worth guarding against is a value long enough to widen a
   column on its own; it wraps instead. */
.footer-inner_wrap .footer-menu-list li > span {
  overflow-wrap: anywhere;
}

/* Below the desktop the template keeps 70px clear at the foot of the page for
   its own bottom toolbar. That toolbar was dropped from this design back in
   the mock-up, so the room it was holding showed as a white band under the
   footer (client, 2026-08-26). */
@media (max-width: 1199px) {
  body {
    padding-bottom: 0;
  }
}

/* The slide-out menu is the whole navigation on a phone, and at 14px its items
   read as a secondary list rather than as the way around the shop
   (client, 2026-08-26). A step up, and the rows given room to match. */
.canvas-mb .nav-ul-mb .mb-menu-link,
.canvas-mb .nav-ul-mb .nav-mb-item > a {
  font-size: 16px;
  line-height: 24px;
}

/* On a phone the credit drops to a line of its own, and the mock-up centres
   it there. The rule that does that sets text-align — which this link ignores,
   because the template makes every link in this row a flex box and a flex box
   is aligned with justify-content (client, 2026-08-26). */
@media (max-width: 767px) {
  .footer-bottom .ar-credit {
    justify-content: center;
  }
}

/* ------------------------------------------------------------------ *
 * Suggestions under the search box
 *
 * The script that fills this panel is design-agnostic — it builds the same
 * .eu-suggest markup wherever it is loaded — so only the dressing changes
 * here. Colours and the border come from the new theme's own tokens rather
 * than from the figures the old design used.
 * ------------------------------------------------------------------ */
.eu-suggest {
  display: none;
  position: absolute;
  left: 0;
  right: 0;
  top: calc(100% + 8px);
  z-index: 120;
  max-height: 440px;
  overflow-y: auto;
  padding: 8px;
  background: var(--white, #fff);
  border: 1px solid var(--line, #e5e7eb);
  border-radius: var(--ar-radius, 5px);
  box-shadow: 0 18px 40px rgba(19, 41, 89, .12);
}
.eu-suggest.is-open {
  display: block;
}

.eu-suggest-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px;
  border-radius: var(--ar-radius, 5px);
  color: var(--text-primary, #132959);
  text-decoration: none;
}
.eu-suggest-item:hover,
.eu-suggest-item:focus {
  background: var(--surface, #f4f6fa);
  outline: none;
}

.eu-suggest-img {
  flex: 0 0 auto;
  width: 52px;
  height: 52px;
  border-radius: var(--ar-radius, 5px);
  background: var(--surface, #f4f6fa);
  overflow: hidden;
}
.eu-suggest-img img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 4px;
}

.eu-suggest-text {
  flex: 1 1 auto;
  min-width: 0;
}
.eu-suggest-name {
  display: block;
  font-size: 14px;
  line-height: 20px;
}
/* The typed part is marked rather than the rest dimmed: it answers "why is
   this here" without making the row harder to read. */
.eu-suggest-name b {
  font-weight: 700;
}
.eu-suggest-model {
  display: block;
  font-size: 12px;
  line-height: 18px;
  color: var(--text-secondary, #6b7280);
}
.eu-suggest-price {
  flex: 0 0 auto;
  font-weight: 600;
  font-size: 14px;
  white-space: nowrap;
  color: var(--text-primary, #132959);
}

.eu-suggest-more {
  display: block;
  padding: 12px 8px 8px;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary, #132959);
  text-decoration: underline;
}
.eu-suggest-empty {
  padding: 16px 8px;
  text-align: center;
  font-size: 14px;
  color: var(--text-secondary, #6b7280);
}

/* The suggestions have to come out over the header's own hairline and over the
   dividers beside the field — and could not, however high their z-index: the
   field sits inside .header-center, which the theme gives z-index 0, and a
   stacking context caps everything within it. Both boxes that make a context
   here are lifted, and only while the panel is open, so the catalogue dropdown
   next door keeps its usual place the rest of the time. */
.header-v2 .header-center:has(.eu-suggest.is-open) {
  z-index: 140;
}
.header-v2 .form-search-nav:has(.eu-suggest.is-open) {
  z-index: 141;
}

/* Below 576px the theme folds every footer column and hides its contents until
   the heading is tapped. The contact column is not folded (client, 2026-08-26):
   a telephone number that has to be found first is a telephone number nobody
   rings. Its heading has lost the class that binds the accordion; this is what
   brings its contents back into view. */
@media (max-width: 575px) {
  .footer-col-block.footer-contact .tf-collapse-content {
    display: block;
  }
}

/* An unearned star.

   The mock-up drew every card with five solid stars because its products were
   invented and its reviews with them. Here the rating is real, and on a shop
   without reviews it is nought — five gold stars over it would be a claim the
   shop has not earned. The template marks the stars above the rating, and this
   is what makes the mark visible: the solid glyph hollowed out to its outline.

   -webkit-text-stroke carries that prefix everywhere and is supported
   everywhere; where it is not, the colour on its own leaves a pale grey solid
   star, which still reads as empty beside a gold one. */
.card-product .star-wrap .icon-Star.is-empty {
  color: #d5d7de;
}

/* ------------------------------------------------------------------ *
 * Toast — the line that says what just happened
 *
 * The template ships no such thing: neither its stylesheet nor its scripts
 * have a toast in them, and OpenCart's own path is worse than nothing —
 * common.js prepends a Bootstrap 3 alert next to a .button('loading') call
 * that throws on the Bootstrap 5 this design uses. So this is ours.
 *
 * The old skin has one too, and it is not shared. The two designs draw
 * everything else differently, and a component made to look right in both
 * ends up looking right in neither; what is shared is the endpoint behind it.
 *
 * Top right, under the header, newest at the bottom, each on its own clock.
 * ------------------------------------------------------------------ */
.ar-toasts {
  position: fixed;
  right: 20px;
  top: 104px;
  z-index: 1090; /* over Bootstrap's backdrop (1050) and offcanvas (1045) */
  display: flex;
  flex-direction: column;
  gap: 12px;
  pointer-events: none; /* the gaps must not swallow clicks on the page */
  max-width: min(390px, calc(100vw - 40px));
}

/* One accent per kind, declared once and read by the badge, the corner wash
   and the timer bar. A fourth kind is three values, not three more rules.
   "off" is the neutral one: taking something off a list is not a success and
   not a failure, and a green tick over "removed" reads as the opposite of
   what happened. */
.ar-toast {
  --ar-accent: #16a34a;
  --ar-accent-soft: rgba(22, 163, 74, .10);
  --ar-accent-wash: rgba(22, 163, 74, .07);
}
.ar-toast.is-off {
  --ar-accent: #64748b;
  --ar-accent-soft: rgba(100, 116, 139, .12);
  --ar-accent-wash: rgba(100, 116, 139, .07);
}
.ar-toast.is-error {
  --ar-accent: #dc2626;
  --ar-accent-soft: rgba(220, 38, 38, .10);
  --ar-accent-wash: rgba(220, 38, 38, .07);
}

.ar-toast {
  position: relative;
  overflow: hidden;
  pointer-events: auto;
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 16px 18px 17px;
  border-radius: var(--ar-radius, 5px);
  border: 1px solid rgba(19, 41, 89, .08);
  /* White card with the status as a wash in the corner the mark sits in,
     rather than a coloured panel. A toast lands over product photography
     several times a session; it should read as the page's furniture and not
     as an alert box dropped on top of it. */
  background:
    radial-gradient(140px 96px at 0% 0%, var(--ar-accent-wash), transparent 72%),
    #fff;
  /* Three shadows: a contact edge, a short drop for thickness, a wide soft
     cast that lifts the card off the page. */
  box-shadow:
    0 1px 2px rgba(19, 41, 89, .05),
    0 8px 18px -8px rgba(19, 41, 89, .14),
    0 28px 54px -18px rgba(19, 41, 89, .22);
  /* transform and opacity only — both composited, so a toast arriving during
     a scroll does not stutter it. */
  transform: translateX(28px) scale(.97);
  opacity: 0;
  transition:
    transform .42s cubic-bezier(.16, 1, .3, 1),
    opacity .3s ease;
}

.ar-toast.is-in { transform: translateX(0) scale(1); opacity: 1; }

/* The mark, where there is no photograph to put it on. */
.ar-toast__icon {
  flex: none;
  width: 30px;
  height: 30px;
  border-radius: 999px;
  display: grid;
  place-items: center;
  background: var(--ar-accent-soft);
  box-shadow: 0 0 0 4px var(--ar-accent-wash);
  color: var(--ar-accent);
}
.ar-toast__icon svg { width: 18px; height: 18px; }

/* With a photograph: the product on the grey plate the cards use, multiplied
   so a white studio background disappears into it. */
.ar-toast__thumb {
  position: relative;
  flex: none;
  width: 54px;
  height: 54px;
  border-radius: var(--ar-radius, 5px);
  background: rgb(242, 243, 245);
  overflow: visible;
}
.ar-toast__thumb img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 5px;
  border-radius: var(--ar-radius, 5px);
  mix-blend-mode: multiply;
}

/* The tick on the corner of the picture; the white ring is what separates it
   from whatever is behind it in the photograph. */
.ar-toast__badge {
  position: absolute;
  right: -5px;
  bottom: -5px;
  width: 20px;
  height: 20px;
  border-radius: 999px;
  display: grid;
  place-items: center;
  background: var(--ar-accent);
  color: #fff;
  box-shadow: 0 0 0 2.5px #fff, 0 2px 6px rgba(19, 41, 89, .2);
}
.ar-toast__badge svg { width: 14px; height: 14px; }

.ar-toast__body { flex: 1 1 auto; min-width: 0; padding-top: 1px; }

.ar-toast__title {
  font-weight: 600;
  font-size: 14px;
  line-height: 20px;
  letter-spacing: -.01em;
  color: var(--text-primary, #132959);
}

/* The product name goes here, and names in this catalogue run long — "DJI
   Mini 5 Pro Fly More Combo (DJI RC 2)". Two lines, then ellipsis. */
.ar-toast__text {
  margin-top: 3px;
  font-size: 13px;
  line-height: 18px;
  color: #6b7280;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* The way on. An underlined word here read as a footnote; a pill reads as the
   thing to press. */
.ar-toast__link {
  display: inline-flex;
  align-items: center;
  margin-top: 11px;
  padding: 7px 15px;
  border: 1px solid rgba(19, 41, 89, .16);
  border-radius: var(--ar-radius, 5px);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-primary, #132959);
  text-decoration: none;
  background: #fff;
  transition: background .2s ease, border-color .2s ease, color .2s ease;
}
.ar-toast__link:hover,
.ar-toast__link:focus-visible {
  background: var(--text-primary, #132959);
  border-color: var(--text-primary, #132959);
  color: #fff;
}

.ar-toast__close {
  flex: none;
  border: 0;
  padding: 0;
  width: 26px;
  height: 26px;
  margin: -3px -5px 0 0;
  border-radius: 999px;
  /* Centred with flex rather than grid: the theme's global button rule sets
     justify-content, and that outlives a switch to grid. */
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: #9aa3ae;
  cursor: pointer;
  transition: background .18s ease, color .18s ease;
}
.ar-toast__close svg { width: 14px; height: 14px; }
.ar-toast__close:hover,
.ar-toast__close:focus-visible {
  background: rgba(19, 41, 89, .06);
  color: var(--text-primary, #132959);
}

/* How long is left: a hairline along the bottom edge, emptying left to right,
   and held where it is while the pointer is over the card — the only visible
   sign that hovering pauses the clock. */
.ar-toast__life {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  transform-origin: left center;
  background: linear-gradient(90deg, var(--ar-accent), var(--ar-accent) 70%, rgba(19, 41, 89, .12));
  opacity: .55;
  animation: ar-toast-life var(--ar-toast-life, 5000ms) linear forwards;
}
.ar-toast.is-held .ar-toast__life { animation-play-state: paused; }

@keyframes ar-toast-life {
  from { transform: scaleX(1); }
  to   { transform: scaleX(0); }
}

/* On a phone the strip spans the screen, and there is no room to throw the
   card in from the right — it drops from above instead. */
@media (max-width: 575px) {
  .ar-toasts {
    right: 12px;
    left: 12px;
    top: 88px;
    max-width: none;
    gap: 10px;
  }
  .ar-toast {
    padding: 14px 15px 15px;
    gap: 12px;
    transform: translateY(-14px) scale(.98);
  }
  .ar-toast.is-in { transform: translateY(0) scale(1); }
  .ar-toast__thumb { width: 46px; height: 46px; }
}

/* Asked for less motion, the message still has to arrive; only the travel is
   dropped. The bar keeps counting — it is information, not decoration. */
@media (prefers-reduced-motion: reduce) {
  .ar-toast { transition: opacity .2s ease; transform: none; }
  .ar-toast.is-in { transform: none; }
}

/* ------------------------------------------------------------------ *
 * The heart and the compare arrows, pressed
 *
 * A switch that looks the same either way answers nothing. Both are switches
 * now, and every card on the page shows which way its own is set — including
 * cards in tabs nobody has opened yet.
 * ------------------------------------------------------------------ */
.card-product .product-action_list .box-icon.is-on {
  background: var(--text-primary, #132959);
  border-color: var(--text-primary, #132959);
  color: #fff;
}
.card-product .product-action_list .box-icon.is-on .icon { color: #fff; }

/* ------------------------------------------------------------------ *
 * Quick view, while it is still loading
 *
 * The panel opens on the press and fills a moment later, so for that moment
 * it is an empty white sheet. Held back to nothing and faded in when the
 * answer lands, which reads as "coming" rather than as "broken".
 * ------------------------------------------------------------------ */
.canvas-quickview .wrap-canvas,
.canvas-quickview .mini-quick-image {
  transition: opacity .2s ease;
}
.canvas-quickview.is-loading .wrap-canvas,
.canvas-quickview.is-loading .mini-quick-image {
  opacity: .25;
}

/* The struck-through price only exists when there is a discount; hidden is
   honoured here because the theme gives every h5 a display of its own. */
.canvas-quickview [data-ar-quick-old][hidden] { display: none; }
.canvas-quickview [data-ar-quick-old] {
  margin: 0;
  text-decoration: line-through;
  font-weight: 400;
}

/* An unearned star, in the panel as on the cards. */
.canvas-quickview .star-wrap .icon-Star.is-empty {
  color: #d5d7de;
}

/* The basket mark is the template's own glyph again (client, 2026-08-27).
   It was replaced on 2026-08-26 by a mask of the outline bag from the current
   shop; against the rest of the row that drawing read heavy, so the mask is
   gone and `icon-ShoppingBagOpen` is left to the icon font — which is what
   every other mark in the header is. */

/* ------------------------------------------------------------------ *
 * The catalogue: filter options
 *
 * Each option is a link, because the whole panel has to work before any
 * script has loaded and a filtered list has to be something you can send
 * somebody. The theme draws its tick boxes on an <input>, and an input is the
 * one thing that cannot also be a link — so the box is a span here, wearing
 * the same twenty pixels, the same corner and the same tick from the icon
 * font as .tf-check.style-large.
 * ------------------------------------------------------------------ */
.filter-group-check .list-item .ar-facet {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text-primary);
  text-decoration: none;
  transition: opacity .25s ease;
}
.filter-group-check .list-item .ar-facet:hover { opacity: .7; }

.ar-facet-box {
  position: relative;
  flex: none;
  width: 20px;
  height: 20px;
  border: 1px solid rgba(0, 0, 0, .2);
  border-radius: 3px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background .3s ease, border-color .3s ease;
}
.ar-facet-box::before {
  font-family: "icomoon";
  content: "\e920";
  position: absolute;
  color: #fff;
  font-size: 14px;
  opacity: 0;
  transform: scale(0);
  transition: opacity .3s ease, transform .3s ease;
}
.ar-facet.is-on .ar-facet-box {
  background: var(--text-primary);
  border-color: var(--text-primary);
}
.ar-facet.is-on .ar-facet-box::before { opacity: 1; transform: scale(1); }

.ar-facet .label { display: flex; align-items: center; gap: 8px; }
.ar-facet .count { color: var(--text-secondary, #6b7280); }

/* Long lists are cut at the number the admin sets and the rest is behind this
   button. Hidden rather than removed, so opening it costs no request. */
.filter-group-check .list-item.eu-extra { display: none; }
.widget-facet.is-open .filter-group-check .list-item.eu-extra { display: flex; }

.widget-facet .eu-more {
  margin-top: 10px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-primary);
  font-size: 13px;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

/* ------------------------------------------------------------------ *
 * The catalogue: the row above the grid
 * ------------------------------------------------------------------ */
.meta-filter-shop.is-empty .filter-tag,
.meta-filter-shop.is-empty .remove-all-filters { display: none; }

/* While a filtered page is on its way. The grid is held back rather than
   emptied: a list that vanishes and comes back reads as a reload, and the
   whole point of fetching in place is that it does not. */
#eu-catalog.eu-loading #eu-results {
  opacity: .45;
  pointer-events: none;
  transition: opacity .18s ease;
}

.eu-empty {
  padding: 60px 20px;
  text-align: center;
}
.eu-empty .eu-empty-title { margin-bottom: 8px; }
.eu-empty .tf-btn { margin-top: 20px; }

/* The price range's own form. With the slider running the two number fields
   are redundant — but they are what makes the range work without scripting,
   so they are hidden only once the slider has actually been built. */
.eu-price-form { display: flex; gap: 8px; margin-top: 14px; }
.eu-price-form.is-slider { display: none; }
.eu-price-input {
  width: 100%;
  height: 40px;
  padding: 0 10px;
  border: 1px solid var(--line, rgba(0, 0, 0, .12));
  border-radius: var(--ar-radius, 5px);
}

/* The filter column had no bottom on a wide screen: pinned in place, it grew
   taller than what was left of the window and the wheel could not reach the
   end of it. Given a ceiling it scrolls inside itself, and the bar is hidden
   because the column already has an edge (client, 2026-08-25). */
@media (min-width: 1200px) {
  .sidebar-filter .canvas-body {
    max-height: calc(100vh - 140px);
    overflow-y: auto;
    scrollbar-width: none;
  }
  .sidebar-filter .canvas-body::-webkit-scrollbar { width: 0; height: 0; }
}

/* ------------------------------------------------------------------ *
 * One card, two layouts
 *
 * The mock-up ships every product twice — once as a tile and once as a row —
 * so nothing in it ever has to be hidden, and the stylesheet has no rule for
 * a tile that happens to carry the row's parts. Here there is one card and
 * the layout is a class on the grid, which halves the page and gives "show
 * more" one place to append to. These are the rules the template family never
 * needed: the row's three columns, put away while the card is a tile.
 * ------------------------------------------------------------------ */
.card-product:not(.product-style_list) > .card-product_button,
.card-product:not(.product-style_list) > .br-line.pseudo-elm,
.card-product:not(.product-style_list) .product-desc_list {
  display: none;
}

/* And the other way round: from a tablet up the row states its price in its
   own column, so the tile's price and basket button underneath it would be
   the same two things said twice. Below that the row folds to a tile shape
   and they are what it has — which is exactly where the theme stops hiding
   .price-wrap, so the two rules meet at the same 768px. */
@media (min-width: 768px) {
  .product-style_list .box-action_add { display: none; }
}

/* The list layout's basket button, navy like every other one.
 *
 * The rule in v4.css names .box-action_add .tf-btn — the button on a tile. In
 * the list layout the same action sits in .card-product_button instead, and
 * was left the template's raspberry: one page, one action, two colours. The
 * client's rule was "the buttons that put something in the basket"
 * (2026-08-24), and this is one of them. */
.card-product_button .group-btn .tf-btn {
  background: var(--text-primary);
  border-color: var(--text-primary);
}
.card-product_button .group-btn .tf-btn:hover {
  background: var(--primary);
  border-color: var(--primary);
}

/* Three columns that actually fit.
 *
 * The theme writes repeat(3, 1fr), and 1fr is minmax(auto, 1fr): a track never
 * shrinks below the widest thing its item cannot break. On a 390px phone the
 * cards' own contents held the tracks at 115px each, 375px in all, and the
 * third column ran off the right edge. minmax(0, …) is the standard remedy —
 * it lets the track go below its content and the card wrap instead. */
.tf-grid-layout.tf-col-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.tf-grid-layout.tf-col-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* ------------------------------------------------------------------ *
 * Three columns on a phone (client, 2026-08-24)
 *
 * Ported from the approved mock-up — v4.css writes exactly this against its
 * own .ar-cols-3, and here the hook is the theme's .tf-col-3, which is what
 * eu-catalog.js puts on the grid. Everything in the block is the price of
 * that third column: at three across a card is about 90px wide inside its
 * padding, and the template's type was drawn for twice that.
 *
 * The basket icon goes rather than the word: "DO KOSZYKA" on one line is what
 * makes the button a button, and on a 320px screen the icon is exactly what
 * pushes it onto two.
 * ------------------------------------------------------------------ */
@media (max-width: 767px) {
  .tf-grid-layout.tf-col-3 {
    column-gap: 8px;
    row-gap: 16px;
  }
  .tf-col-3 .card-product_info {
    padding: 10px;
    padding-top: 0;
    gap: 6px;
  }
  .tf-col-3 .product-cate {
    font-size: 10px;
    line-height: 14px;
  }
  /* Tighter and heavier, because at 12px over two lines the name was the one
     thing on the card that did not read (client, 2026-08-24).

     Asking for 700 is enough now. It was not under Segoe UI Semibold: that
     family holds a single face, so 600 and 700 came back identical and the
     name had to borrow Bold from Segoe UI proper. The shop is set in Nunito
     Sans since 2026-08-29 — a variable font, which simply gets heavier — so
     the borrowed family is gone and only the number is left.

     Both !important marks answer the template's own: the name wears .lh-24
     and .fw-medium, and each of those utilities carries one.

     The height is fixed rather than minimum, and the overflow hidden with it:
     three lines is what the card reserves, and a fourth would push the price
     out of line with the card beside it. -webkit-line-clamp cannot do this
     job here — the name is a flex item, its display is blockified, and the
     -webkit-box the clamp needs never reaches the computed style. */
  .tf-col-3 .card-product_info .name-product {
    font-size: 12px;
    line-height: 14px !important;
    font-weight: 700 !important;
    /* min-height as well as the cap: the theme sets min-height 48px on
       every product name, and a min-height always beats a smaller height.
       Ours is the more specific selector, so naming both pins the box at the
       43px the client asked for (2026-08-25) — three lines of the leading
       above — and the overflow cuts anything longer, so one long name cannot
       push its card's price out of line with the card beside it. */
    min-height: 43px;
    max-height: 43px;
    height: 43px;
    overflow: hidden;
  }
  .tf-col-3 .product-rating .star-wrap {
    font-size: 10px;
  }
  .tf-col-3 .product-rating .text-caption-01 {
    font-size: 11px;
    line-height: 16px;
  }
  .tf-col-3 .product-badge_stock {
    font-size: 9px;
    line-height: 13px;
    padding: 1px 5px;
    gap: 3px;
  }
  .tf-col-3 .product-badge_stock .br-dot {
    width: 5px;
    height: 5px;
  }
  .tf-col-3 .price-wrap .price-new {
    font-size: 12px;
    line-height: 18px;
  }
  .tf-col-3 .box-action_add .tf-btn {
    --px: 6px;
    --h: 32px;
    gap: 0;
  }
  .tf-col-3 .box-action_add .tf-btn .icon {
    display: none;
  }
  .tf-col-3 .box-action_add .tf-btn .text-caption-01 {
    font-size: 10px;
    line-height: 14px;
    white-space: nowrap;
  }
  /* The three marks over the photograph shrink with everything else — at full
     size on a 110px card they were the loudest thing on it (client,
     2026-08-26). */
  .tf-col-3 .product-action_list .box-icon {
    width: 28px;
    height: 28px;
  }
  .tf-col-3 .product-action_list .box-icon .icon {
    font-size: 14px;
  }
}

/* ------------------------------------------------------------------ *
 * The pager
 *
 * The numbers are the theme's own .tf-pagination — 40px outlined squares,
 * the current one filled navy. "Show more" stands beside them in the same
 * outline rather than as a filled block (client, 2026-08-26): the two do the
 * same kind of thing, and shouting one of them made it the loudest element
 * on the page.
 * ------------------------------------------------------------------ */
.ar-pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 32px;
}

.ar-pager .ar-loadmore {
  /* The theme's .pag-item box is written as .tf-pagination .pag-item, and this
     button sits beside that container rather than inside it — so the box is
     spelled out here. Same forty pixels and the same hairline as the numbers
     it stands next to; only wider, and see-through rather than filled
     (client, 2026-08-26). */
  display: flex;
  align-items: center;
  justify-content: center;
  height: 40px;
  width: auto;
  padding: 0 20px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--text-primary, #132959);
  font-weight: 500;
  cursor: pointer;
  transition: border-color .25s ease, background .25s ease;
}
.ar-pager .ar-loadmore:hover {
  border-color: var(--text-primary, #132959);
}
/* The gap in a long pager — "…" is not a page and must not look pressable. */
.ar-pager .pag-item.ar-gap {
  border-color: transparent;
  cursor: default;
}

@media (min-width: 768px) {
  .ar-pager { gap: 12px; }
}

/* ------------------------------------------------------------------ *
 * The list layout has room for two marks, not three
 *
 * Comparison is the one that goes: it is the least used of the three, and it
 * is the one with a panel of its own two clicks away in the header. On a
 * narrow window the row was wrapping onto a second line (client, 2026-08-26).
 * ------------------------------------------------------------------ */
.product-style_list .card-product_button .tf-list [data-ar-compare] {
  display: none;
}

/* ------------------------------------------------------------------ *
 * The product page
 * ------------------------------------------------------------------ */

/* An unearned star, wherever one is drawn. The rule existed for the cards and
   the quick-view panel; the product page draws the same stars in three more
   places — under the name, over the review summary and beside every review —
   and had them all gold on a product nobody has reviewed.

   Filled grey rather than an outline (client, 2026-08-29). The outline was
   drawn by making the glyph transparent and stroking its edge, which left a
   row of thin wire shapes beside a solid gold one — five of them, on every
   product nobody has reviewed yet, which is most of the catalogue. It is the
   same glyph as the gold star now, in grey: one shape, two colours, and the
   row reads as a rating with nothing in it rather than as five empty boxes.

   A shade lighter than the old stroke, because a solid area reads heavier
   than a line of the same colour. */
.icon-Star.is-empty {
  color: #d5d7de;
}
/* Half a star: the solid glyph clipped down the middle over an empty one. A
   gradient would need the glyph as a mask, which an icon font cannot give. */
.icon-Star.is-half {
  position: relative;
  color: #d5d7de;
}
.icon-Star.is-half::after {
  /* The glyph .icon-Star itself prints, read off the icon font rather than
     guessed at. */
  content: "\e900";
  font-family: "icomoon";
  position: absolute;
  left: 0;
  top: 0;
  width: 50%;
  overflow: hidden;
  color: var(--yellow, #f59e0b);
  -webkit-text-stroke: 0;
  -webkit-text-fill-color: currentColor;
}

/* The field no person can see and every robot fills in. Not hidden with the
   hidden attribute: a robot reading the markup skips those, and the point of
   it is to be filled. */
.ar-quick_trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

/* The payment marks under the column, on one line with their caption. */
.ar-pay-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}
.ar-pay-icons {
  display: flex;
  align-items: center;
  gap: 8px;
}
.ar-pay-icons img { height: 30px; width: auto; }

/* Picking a rating in the review form: five stars that behave like the radio
   buttons they are. The input itself is off-screen rather than display:none,
   so it can still be reached by keyboard and still be announced. */
.ar-rate-pick { display: flex; gap: 6px; }
.ar-rate-star { cursor: pointer; }
.ar-rate-star input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}
/* The stars somebody presses to leave a rating, before they press one. Solid
   grey like every other unearned star since 2026-08-29 — an outline here and
   a filled shape on the card two lines above would read as two controls for
   one idea. */
.ar-rate-star .icon {
  font-size: 22px;
  color: #d5d7de;
  transition: color .15s ease;
}
/* Hovering lights the star under the pointer and every star before it, which
   is how a rating control is read. :has does the "and every one before it"
   part — the row is reversed in the markup only for this, no. It is done with
   a sibling selector below instead: the stars stay in reading order. */
.ar-rate-star:hover .icon,
.ar-rate-star:has(input:checked) .icon,
.ar-rate-star:has(~ .ar-rate-star:hover) .icon,
.ar-rate-star:has(~ .ar-rate-star input:checked) .icon {
  color: var(--yellow, #f59e0b);
  -webkit-text-stroke: 0;
  -webkit-text-fill-color: currentColor;
}
.ar-rate-star input:focus-visible + .icon { outline: 2px solid var(--text-primary, #132959); outline-offset: 2px; }

/* The reviewer's initial where the mock-up puts a photograph. This shop has no
   avatars, and a circle with a letter in it says who wrote the review without
   pretending to know more. */
.ar-monogram {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  flex: none;
  border-radius: 999px;
  background: rgba(19, 41, 89, .08);
  color: var(--text-primary, #132959);
  font-weight: 600;
  font-size: 20px;
  text-transform: uppercase;
}

.ar-review-pager { margin-top: 24px; }

/* ------------------------------------------------------------------ *
 * The description, as it actually arrives
 *
 * The mock-up's description tab is two hand-set boxes of paragraphs, so its
 * stylesheet has a rule for .desc_title and one for .desc_info and nothing
 * else. What the catalogue sends is a real document — headings, lists, bold
 * runs — and every tag in it fell through to the theme's global scale: an h3
 * at forty pixels over sixteen-pixel body text, lists with no marks and no
 * spacing, and a measure the full 1290px of the container.
 *
 * So the document is mapped onto the block's own scale: 15/23 for reading,
 * and a 16px uppercase semibold navy label for anything that is a heading
 * (client, 2026-08-27 — a description here is a specification rather than an
 * essay, and reads better set a step tighter than the page around it).
 * ------------------------------------------------------------------ */
.ar-desc > *:first-child { margin-top: 0; }
.ar-desc > *:last-child { margin-bottom: 0; }

.ar-desc p {
  margin: 0;
  font-size: 15px;
  line-height: 23px;
}

.ar-desc h1,
.ar-desc h2,
.ar-desc h3,
.ar-desc h4,
.ar-desc h5,
.ar-desc h6 {
  margin: 8px 0 8px;
  font-size: 16px;
  line-height: 26px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--text-primary, #132959);
}

.ar-desc ul,
.ar-desc ol {
  display: grid;
  gap: 4px;
  margin: 0 0 8px;
  padding-left: 20px;
}
.ar-desc li {
  font-size: 15px;
  line-height: 23px;
}
/* A mark the theme does not draw. Squared off to the stem width of the
   wordmark, which is the shape the whole identity is built on — and in the
   ink of the text rather than in the raspberry, which is this shop's colour
   for something to press. Six bullets of it down a list of features read as
   six things to click. */
.ar-desc ul { list-style: none; padding-left: 0; }
.ar-desc ul > li {
  position: relative;
  padding-left: 18px;
}
.ar-desc ul > li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 9px;
  width: 5px;
  height: 5px;
  border-radius: 1px;
  background: rgba(19, 41, 89, .35);
}

/* A run in bold inside a list item is its label — "Testowana ładowność:" —
   and reads as one only if it is the darker of the two. */
.ar-desc strong,
.ar-desc b {
  font-weight: 600;
  color: var(--text-primary, #132959);
}
.ar-desc em, .ar-desc i { font-style: italic; }
.ar-desc a { color: var(--text-primary, #132959); text-decoration: underline; text-underline-offset: 3px; }
.ar-desc img { max-width: 100%; height: auto; border-radius: var(--ar-radius, 5px); }
.ar-desc table { width: 100%; border-collapse: collapse; margin: 0 0 8px; }
.ar-desc th, .ar-desc td {
  padding: 8px 12px;
  border: 1px solid var(--line);
  font-size: 15px;
  line-height: 24px;
  text-align: left;
}

/* The two boxes of this tab sit at the top of their row rather than stretching
   to the tallest: the figures on the right are a short list and had a hundred
   pixels of nothing under them. */
.tab-content_desc.tf-grid-layout { align-items: start; }

/* No gap of its own (client, 2026-08-27): the blocks inside carry their own
   spacing now, and the grid's 8px was adding to every one of them. */
.tab-content_desc .desc_info {
  display: grid;
  gap: 0;
}

/* ------------------------------------------------------------------ *
 * The specification sheet
 *
 * The approved page sets these rows at 16/26 with 11px 30px of padding, and
 * that is right for what it shows: "Producent — DJI", two words to a row.
 * This catalogue's sheets are DJI's own — four lines of figures per row,
 * forty rows to a product — and at the mock-up's scale that is a wall.
 *
 * So one step down, and the padding the client settled on (2026-08-26):
 * 9px by 12px. The label keeps its weight and loses its uppercase (client,
 * 2026-08-27): the distinction between a name and a value is what makes a
 * sheet scannable, and weight alone carries it. Case does not — set in
 * capitals, "Maks. odporność na wiatr" is a row of rectangles with no
 * ascenders to read the word's shape from, and Polish diacritics sit worse
 * above capitals than above lowercase. The group headings above the sheet
 * keep theirs; that is what separates a heading from a row.
 * ------------------------------------------------------------------ */
.tab-content_information li {
  padding: 9px 12px;
  gap: 32px;
}
.tab-content_information .name,
.tab-content_information .infor {
  font-size: 15px;
  line-height: 24px;
}

/* The theme sets these in capitals; both sheets on this page read as
   sentences instead. */
.tab-content_information .name {
  text-transform: none;
}

/* A group of the sheet, and the space between one group and the next.

   The label gets the same treatment as every other label in this tab. The
   theme only dresses .desc_title inside .tab-content_desc, so outside it the
   group names came out plain and small — smaller than the row labels under
   them, which read as though the sheet had no groups at all. */
.ar-spec-group + .ar-spec-group { margin-top: 32px; }
.ar-spec-group .desc_title {
  margin-bottom: 8px;
  font-size: 16px;
  line-height: 26px;
  text-transform: uppercase;
}

/* The two columns of a sheet row, pushed to their own edges (client,
   2026-08-26): the label against the left, the figure against the right. With
   forty rows down a page that is what lets the eye run down either column
   without reading the other — the theme's version leaves both floating in the
   middle of a very wide row. */
.tab-content_information li {
  justify-content: space-between;
  align-items: baseline;
}
.tab-content_information .name {
  flex: 0 1 auto;
  text-align: left;
}
.tab-content_information .infor {
  flex: 1 1 auto;
  text-align: right;
}

/* ------------------------------------------------------------------ *
 * The quantity, counted
 *
 * The field itself has to keep a plain number in it — the form posts it, and
 * OpenCart reads it — so the counting is drawn in a span laid exactly over it
 * and the input's own text is hidden while that span is there. The field
 * still takes focus, still takes typing, and the moment it does the ghost
 * gets out of the way.
 * ------------------------------------------------------------------ */
.wg-quantity { position: relative; }

.ar-qty-ghost {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  pointer-events: none;
  font: inherit;
  color: inherit;
  font-variant-numeric: tabular-nums;
}
.wg-quantity:has(.ar-qty-ghost) .quantity-product { color: transparent; }
.wg-quantity:focus-within .ar-qty-ghost { display: none; }
.wg-quantity:focus-within .quantity-product { color: inherit; }

/* The total counts too, and a proportional font makes the digits jump about
   as it does. Tabular figures hold their column. */
[data-ar-total] { font-variant-numeric: tabular-nums; }

/* A measure a person can follow. With the key figures beside it the box is
   625px and this never bites; without them the description had the whole
   1290px of the container, and a line that wide loses the eye on its way
   back to the left. */
.ar-desc { max-width: 760px; }

/* ==================================================================== *
 * The basket page  ·  /koszyk and /kasa
 *
 * The approved mock-up never drew a basket, so nothing here is copied from
 * it — but nothing here is invented either. Every value below is one the new
 * skin already uses somewhere else: its hairline, its 5px corner, its navy
 * for anything that decides and its raspberry for anything that removes, its
 * type scale, and its own cart table for the rows, which is what gives a
 * phone the four labelled cards for free.
 *
 * The construction is this shop's own. OpenCart ships a basket page and a
 * checkout page with a button between them; here they are one screen — the
 * things being bought and the four questions on the left, the figures on the
 * right — because the trip to a second screen is where baskets are abandoned.
 * ==================================================================== */

/* ---- the two columns ---- */

.ar-co-flow {
  display: grid;
  gap: 16px;
}

.ar-co-side {
  margin-top: 24px;
}

@media (min-width: 1200px) {
  .ar-co-side {
    margin-top: 0;
  }
}

/* While the shop is being asked something, the parts of the page whose answer
   is about to change stop taking clicks. Not a spinner: the answer arrives in
   a few hundred milliseconds, and a spinner that appears and goes in that time
   reads as a flicker. */
.ar-co.is-busy [data-eu-lines],
.ar-co.is-busy [data-eu-shipping],
.ar-co.is-busy [data-eu-payment],
.ar-co.is-busy [data-eu-summary] {
  opacity: 0.55;
  pointer-events: none;
  transition: opacity 0.15s ease;
}

/* ---- a block, and the number in front of it ---- */

.ar-co-block {
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
  padding: 20px;
}

@media (min-width: 768px) {
  .ar-co-block {
    padding: 24px;
  }
}

.ar-co-block_head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 20px;
}

.ar-co-block_head h5 {
  margin: 0;
}

/* The step marker. It is a number because the page is a sequence — four
   questions worked down in order — and it becomes a tick when its block has
   been answered, which is what keeps it a statement rather than an ornament.
   A number that could never change would be decoration. */
.ar-co-step {
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--surface);
  color: var(--text-primary);
  font-size: 15px;
  line-height: 1;
  font-weight: 600;
  transition: background-color 0.25s ease, color 0.25s ease;
}

.ar-co-block.is-done .ar-co-step {
  background: var(--text-primary);
  color: var(--white);
  /* The digit goes and the tick takes its place. Hidden by size rather than
     by emptying the element, so the number is still there for anything
     reading the page rather than looking at it. */
  font-size: 0;
}

.ar-co-block.is-done .ar-co-step::after {
  font-family: "icomoon";
  content: "\e920";
  font-size: 13px;
}

/* The notes box has no number: it is the one block nobody has to fill in. */
.ar-co-block--plain .ar-co-block_head {
  margin-bottom: 16px;
}

.ar-co-note {
  margin: 0 0 14px;
}

.ar-co-hint {
  margin: 0;
  color: var(--text-secondary);
}

/* ---- signing in: an aside between blocks, not a block ---- */

.ar-co-aside {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 13px 20px;
  border-radius: var(--ar-radius);
  background: var(--surface);
}

.ar-co-aside p {
  margin: 0;
}

.ar-co-login {
  display: grid;
  gap: 14px;
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
}

.ar-co-login_foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

/* ---- fields ----
   The skin styles its fields through a list of "form input[type=…]" selectors,
   and the blocks on this page are deliberately not forms — a checkout that is
   one <form> submits itself on the first Enter pressed in a postcode. So the
   same dressing is written out here for the fields as they actually sit. */

.ar-co .eu-field input,
.ar-co .eu-field textarea,
.ar-co .eu-field select,
.ar-co-login input {
  width: 100%;
  padding: 11px 15px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
  outline: 0;
  box-shadow: none;
  color: var(--text-primary);
  background: var(--white);
  transition: border-color 0.3s ease;
}

.ar-co .eu-field input::placeholder,
.ar-co .eu-field textarea::placeholder,
.ar-co-login input::placeholder {
  color: var(--text-mute);
}

.ar-co .eu-field input:focus,
.ar-co .eu-field textarea:focus,
.ar-co-login input:focus {
  border-color: var(--text-primary);
}

.ar-co .eu-field textarea {
  min-height: 96px;
  resize: vertical;
}

.ar-co .eu-field input[readonly] {
  background: var(--surface);
  color: var(--text-secondary);
}

.ar-co-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

@media (max-width: 575px) {
  .ar-co-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* A field the shop rejected, and the reason under it. Both classes are hooks
   shared with the old design — eu-checkout.js drives one page in two skins
   and looks for these names — so only the dressing is written twice. */
.ar-co .eu-field.is-wrong input,
.ar-co .eu-field.is-wrong textarea,
.ar-co .eu-field.is-wrong .eu-select-btn {
  border-color: #dc2626;
}

.ar-co .eu-field-error {
  margin-top: 6px;
  font-size: 14px;
  line-height: 20px;
  color: #dc2626;
}

.ar-co .eu-method-box.is-wrong {
  border-radius: var(--ar-radius);
  box-shadow: 0 0 0 1px #dc2626;
}

.ar-co-error {
  margin-top: 12px;
  text-align: center;
  font-size: 14px;
  line-height: 20px;
  color: #dc2626;
}

.ar-co-error:empty,
.ar-co-error[hidden] {
  display: none;
}

.ar-co-login .ar-co-error {
  margin-top: 0;
  text-align: start;
}

/* ---- our own dropdowns ----
   A native select is drawn by the operating system, in its language and its
   own idea of a font; eu-select.js replaces every one of them with a button
   and a list.

   Not scoped to a page. These were written for the basket and scoped to it,
   and the account's address form — the only other place in the new design
   with a select on it — then showed the widget undressed: a bold country name
   with two hundred more listed underneath it, because the menu had no box to
   be in and the native control no rule to hide it. The class names are ours
   and appear nowhere in the skin, so they are safe unscoped. */

.eu-select {
  position: relative;
}

.eu-select-native {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.eu-select-btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 11px 15px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
  background: var(--white);
  color: var(--text-primary);
  font: inherit;
  text-align: start;
  cursor: pointer;
  transition: border-color 0.3s ease;
}

.eu-select-btn::after {
  font-family: "icomoon";
  content: "\e905";
  font-size: 10px;
  color: var(--text-secondary);
  transition: transform 0.25s ease;
}

/* One line, always. A branch of Nova Poshta is called "Відділення №9 (до 30 кг
   на одне місце): просп. Незалежності, 62Б", and with nothing to stop it that
   wrapped: the field became two rows tall the moment a branch was chosen,
   while the town beside it stayed one, and the whole card jumped (client,
   2026-08-28). This design never had the rule the old one has.

   min-width: 0 is the part that actually does it. A flex child will not shrink
   below the width of its own text without it, so the ellipsis never arrives
   and the box grows instead. The full name goes on the button's title, for
   anyone who wants to read the rest without opening the list again. */
.eu-select-value {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.eu-select.is-open .eu-select-btn {
  border-color: var(--text-primary);
}

.eu-select.is-open .eu-select-btn::after {
  transform: rotate(180deg);
}

/* The menu is a frame, not a scrolling box (client, 2026-08-28).

   It used to be one scrolling box, and a search field dropped into the top of
   it would have scrolled away with the first turn of the wheel. Now the frame
   holds its height and the list inside it scrolls, so the field stays where it
   was put. */
.eu-select-menu {
  position: absolute;
  z-index: 20;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  display: none;
  flex-direction: column;
  max-height: 300px;
  padding: 6px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
  background: var(--white);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.1);
}

.eu-select.is-open .eu-select-menu {
  display: flex;
}

/* The search row. Present in the markup of every dropdown and shown only on
   the long ones — the branch list goes from one town's ninety to the next
   town's four, and a control that appeared once and stayed would be wrong
   half the time. */
.eu-select-find {
  display: none;
  flex: 0 0 auto;
  padding: 2px 2px 8px;
}

.eu-select.has-find .eu-select-find {
  display: block;
}

.eu-select-find_input {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
  background: var(--surface);
  color: var(--text-primary);
  font: inherit;
  font-size: 15px;
  line-height: 20px;
  outline: none;
  transition: border-color 0.2s ease, background-color 0.2s ease;
}

.eu-select-find_input::placeholder {
  color: var(--text-secondary);
}

.eu-select-find_input:focus {
  border-color: var(--text-primary);
  background: var(--white);
}

/* Safari draws its own round clear button inside type=search, at a size that
   fits nothing else on this page. */
.eu-select-find_input::-webkit-search-decoration,
.eu-select-find_input::-webkit-search-cancel-button {
  -webkit-appearance: none;
}

.eu-select-list {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}

/* Said once, when the typing matches nothing — otherwise an empty white box
   reads as a list that failed to load. */
.eu-select-none {
  flex: 0 0 auto;
  padding: 10px;
  color: var(--text-secondary);
  font-size: 15px;
  line-height: 22px;
}

.eu-select-item {
  padding: 8px 10px;
  border-radius: var(--ar-radius);
  font-size: 15px;
  line-height: 22px;
  color: var(--text-primary);
  cursor: pointer;
  transition: background-color 0.2s ease;
}

/* Hover and the keyboard highlight are the same state seen two ways, so they
   wear the same face — otherwise arrowing down a filtered list looks like
   nothing is happening. */
.eu-select-item:hover,
.eu-select-item.is-lit {
  background: var(--surface);
}

/* The one already chosen, and one that cannot be. */
.eu-select-item.is-on {
  background: var(--surface);
  color: var(--primary);
}

.eu-select-item.is-off {
  color: var(--text-mute);
  pointer-events: none;
}

/* Near the bottom of the window the list opens upwards instead. */
.eu-select.is-up .eu-select-menu {
  top: auto;
  bottom: calc(100% + 4px);

  /* And the search row goes to the bottom — next to the button the shopper
     just pressed, rather than at the far end of the list. Reversed by the
     layout and not in the markup, so the tab order stays the reading order. */
  flex-direction: column-reverse;
}

/* ---- delivery and payment: one card per answer ---- */

.ar-co .eu-method-box {
  display: grid;
  gap: 10px;
}

.ar-co-method {
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
  transition: border-color 0.25s ease;
}

.ar-co-method.is-on {
  border-color: var(--text-primary);
}

.ar-co-method_head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  margin: 0;
  cursor: pointer;
}

.ar-co-method_icon {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  color: var(--text-primary);
}

.ar-co-method_icon svg {
  display: block;
  width: 100%;
  height: 100%;
}

.ar-co-method_title {
  flex: 1 1 auto;
  color: var(--text-primary);
}

.ar-co-method_price {
  flex-shrink: 0;
  color: var(--text-primary);
}

/* The panel is in the markup under every card, so what the shopper typed
   survives a change of mind and a repaint. Only the chosen one is shown —
   and being genuinely hidden is also what tells the step marker that the
   fields under an unchosen method are not the shopper's to fill in. */
.ar-co-method_body {
  display: none;
  padding: 0 16px 16px;
}

.ar-co-method.is-on .ar-co-method_body {
  display: grid;
  gap: 12px;
}

/* ---- the strips above the basket ---- */

.ar-co-strips {
  display: grid;
  gap: 10px;
  margin-bottom: 20px;
}

.ar-co-strip {
  padding: 11px 16px;
  border-radius: var(--ar-radius);
}

.ar-co-strip p {
  margin: 0;
}

/* What the basket is saving, and how long is left of the offer when an end
   date has been set on it. Raspberry, because it is the one thing on the page
   that is an offer rather than a fact. */
.ar-co-strip--sale {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  background: rgba(234, 15, 91, 0.08);
  color: var(--primary);
}

.ar-co-strip--sale .icon {
  font-size: 16px;
  line-height: 22px;
  flex-shrink: 0;
}

.ar-co-clock {
  font-weight: 600;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.ar-co-strip--free {
  background: var(--surface);
}

/* The skin's own bar, with the marker at the head of it. The marker is
   called round and the skin draws it square — everywhere else on this
   storefront a five-pixel corner was enough, but a 20px box with a lorry in
   it reads as a badge that fell off something unless it is a circle. */
.ar-co-strip--free .progress-cart {
  margin-top: 10px;
  margin-bottom: 0;
}

.ar-co-strip--free .progress-cart .round {
  border-radius: 50%;
}

/* The cell holding a line's total. Not the skin's .cart_total: that one is a
   flex box, and a table-cell told to be a flex box stops being a table-cell —
   the figure then ignores the row's vertical-align and sits low. */
.ar-co-total {
  text-align: start;
}

/* ---- the basket rows ---- */

.ar-co-table {
  width: 100%;
}

/* The skin reserves 357px for the product column and 850px for the row, which
   is the width of its own demo page and about a hundred more than this layout
   has: the basket shares the screen with the order box. Narrowed to what the
   content actually needs — the photograph, two lines of name, and four
   figures — so the table fits instead of scrolling sideways. */
@media (min-width: 576px) {
  .ar-co-table td:nth-child(1),
  .ar-co-table th:nth-child(1) {
    min-width: 0;
  }
  .ar-co-table td:nth-child(2),
  .ar-co-table th:nth-child(2) {
    min-width: 104px;
  }
  .ar-co-table td:nth-child(3),
  .ar-co-table th:nth-child(3) {
    min-width: 116px;
  }
  .ar-co-table td:nth-child(4),
  .ar-co-table th:nth-child(4) {
    min-width: 108px;
  }
  .ar-co-table td:nth-child(5),
  .ar-co-table th:nth-child(5) {
    min-width: 36px;
    width: 36px;
  }
}

.ar-co-table th {
  padding-bottom: 12px;
  text-align: start;
  color: var(--text-secondary);
  font-weight: 400;
}

/* The skin gives its cells no padding at all and lets a 120px photograph set
   the height of the row. The photograph here is smaller, so the air is asked
   for rather than borrowed. */
.ar-co-table td {
  padding: 16px 0;
}

.ar-co-table tbody tr:last-child td {
  border-bottom: 0;
  padding-bottom: 0;
}

.ar-co-table .cart_product {
  gap: 16px;
  padding-right: 16px;
}

.ar-co-table .img-prd {
  width: 80px;
  max-width: 80px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
}

/* Contained rather than cropped: these are photographs of equipment on white,
   and cropping one to a square cuts the propellers off. */
.ar-co-table .img-prd img {
  aspect-ratio: 1;
  object-fit: contain;
  background: var(--white);
}

.ar-co-line {
  display: grid;
  gap: 4px;
}

.ar-co-line p {
  margin: 0;
}

.ar-co-oos {
  color: #dc2626;
}

/* The field is a real field — a shopper who wants nine of something types a
   nine rather than pressing "+" eight times. The skin disables it because its
   own demo has nothing listening. */
.ar-co-table .wg-quantity .quantity-product {
  pointer-events: auto;
}

.ar-co-table .cart_remove {
  text-align: end;
}

/* A button, not the skin's bare span: reachable by keyboard, and named for a
   screen reader. Everything that made it look like a button is stripped. */
.ar-co-table .cart_remove .remove {
  padding: 0;
  background: none;
  border-radius: var(--ar-radius);
  cursor: pointer;
}

/* On a phone the skin turns each row into a card and labels every cell from
   its data-cart-title. That is right for the three figures and wrong for the
   cross: a row reading "Usuń" with a 12px target at the far end of it is the
   hardest thing on the page to hit. The cross goes to the corner of the card
   instead, where a card's remove button lives. */
@media (max-width: 767px) {
  .ar-co-table .cart_remove {
    position: absolute;
    top: 2px;
    right: 0;
    width: auto;
    padding: 0;
  }

  .ar-co-table .cart_remove .remove.icon {
    width: 26px;
    height: 26px;
    font-size: 13px;
  }

  /* So a long name does not run under it. */
  .ar-co-table td:first-child {
    padding-right: 32px;
  }

  /* The same words as the column headings on a wide screen, so they read the
     same way. The skin sets them in its raspberry, which on this page is the
     colour of removing something — three pink labels per card, and none of
     them an action. */
  .ar-co-table .tf-cart_item td[data-cart-title]::before {
    color: var(--text-secondary);
    font-weight: 400;
    font-size: 15px;
  }
}

/* ---- money that counts ----
   Every figure that can change carries the number behind it, and moves to a
   new one by counting rather than by being swapped for it. Tabular figures,
   or the digits change width as they run and the column shivers. */
.ar-money {
  font-variant-numeric: tabular-nums;
}

/* ---- the order box ---- */

.ar-co-order.box-order-summary {
  padding: 24px;
  border: 0;
  border-radius: var(--ar-radius);
  /* The one tinted panel on the page. Every block on the left is a question
     asked on white; this is the answer, and it is worth being a different
     surface rather than a fifth bordered box. */
  background: var(--surface);
}

.ar-co-order_title {
  margin-bottom: 20px;
}

.ar-co-order .subtotal {
  border-bottom-color: rgba(0, 0, 0, 0.06);
}

.ar-co-order .total-order {
  margin-top: 20px;
  margin-bottom: 0;
  padding-top: 16px;
  border-top: 1px solid rgba(0, 0, 0, 0.09);
}

.ar-co-order_tax {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 6px 0 0;
}

/* The coupon. The skin's version is 500px wide with 24px of padding, drawn for
   the full width of a cart page; this one lives in a 300px column. */
.ar-co-coupon {
  max-width: none;
  margin: 20px 0 0;
}

.ar-co-coupon input {
  padding: 11px 15px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
  background: var(--white);
  color: var(--text-primary);
  min-width: 0;
}

.ar-co-coupon input:focus {
  border-color: var(--text-primary);
  outline: 0;
}

.ar-co-coupon input::placeholder {
  color: var(--text-mute);
}

.ar-co-coupon .tf-btn {
  --px: 18px;
  flex-shrink: 0;
}

.ar-co-coupon_off {
  margin-top: 8px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-secondary);
  cursor: pointer;
}

.ar-co-coupon_off:hover {
  color: var(--primary);
}

.ar-co-agree {
  margin: 20px 0 12px;
  align-items: flex-start;
}

.ar-co-agree .tf-check {
  margin-top: 3px;
}

.ar-co-agree label {
  margin: 0;
}

.ar-co-agree a {
  color: var(--text-primary);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.ar-co-agree a:hover {
  color: var(--primary);
}

/* The button that ends the visit. Navy at rest and raspberry under the
   pointer, which on this storefront is what every button that buys something
   does — the two on the product page and the bar on every card. */
.ar-co-place {
  background: var(--text-primary);
  border-color: var(--text-primary);
}

.ar-co-place:hover {
  background: var(--primary);
  border-color: var(--primary);
}

.ar-co-order_note {
  margin: 12px 0 0;
  text-align: center;
}

/* ---- nothing in it yet ---- */

.ar-co-empty {
  display: grid;
  justify-items: center;
  gap: 14px;
  max-width: 460px;
  margin: 0 auto;
  padding: 40px 20px 60px;
  text-align: center;
}

.ar-co-empty p {
  margin: 0;
}

.ar-co-empty_mark {
  width: 56px;
  height: 56px;
  color: var(--text-mute);
}

.ar-co-empty_mark svg {
  width: 100%;
  height: 100%;
  display: block;
}

.ar-co-empty .tf-btn {
  margin-top: 6px;
}

/* ==================================================================== *
 * The account  ·  /moje-konto and everything under it
 *
 * The skin ships most of this: the bordered nav down the left, the counting
 * boxes, the recent-orders table, the order cards, the labelled fields. What
 * is written here is what it does not ship — the block that says who is
 * signed in, the way into that nav on a phone, the screens in front of the
 * login, and the handful of panels our account has and the mock-up's did not
 * (saved addresses, one order in full, returns).
 * ==================================================================== */

/* ---- who is signed in ---- */

.ar-ac-who {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px;
  margin-bottom: 16px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
  background: var(--surface);
}

/* The mock-up's photograph, replaced by initials in the same circle: the shop
   never asks for a picture, so the alternative was a placeholder avatar on
   every account in the database. */
.ar-ac-avatar {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--text-primary);
  color: var(--white);
  font-size: 16px;
  line-height: 1;
  font-weight: 600;
}

.ar-ac-who_text {
  min-width: 0;
}

.ar-ac-who_text p {
  margin: 0;
}

/* ---- the way into the menu on a phone ----
   The column is four hundred pixels of navigation; above the page somebody
   asked for, that is not navigation but a wall. So it moves into the same
   drawer the catalogue's filters use, and this bar opens it — in the flow of
   the page rather than pinned to the edge of the screen, where it would float
   over whatever scrolled under it. */

.ar-ac-bar {
  margin-bottom: 20px;
}

.ar-ac-bar button {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 16px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
  background: var(--white);
  color: var(--text-primary);
  cursor: pointer;
  transition: border-color 0.25s ease;
}

.ar-ac-bar button:hover {
  border-color: var(--text-primary);
}

.ar-ac-bar button .icon:first-child {
  font-size: 20px;
}

/* The arrow at the far end, whichever way the page reads. */
.ar-ac-bar button .icon:last-child {
  margin-inline-start: auto;
}

.ar-ac-canvas .canvas-body {
  padding: 20px;
}

.ar-ac-canvas .my-account-nav {
  max-width: none;
}

/* ---- the column, at a size that fits one screen ----

   The client asked for the whole column to be visible without scrolling
   (2026-08-27). It was seven rows of 20/26 text in 20px of padding — 67px a
   row, 469px of navigation, and with the person on top of it the column ran
   past the fold on a laptop.

   A step down in both: the text to the size the rest of the interface uses
   for a link, and the padding to what a row of that size needs. Same seven
   rows now come to about 340px, and the column ends above the fold with the
   sticky offset already taken off. Nothing is smaller than it should be —
   16/24 is the size of every other menu in this shop. */
.my-account-nav .link-account {
  padding: 12px 16px;
  gap: 10px;
  font-size: 16px;
  line-height: 24px;
}

.my-account-nav .link-account .icon {
  font-size: 20px;
}

.ar-ac-who {
  gap: 10px;
  padding: 12px;
  margin-bottom: 12px;
}

.ar-ac-avatar {
  width: 38px;
  height: 38px;
  font-size: 14px;
}

.ar-ac-who_text p.h6 {
  font-size: 16px;
  line-height: 24px;
}

@media (min-width: 992px) {
  /* Clear of the header, which is fixed once the page has been scrolled. */
  .sidebar-account-wrap {
    position: sticky;
    top: 100px;
  }
}

/* ---- the dashboard ---- */

/* The mock-up runs the three counts through a carousel. Three boxes fit on
   every screen this shop is read on — a grid that becomes one column on a
   phone shows all three at once, and a carousel hides two of them behind a
   swipe nobody knows is there. */
.ar-ac-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}

/* Three across on a phone as well, the way the catalogue's cards are: the
   counts are two digits and a short label, and stacked they were three tall
   boxes pushing the orders themselves below the fold. The picture is what goes
   — at this width it is the half of the box that says nothing. */
@media (max-width: 767px) {
  .ar-ac-stats {
    gap: 8px;
  }

  .acount-order_stats .order-box {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    padding: 14px 12px;
  }

  .acount-order_stats .order_icon {
    display: none;
  }

  .acount-order_stats .info__count {
    font-size: 24px;
    line-height: 30px;
  }

  .acount-order_stats .info__label {
    font-size: 10px;
    line-height: 14px;
  }
}

.acount-order_stats .order-box {
  border-radius: var(--ar-radius);
}

.acount-order_stats .info__label {
  margin: 4px 0 0;
  color: var(--text-secondary);
}

.account-my_recent {
  border-radius: var(--ar-radius);
}

@media (max-width: 767px) {
  .account-my_recent {
    padding: 20px;
  }
}

/* ---- the three tables ----
   The skin lays its table out as a flex row — not a table layout — with four
   fixed column widths drawn around its own demo data: 80, 360, 80, 90. The
   dashboard here has five columns, an order has four and its history three,
   and the figures are Polish zloty rather than two-digit dollars. So every
   column width is set again, per table, instead of inherited. */

.my-account-content .table-my_recent tr {
  align-items: center;
}

.my-account-content .table-my_recent th,
.my-account-content .table-my_recent td {
  width: auto;
  flex: 0 0 auto;
}

/* Recent orders: number · what was in it · what it cost · where it is · in full */
.ar-ac-recent th:nth-child(1),
.ar-ac-recent td:nth-child(1) {
  width: 76px;
}

.ar-ac-recent th:nth-child(2),
.ar-ac-recent td:nth-child(2) {
  flex: 1 1 auto;
  min-width: 0;
}

.ar-ac-recent th:nth-child(3),
.ar-ac-recent td:nth-child(3) {
  width: 116px;
  text-align: end;
}

.ar-ac-recent th:nth-child(4),
.ar-ac-recent td:nth-child(4) {
  width: 168px;
}

.ar-ac-recent th:nth-child(5),
.ar-ac-recent td:nth-child(5) {
  width: 124px;
  text-align: end;
}

/* A status is a sentence in Polish — "oczekuje na płatność" — where the skin's
   demo had one word. It wraps rather than running over the column beside it. */
.ar-ac-recent .tb-order_status {
  min-width: 0;
  white-space: normal;
  text-align: center;
  font-size: 11px;
  line-height: 15px;
  padding: 5px 10px;
}

/* On a phone the row folds instead of running off the side of the screen. The
   skin's table is a flex row already, so this is a matter of letting it wrap
   and saying what goes where: the number and the total on the first line, what
   was bought on the second, where it is and the way in on the third. */
@media (max-width: 767px) {
  .ar-ac-recent thead {
    display: none;
  }

  .ar-ac-recent tr {
    flex-wrap: wrap;
    gap: 10px 16px;
  }

  .ar-ac-recent td {
    width: auto !important;
  }

  .ar-ac-recent td:nth-child(1) {
    order: 0;
  }

  .ar-ac-recent td:nth-child(3) {
    order: 0;
    margin-inline-start: auto;
  }

  .ar-ac-recent td:nth-child(2) {
    order: 1;
    flex: 1 1 100%;
  }

  .ar-ac-recent td:nth-child(4) {
    order: 2;
  }

  .ar-ac-recent td:nth-child(5) {
    order: 2;
    margin-inline-start: auto;
  }
}

.ar-ac-recent .tb-order_product {
  align-items: center;
  gap: 12px;
}

.ar-ac-recent .img-prd {
  width: 48px;
  height: 48px;
  flex-shrink: 0;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
  overflow: hidden;
}

/* Contained rather than cropped: these are photographs of equipment on white,
   and a square crop takes the propellers off. */
.ar-ac-recent .img-prd img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: var(--white);
}

/* One order: what · how many · each · together */
.ar-ac-lines th:first-child,
.ar-ac-lines td:first-child {
  flex: 1 1 auto;
  min-width: 0;
  white-space: normal;
}

.ar-ac-lines th:nth-child(2),
.ar-ac-lines td:nth-child(2) {
  width: 70px;
  text-align: center;
}

.ar-ac-lines th:nth-child(3),
.ar-ac-lines td:nth-child(3) {
  width: 116px;
  text-align: end;
}

.ar-ac-lines th:nth-child(4),
.ar-ac-lines td:nth-child(4) {
  width: 124px;
  text-align: end;
}

/* colspan does nothing to a row laid out with flex, so the totals are two
   cells: the name takes what is left, the figure keeps the last column. */
.ar-ac-lines tfoot td:first-child {
  flex: 1 1 auto;
  min-width: 0;
  text-align: end;
}

.ar-ac-lines tfoot td:last-child {
  width: 124px;
  text-align: end;
}

/* Its history: when · what · what was said */
.ar-ac-history th:first-child,
.ar-ac-history td:first-child {
  width: 130px;
}

.ar-ac-history th:nth-child(2),
.ar-ac-history td:nth-child(2) {
  width: 168px;
}

.ar-ac-history th:last-child,
.ar-ac-history td:last-child {
  flex: 1 1 auto;
  min-width: 0;
  white-space: normal;
}

/* Neutral, and deliberately so: a history row carries the status as a word
   and not as an id, so there is nothing to colour it by. Painting every entry
   the same green or blue would be a claim the page cannot check. */
.ar-ac-history .tb-order_status {
  background: var(--surface);
  color: var(--text-primary);
  min-width: 0;
  white-space: normal;
  text-align: center;
  font-size: 11px;
  line-height: 15px;
  padding: 5px 10px;
}

.table-my_recent .tb-order_view {
  text-align: end;
}

/* The skin styles the name and the small print under it on its own demo data;
   ours is a real product name and can be long. */
.table-my_recent .prd_name {
  display: block;
  max-width: 320px;
  white-space: normal;
}

.table-my_recent .prd_type {
  margin: 2px 0 0;
  color: var(--text-secondary);
}

.table-my_recent td {
  padding-top: 14px;
  padding-bottom: 14px;
}

/* ---- the orders ---- */

.wg-my-order {
  border-radius: var(--ar-radius);
}

.ar-ac-order_foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}

.ar-ac-order_sum {
  display: flex;
  align-items: baseline;
  gap: 12px;
}

.ar-ac-pager {
  margin-top: 28px;
}

/* ---- one order, in full ---- */

.ar-ac-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1px;
  margin-bottom: 24px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
  overflow: hidden;
}

.ar-ac-fact {
  display: grid;
  gap: 4px;
  padding: 16px 20px;
  background: var(--white);
}

.ar-ac-two {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  margin-bottom: 24px;
}

@media (max-width: 767px) {
  .ar-ac-two {
    grid-template-columns: minmax(0, 1fr);
  }
}

.ar-ac-panel {
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
}

.ar-ac-panel p {
  margin: 0;
}

.ar-ac-panel_title {
  margin-bottom: 12px;
}

.ar-ac-second {
  margin-top: 24px;
}

.ar-ac-lines td:first-child {
  white-space: normal;
  max-width: 380px;
}

/* The rule above the totals goes on the row, not on its cells: the row is
   laid out with flex and its two cells do not reach across the table, so a
   border on them drew two stubs with a gap between. */
.ar-ac-lines tfoot tr:first-child {
  border-top: 1px solid var(--line);
}

.ar-ac-lines tfoot tr:first-child td {
  padding-top: 14px;
}

.ar-ac-total_name {
  text-align: end;
  color: var(--text-secondary);
}

/* ---- addresses ---- */

.ar-ac-addresses {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}

@media (max-width: 767px) {
  .ar-ac-addresses {
    grid-template-columns: minmax(0, 1fr);
  }
}

.ar-ac-address {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
}

.ar-ac-address p {
  margin: 0;
  flex: 1 1 auto;
}

.ar-ac-address_do {
  display: flex;
  align-items: center;
  gap: 16px;
}

/* Deleting is not a button. It is the one destructive thing on the account,
   and a quiet link beside a solid button is the right weight for it. */
.ar-ac-address_del {
  color: var(--text-secondary);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.ar-ac-address_del:hover {
  color: var(--primary);
}

.ar-ac-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 24px;
}

/* ---- fields ----
   The skin labels its fields above them and styles the field; the label class
   it uses is not in its stylesheet. */

/* The skin's field is a grid with place-items: start, which sizes its children
   to their content. Its own inputs get a width of 100% and do not notice; a
   dropdown of ours is a div, and came out as wide as the word "Poland". */
.my-account-content .tf-field,
.ar-page .tf-field {
  justify-items: stretch;
}

.tf-lable {
  display: block;
  margin-bottom: 8px;
  font-size: 15px;
  line-height: 22px;
  color: var(--text-primary);
}

.tf-lable .text-primary {
  margin-inline-start: 2px;
}

/* Every control in a field is as wide as the field — except the ones that are
   a mark rather than a box. A radio told to be 100% wide comes out as a rule
   across the page with its label squeezed into whatever is left, which is what
   the returns form's five reasons looked like. */
.my-account-content .tf-field input:not([type=radio]):not([type=checkbox]),
.my-account-content .tf-field select,
.my-account-content .tf-field textarea,
.ar-page .tf-field input:not([type=radio]):not([type=checkbox]),
.ar-page .tf-field select,
.ar-page .tf-field textarea {
  width: 100%;
  padding: 11px 15px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
  outline: 0;
  color: var(--text-primary);
  background: var(--white);
  transition: border-color 0.3s ease;
}

.my-account-content .tf-field input:not([type=radio]):not([type=checkbox]):focus,
.my-account-content .tf-field textarea:focus,
.ar-page .tf-field input:not([type=radio]):not([type=checkbox]):focus,
.ar-page .tf-field textarea:focus {
  border-color: var(--text-primary);
}

.my-account-content .tf-field input::placeholder,
.my-account-content .tf-field textarea::placeholder,
.ar-page .tf-field input::placeholder,
.ar-page .tf-field textarea::placeholder {
  color: var(--text-mute);
}

.my-account-content .tf-field textarea {
  min-height: 110px;
  resize: vertical;
}

.ar-ac-narrow {
  max-width: 180px;
}

/* The eye that shows the password. The skin binds it in its own main.js and
   draws the field, but not the field's own class. */
.password-wrapper {
  position: relative;
}

.password-wrapper .toggle-pass {
  position: absolute;
  top: 50%;
  inset-inline-end: 14px;
  transform: translateY(-50%);
  z-index: 2;
  font-size: 18px;
  color: var(--text-secondary);
  cursor: pointer;
}

.password-wrapper .toggle-pass:hover {
  color: var(--text-primary);
}

.my-account-content .password-wrapper input.password-field,
.ar-page .password-wrapper input.password-field {
  padding-inline-end: 44px;
}

.ar-ac-checks {
  display: grid;
  gap: 10px;
}

.ar-ac-checks .checkbox-wrap {
  align-items: flex-start;
  gap: 8px;
}

.ar-ac-checks .tf-check {
  margin-top: 3px;
  flex-shrink: 0;
}

.ar-ac-checks label {
  margin: 0;
  cursor: pointer;
}

/* The privacy notice and the terms of sale are named inside these sentences,
   and they are the two links a shopper is asked to read before ticking the
   box. The skin underlines links only under the pointer, which on one word in
   the middle of a sentence means nothing marks it at all. */
.ar-ac-checks label a {
  color: var(--text-primary);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.ar-ac-checks label a:hover {
  color: var(--primary);
}

.ar-ac-radios {
  display: grid;
  gap: 10px;
}

.ar-ac-radios.is-row {
  grid-auto-flow: column;
  justify-content: start;
  gap: 24px;
}

.ar-ac-radio {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}

.ar-ac-radio input {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
}

.ar-ac-captcha {
  display: grid;
  gap: 10px;
}

.ar-ac-captcha img {
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
}

.ar-ac-error {
  margin-top: 6px;
  font-size: 14px;
  line-height: 20px;
  color: #dc2626;
}

/* ---- what the shop has to say ---- */

.ar-ac-alert {
  padding: 12px 16px;
  margin-bottom: 20px;
  border-radius: var(--ar-radius);
  font-size: 15px;
  line-height: 22px;
}

.ar-ac-alert.is-good {
  background: rgba(22, 163, 74, 0.1);
  color: #15803d;
}

.ar-ac-alert.is-bad {
  background: rgba(220, 38, 38, 0.1);
  color: #dc2626;
}

.ar-ac-alert.is-hint {
  background: var(--surface);
  color: var(--text-primary);
}

.ar-ac-alert a {
  color: inherit;
  text-decoration: underline;
}

.ar-ac-lead {
  margin: -8px 0 24px;
  max-width: 720px;
}

.ar-ac-empty {
  display: grid;
  justify-items: center;
  gap: 14px;
  padding: 40px 20px;
  text-align: center;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
}

.ar-ac-empty p {
  margin: 0;
}

/* ---- the wish list ---- */

.ar-ac-wish .card-product_wrapper {
  border-radius: var(--ar-radius);
}

/* The cross that takes a product off the list. Everywhere else on the shop
   this corner holds a heart that switches; here the card is the entry, so the
   mark says what pressing it does. */
.ar-ac-wish .product-action_list .box-icon .icon-Close {
  font-size: 13px;
}

/* On the wish list the two controls are the page, not a flourish over it.
   The skin slides them out of a card on hover — which is right in a catalogue,
   where the card is a product and the icons are extras, and wrong here, where
   the cross is the only way to take something off the list. A touch screen has
   no hover at all. */
.ar-ac-wish .card-product .product-action_list li {
  opacity: 1;
  visibility: visible;
  transform: none;
}

.ar-ac-wish .card-product .box-action_add {
  position: static;
  height: auto;
  bottom: auto;
  opacity: 1;
  visibility: visible;
}

.ar-ac-wish .card-product.is-going {
  opacity: 0;
  transform: scale(0.97);
  transition: opacity 0.2s ease, transform 0.2s ease;
}

@media (prefers-reduced-motion: reduce) {
  .ar-ac-wish .card-product.is-going {
    transition: none;
  }
}

.ar-ac-wish .price-wrap {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

/* ==================================================================== *
 * "Done"  ·  the thank-you page, and logging out
 *
 * One template answers both: OpenCart renders common/success after an order
 * and again after a log-out, with the rich half switched off in the second
 * case. So the two states are dressed together — the account port needed the
 * plain one, and the new checkout would otherwise have ended on the old skin.
 * ==================================================================== */

.ar-th-head {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 20px 24px;
  margin-bottom: 24px;
  border-radius: var(--ar-radius);
  background: rgba(22, 163, 74, 0.08);
}

.ar-th-head p {
  margin: 0;
}

/* Green, and the only green on the storefront: it is the one moment a page
   reports that something worked. */
.ar-th-mark {
  width: 46px;
  height: 46px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: #16a34a;
  color: var(--white);
}

.ar-th-mark svg {
  width: 24px;
  height: 24px;
}

.ar-th-no {
  color: var(--text-secondary);
  margin-bottom: 2px !important;
}

.ar-th-side {
  display: grid;
  gap: 16px;
  margin-top: 24px;
}

@media (min-width: 992px) {
  .ar-th-side {
    margin-top: 0;
  }
}

/* What happens next. Numbered because it is a sequence and the shopper is in
   the middle of it — the first step is ticked because it has already
   happened, which is the whole point of showing the list. */
.ar-th-steps {
  display: grid;
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: ar-step;
}

.ar-th-steps li {
  position: relative;
  padding-inline-start: 34px;
  font-size: 15px;
  line-height: 22px;
  color: var(--text-secondary);
  counter-increment: ar-step;
}

.ar-th-steps li::before {
  content: counter(ar-step);
  position: absolute;
  inset-inline-start: 0;
  top: 0;
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--surface);
  color: var(--text-primary);
  font-size: 13px;
  font-weight: 600;
}

.ar-th-steps li.is-done {
  color: var(--text-primary);
}

.ar-th-steps li.is-done::before {
  content: "\e920";
  font-family: "icomoon";
  font-size: 11px;
  background: #16a34a;
  color: var(--white);
}

.ar-th-address {
  display: grid;
  gap: 2px;
  margin: 0;
  font-style: normal;
}

.ar-th-actions {
  display: grid;
  gap: 12px;
}

.ar-th-help {
  margin: 0;
  text-align: center;
}

.ar-th-totals {
  display: grid;
  gap: 8px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}

.ar-th-total {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  font-size: 15px;
  line-height: 22px;
  color: var(--text-secondary);
}

.ar-th-total.is-grand {
  padding-top: 10px;
  margin-top: 2px;
  border-top: 1px solid var(--line);
  font-size: 18px;
  line-height: 26px;
  font-weight: 600;
  color: var(--text-primary);
}

/* Logging out, and anything else the shop simply reports as finished. */
.ar-th-done {
  display: grid;
  justify-items: center;
  gap: 16px;
  max-width: 520px;
  margin: 0 auto;
  padding: 40px 20px 60px;
  text-align: center;
}

.ar-th-done p {
  margin: 0;
}

/* ==================================================================== *
 * The calendar
 *
 * One date field on this side of the port — the day an order was placed, on
 * the returns form — and the same rule as the dropdowns: a native calendar is
 * drawn by the operating system, in the operating system's language and its
 * own idea of a font, and on a Polish shop read on an English phone that is a
 * month name nobody asked for. eu-date.js hides the control and draws the
 * panel; the field underneath stays a real type=date, so what is posted is
 * still the Y-m-d the controller expects.
 *
 * The same panel as the old design's, in this one's colours: navy for the day
 * that has been chosen, raspberry for today, and the five-pixel corner.
 * ==================================================================== */

.eu-date {
  position: relative;
  display: block;
}

.eu-date-native {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: 0;
  border: 0;
  opacity: 0;
  pointer-events: none;
  bottom: 6px;
  left: 12px;
}

/* Deliberately the fields' own measurements to the pixel: this one stands
   beside the order number in a two-column row, and a date box a hair taller
   than the field next to it reads as sloppy without the reader being able to
   say why. */
.eu-date-btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 11px 15px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
  background: var(--white);
  text-align: start;
  color: var(--text-primary);
  cursor: pointer;
  transition: border-color 0.25s ease;
}

.eu-date-btn:hover,
.eu-date.is-open .eu-date-btn {
  border-color: var(--text-primary);
}

.eu-date.is-empty .eu-date-btn {
  color: var(--text-mute);
}

.eu-date.is-disabled .eu-date-btn {
  opacity: 0.55;
  pointer-events: none;
}

.eu-date-value {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.eu-date-icon {
  flex: none;
  display: grid;
  place-items: center;
  color: var(--text-secondary);
}

.eu-date-icon svg {
  width: 19px;
  height: 19px;
}

.eu-date.is-open .eu-date-icon {
  color: var(--text-primary);
}

.eu-date-pop {
  position: absolute;
  z-index: 60;
  left: 0;
  top: calc(100% + 6px);
  width: 306px;
  max-width: calc(100vw - 30px);
  padding: 14px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12);
  display: none;
}

.eu-date.is-open .eu-date-pop {
  display: block;
}

.eu-date.is-up .eu-date-pop {
  top: auto;
  bottom: calc(100% + 6px);
}

.eu-date.is-right .eu-date-pop {
  left: auto;
  right: 0;
}

.eu-date-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 10px;
}

.eu-date-month {
  font-size: 14px;
  font-weight: 600;
  line-height: 20px;
  color: var(--text-primary);
}

/* The centring is spelled out in full, because the skin gives every button on
   the site justify-content: space-between — which on a one-item row means "at
   the start", and the chevron sat against the wall of its circle. */
.eu-date-nav {
  flex: none;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

.eu-date-nav svg {
  width: 17px;
  height: 17px;
}

.eu-date-nav:hover {
  background: var(--surface);
  color: var(--text-primary);
}

.eu-date-week,
.eu-date-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}

.eu-date-week {
  margin-bottom: 4px;
}

.eu-date-week span {
  text-align: center;
  font-size: 11px;
  font-weight: 600;
  line-height: 18px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-mute);
}

/* A square plate centred in its column, not a cell the width of the column. */
.eu-date-day {
  width: 36px;
  height: 36px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: var(--ar-radius);
  background: transparent;
  font-size: 14px;
  font-weight: 500;
  line-height: 1;
  color: var(--text-primary);
  cursor: pointer;
  transition: background 0.14s ease, color 0.14s ease;
}

.eu-date-day:hover {
  background: var(--surface);
}

/* A halo rather than an outline: the panel puts focus on a day the moment it
   opens, so this is on screen every time, and a hard ring outside a 36px
   plate reads as a second, badly drawn border around it. */
.eu-date-day:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(234, 15, 91, 0.22);
}

/* The days either side of the month are shown rather than left blank — a grid
   with holes in it is harder to count across than one that runs on. */
.eu-date-day.is-outside {
  color: var(--text-mute);
}

/* The order these four win in is the order they are written: an ordinary day,
   then today, then a day out of range, then the day that has been chosen — so
   today is raspberry, today-but-unavailable is grey, and today-and-chosen is
   navy. */
.eu-date-day.is-today,
.eu-date-day.is-today:hover {
  background: var(--primary);
  color: var(--white);
  font-weight: 600;
}

/* Out of range: paler than the days either side of the month, and that is all.
   A rule struck through half the grid — every day after today, on this form —
   made the panel read as damaged. */
.eu-date-day.is-off,
.eu-date-day.is-off:hover {
  background: transparent;
  color: #d7dae0;
  font-weight: 500;
  cursor: not-allowed;
}

.eu-date-day.is-on,
.eu-date-day.is-on:hover {
  background: var(--text-primary);
  color: var(--white);
  font-weight: 600;
}

/* On a phone the panel is as wide as the field and the days are a thumb tall. */
@media (max-width: 575px) {
  .eu-date-pop {
    width: 100%;
    min-width: 268px;
  }

  .eu-date-day {
    height: 40px;
    font-size: 15px;
  }
}

/* ==================================================================== *
 * The gap under a page title  (client, 2026-08-27)
 *
 * Every re-drawn page opens the same way: the breadcrumb and the heading in
 * their own band, then the content. The skin puts 60px between them, which is
 * the figure it uses between two unrelated sections — and these two are not
 * unrelated, they are a heading and the thing it heads. Twenty pixels reads as
 * one block instead of two.
 *
 * Written as "the spacing that follows a page title" rather than by changing
 * flat-spacing-3 itself: that class also separates real sections further down
 * the same pages, and 60px is right there.
 * ==================================================================== */
.section-page-title + .flat-spacing-3 {
  padding-top: 20px;
}

/* ==================================================================== *
 * The written pages, the contact page, the two ways in, and the 404
 * ==================================================================== */

/* ---- in front of the login ----
   Two columns, the way the shop already had them (client, 2026-08-27): the
   form on the left and the other errand on the right. Signing in and opening
   an account are different things, and side by side a shopper sees at a glance
   which one is theirs — stacked in one card they read as one form with two
   ways to submit it. */

.ar-gate {
  --bs-gutter-y: 20px;
}

.ar-gate-card {
  height: 100%;
  padding: 28px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
}

/* Sized to what it holds, not to the form beside it (client, 2026-08-27).
   Stretched, it was a grey rectangle with a sentence at the top, a button at
   the bottom and a hand's width of nothing in between — which reads as a block
   somebody forgot to finish rather than as a panel.

   The tint is a shallow gradient rather than a flat fill, so the panel has a
   direction and the eye lands on the heading. */
.ar-gate-side {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 14px;
  padding: 28px;
  border-radius: var(--ar-radius);
  background: linear-gradient(180deg, var(--surface) 0%, rgba(241, 244, 248, 0.35) 100%);
}

.ar-gate-side p {
  margin: 0;
}

/* And it says what the account is actually for. Four lines of substance beat
   any amount of decoration in the same space, and they are the argument for
   pressing the button underneath them. */
.ar-gate-perks {
  display: grid;
  gap: 10px;
  width: 100%;
  margin: 4px 0 2px;
  padding: 0;
  list-style: none;
}

.ar-gate-perks li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

/* Outlined, not filled (client, 2026-08-27): four solid discs down the side
   of a quiet panel read as four bullets shouting, and the list is meant to be
   read rather than counted.

   Drawn rather than set from the icon font, for the same reason (client, same
   day): the ring was a 1.5px shadow and the tick a 10px glyph, so the box was
   heavier than what it held and the check hardly showed. As one drawing the
   two strokes answer to each other. */
.ar-gate-perks .ar-tick {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  margin-top: 1px;
  display: block;
  color: var(--text-primary);
}

@media (max-width: 575px) {
  .ar-gate-card,
  .ar-gate-side {
    padding: 20px;
  }
}

.ar-gate-title {
  margin-bottom: 20px;
}

/* ---- signed in ---- */

/* Bottom right of the person's own 24px box (client, 2026-08-27) — the
   wrapper around the glyph is what it is measured from, so the two move
   together at any size the bar is drawn at. */
.ar-signed-in {
  position: absolute;
  inset-inline-end: -4px;
  bottom: -4px;
  width: 13px;
  height: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--primary);
  color: var(--white);
  /* A ring in the header's own colour, so the mark reads as sitting on top of
     the icon rather than cut into it. */
  box-shadow: 0 0 0 2px var(--white);
}

.ar-signed-in svg {
  width: 9px;
  height: 9px;
}

.ar-gate-lead {
  margin: -12px 0 20px;
}

.ar-gate-forgot {
  display: flex;
  justify-content: flex-end;
}

/* ---- the written pages ---- */

.ar-doc-toc {
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
}

/* Below the desktop the contents block is not a sidebar any more — the
   column stacks above the document — and it had no space under it at all, so
   the first line of the text started against its border (client, 2026-08-29,
   on a phone). */
 (max-width: 991px) {
  .ar-doc-toc {
    margin-bottom: 28px;
  }
}

@media (min-width: 992px) {
  .ar-doc-toc {
    top: 100px;
  }
}

.ar-doc-toc_title {
  margin: 0 0 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.ar-doc-toc ol {
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* No numbering of our own. These headings are the client's, and on the legal
   pages they are already numbered — "§ 1. Postanowienia ogólne" — so a counter
   in front of them read "1.§ 1." all the way down the column. Where a page's
   headings carry no numbers, a plain list is the right shape anyway. */

.ar-doc-toc li a {
  display: block;
}

.ar-doc-toc li a:hover {
  color: var(--primary);
}

/* The body of a legal page or a guide. The text is the client's, written in
   the admin, so everything here is about giving prose room rather than about
   any particular block. Around 70 characters a line is where reading stops
   being work. */
.ar-doc {
  max-width: 72ch;
  color: var(--main);
  font-size: 16px;
  line-height: 27px;
}

.ar-doc > *:first-child {
  margin-top: 0;
}

.ar-doc h2,
.ar-doc h3,
.ar-doc h4 {
  margin: 36px 0 12px;
}

.ar-doc h2 {
  font-size: 24px;
  line-height: 32px;
}

.ar-doc h3 {
  font-size: 20px;
  line-height: 28px;
}

.ar-doc h4 {
  font-size: 17px;
  line-height: 26px;
}

.ar-doc p,
.ar-doc ul,
.ar-doc ol,
.ar-doc table {
  margin: 0 0 16px;
}

.ar-doc ul,
.ar-doc ol {
  padding-inline-start: 22px;
}

.ar-doc li {
  margin-bottom: 6px;
}

.ar-doc a {
  color: var(--text-primary);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.ar-doc a:hover {
  color: var(--primary);
}

.ar-doc img {
  max-width: 100%;
  height: auto;
  border-radius: var(--ar-radius);
}

/* A wide table on a phone scrolls inside itself rather than pushing the page
   sideways. */
.ar-doc table {
  display: block;
  overflow-x: auto;
  border-collapse: collapse;
}

.ar-doc th,
.ar-doc td {
  padding: 10px 14px;
  border: 1px solid var(--line);
  text-align: start;
}

.ar-guides {
  margin-top: 40px;
}

.ar-guides .entry-desc {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin: 0;
}

/* ---- contact ---- */

.ar-contact-side {
  display: grid;
  gap: 24px;
  padding: 28px;
  border-radius: var(--ar-radius);
  background: var(--surface);
}

.ar-contact-list {
  display: grid;
  gap: 24px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ar-contact-list li {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}

.ar-contact-list p {
  margin: 0;
}

.ar-contact-icon {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--white);
  color: var(--text-primary);
  font-size: 20px;
}

.ar-contact-legal {
  padding-top: 20px;
  border-top: 1px solid rgba(0, 0, 0, 0.08);
}

.ar-contact-legal p + p {
  margin-top: 6px;
}

.ar-contact-form {
  padding: 28px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
}

@media (max-width: 575px) {
  .ar-contact-side,
  .ar-contact-form {
    padding: 20px;
  }
}

.ar-contact-form_title {
  margin-bottom: 20px;
}

@media (max-width: 991px) {
  .ar-contact-form {
    margin-top: 20px;
  }
}

/* ---- nothing at this address ---- */

.ar-404 {
  display: grid;
  justify-items: center;
  gap: 16px;
  max-width: 620px;
  margin: 0 auto;
  padding: 20px 0 40px;
  text-align: center;
}

.ar-404 p {
  margin: 0;
}

/* Large, pale and behind everything else: the number is the least useful thing
   on the page and the most recognisable, so it says where you are without
   taking the place of what to do next. */
.ar-404-mark {
  font-size: clamp(72px, 14vw, 140px);
  line-height: 1;
  font-weight: 600;
  color: var(--surface);
}

.ar-404-search {
  display: flex;
  gap: 8px;
  width: 100%;
  max-width: 460px;
  margin-top: 8px;
}

.ar-404-search input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 11px 15px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
  background: var(--white);
  color: var(--text-primary);
  outline: 0;
  transition: border-color 0.25s ease;
}

.ar-404-search input:focus {
  border-color: var(--text-primary);
}

.ar-404-search input::placeholder {
  color: var(--text-mute);
}

.ar-404-search .tf-btn {
  flex-shrink: 0;
}

/* ==================================================================== *
 * The reading face  (client, 2026-08-27)
 *
 * Nunito Sans wherever there are sentences to read rather than words to
 * scan: paragraphs, a product's description and its table of figures, the
 * legal pages and the guides. Everything else — headings, buttons, labels,
 * prices, the menu — stays in the interface family the design was drawn in.
 *
 * Listed by what a thing IS rather than by page, so a block that moves keeps
 * its face and a page added later needs nothing written here.
 * ==================================================================== */

/* Chosen by what a block IS, never by tag (client, 2026-08-27).

   The first version of this said "p" — and in this template family a p is
   just as often a small label as it is a paragraph: the last crumb in a
   breadcrumb, the code under a product's name, the count beside a filter.
   Those sit in a row next to links and spans that kept the interface face,
   and two faces in one line do not share a baseline or an x-height, so the
   row visibly stepped up and down. The client caught it on the breadcrumb.

   So the reading face is given to blocks that hold prose, and everything
   inside them inherits it. Nothing that lives in a row with something else
   gets it at all. */
.ar-doc,
.ar-desc,
.tab-content_information li,
.entry-desc,
.ar-doc-lead {
  font-family: var(--ar-text);
}

/* The lead paragraph under a page's heading, and the same kind of standalone
   sentence in a panel. Named one by one rather than through .text-body-*,
   because those utilities are also worn by labels standing in rows. */
.main-page-title > p,
.ar-gate-side > p,
.ar-gate-lead,
.ar-contact-form + p,
.ar-ac-lead,
.ar-th-done > p {
  font-family: var(--ar-text);
}

/* ---- the breadcrumb, one typeface ---- */

/* Pinned rather than left to inherit (client, 2026-08-27). Nothing gives the
   crumbs the reading face today — the rule that did was replaced above — but
   the row is a mixed bag of elements: an anchor, an icon and a p, sitting on
   one line at 14px. Two faces in a row that short do not share an x-height,
   and the eye reads the difference as the line stepping up and down.
   Declaring the face here means a rule added later for paragraphs, or for one
   of the text- utilities, cannot reach in and split the row again.

   :not(.icon) so the caret keeps icomoon: it is a glyph, not a letter. */
.breadcrumbs,
.breadcrumbs :not(.icon) {
  font-family: var(--ar-font);
}

/* ---- the page's own title ----

   One step down from the template's h3 (client, 2026-08-27). The theme sets
   every h3 at clamp(24px, 3.4vw, 36px), which is right for a section heading
   inside a page and loud for the line that only repeats what the breadcrumb
   above it just said. Scoped to the title block so the section headings keep
   the size they were drawn at, and kept as a clamp so it still comes down on
   a narrow screen. */
.section-page-title .main-page-title h3 {
  font-size: clamp(22px, 2.8vw, 30px);
  line-height: clamp(30px, 3.4vw, 38px);
}

/* ==================================================================== *
 * The line under a product's name  (client, 2026-08-27)
 *
 * Three facts separated by hairlines: how it is rated, its code, whether it
 * is in stock. Two things were wrong with it. The label and its value were
 * the same colour and weight, so "Kod produktu: DJI-190911" read as one
 * run-on phrase; and the review count sat against the last star with nothing
 * between them.
 * ==================================================================== */

/* The label is the quiet half. The value is what the reader came for, so it
   is the shop's navy and a shade heavier — the difference does the work that
   a colon on its own could not. */
.tf-product-info-wrap .product-infor-meta .infor_sku {
  gap: 6px;
  color: var(--text-secondary);
}

.tf-product-info-wrap .product-infor-meta .infor_sku > span {
  color: var(--text-primary);
  font-weight: 600;
}

/* Room between the stars and what follows them. */
.tf-product-info-wrap .product-infor-meta .infor_rate {
  gap: 8px;
}

.tf-product-info-wrap .product-infor-meta .rate__count {
  color: var(--text-secondary);
}

/* The rating is a link now; it should say so under the pointer without
   turning into a blue underlined thing in the middle of a quiet row. */
.ar-rate-link {
  transition: color 0.25s ease;
}

.ar-rate-link:hover .rate__count {
  color: var(--primary);
}

.ar-rate-link .star-wrap {
  pointer-events: none;
}

/* ==================================================================== *
 * The caret in a breadcrumb  (client, 2026-08-27)
 *
 * The boxes were already centred — link, caret and last crumb all shared a
 * centre line to the pixel. What did not line up was the ink inside them: an
 * icon font hangs its glyph off the cap height, while text is read off its
 * x-height, so the arrow sat high even though its box did not.
 *
 * Measured rather than guessed. Rendering both to a canvas and comparing the
 * centres of the actual marks — not the boxes — put the caret 2.51px above
 * the letters beside it, at 12px against 14px. Two pixels closes it without
 * landing the glyph on a half-pixel, where it would blur.
 * ==================================================================== */
.breadcrumbs .icon-CaretRight {
  transform: translateY(2px);
}

/* ==================================================================== *
 * The catalogue's control bar on a phone  (client, 2026-08-27)
 *
 * Three controls, one row: what to filter by, what to sort by, how many
 * across. The bar was built as two halves — the filter button and the view
 * switches on the left, sorting on the right — which is right on a desktop and
 * on a phone put sorting on a second line of its own, ninety pixels of
 * furniture above the first product.
 *
 * The halves are dissolved rather than re-marked up: display:contents takes
 * .col-left and .col-right out of the box tree and hands their three children
 * straight to the bar, where order puts them in the sequence the client drew.
 * The markup stays one shape for both widths, which matters because this bar
 * is also re-rendered by the filtering script.
 * ==================================================================== */

/* ---- the control bar on a phone ---- */

@media (max-width: 767.98px) {
  .tf-shop-control {
    flex-wrap: nowrap;
    gap: 10px;
  }

  .tf-shop-control .col-left,
  .tf-shop-control .col-right {
    display: contents;
  }

  .tf-shop-control .tf-btn-filter {
    order: 1;
    flex-shrink: 0;
  }

  /* The middle takes what the two ends leave, and the name of the current
     sort is cut rather than allowed to push them apart. */
  .tf-shop-control .tf-control-sorting {
    order: 2;
    flex: 1 1 auto;
    min-width: 0;
    justify-content: center;
  }

  .tf-shop-control .tf-dropdown-sort {
    min-width: 0;
  }

  .tf-shop-control .text-sort-value {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .tf-shop-control .tf-control-layout {
    order: 3;
    flex-shrink: 0;
  }
}

/* ==================================================================== *
 * The search on a phone  (client, 2026-08-27)
 *
 * A button in the bar, and a panel that comes down out of the header when it
 * is pressed. The panel is positioned against the header, not the page: the
 * header is fixed once anything has been scrolled, and a panel hung off the
 * document would have stayed behind at the top of it.
 * ==================================================================== */

.ar-msearch {
  position: absolute;
  z-index: 5;
  inset-inline: 0;
  top: 100%;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
  background: var(--white);
  box-shadow: 0 12px 24px rgba(19, 41, 89, .08);

  /* Closed: out of sight, out of the tab order, and out of the way of taps.
     visibility rather than display so the way in and out can be animated. */
  visibility: hidden;
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity .2s ease, transform .2s ease, visibility .2s;
}

.ar-msearch.is-open {
  visibility: visible;
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .ar-msearch {
    transition: none;
  }
}

.ar-msearch_form {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
  background: var(--white);
}

.ar-msearch_form:focus-within {
  border-color: var(--text-primary);
}

.ar-msearch_mark {
  flex-shrink: 0;
  font-size: 20px;
  color: var(--text-secondary);
}

.ar-msearch_form input[name="search"] {
  flex: 1 1 auto;
  min-width: 0;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-primary);
  outline: 0;
}

.ar-msearch_form input[name="search"]::placeholder {
  color: var(--text-mute);
}

.ar-msearch_close {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--surface);
  color: var(--text-secondary);
  cursor: pointer;
}

.ar-msearch_close svg {
  width: 16px;
  height: 16px;
}

/* The suggestions belong to the form, and eu-search.js hangs them there
   itself. All they need here is to start below the box rather than on top of
   it, and to stop before the foot of the screen on a short phone. */
.ar-msearch_form .eu-suggest {
  top: calc(100% + 8px);
  max-height: 60vh;
  overflow-y: auto;
}

/* The button sits in a row the client stripped down to three marks in August;
   this is the fourth, and only below xl. */
.ar-msearch-li .nav-icon-item {
  border: 0;
  background: none;
  padding: 0;
  cursor: pointer;
}

/* ==================================================================== *
 * The list pages that are not the catalogue
 *
 * Search results, Promocje and one brand are the catalogue with the filter
 * column taken out: same cards, same grid, same pager, and a control row that
 * carries only the count and the sort. The catalogue's own row is not reused
 * because its left half is a filter button, and an empty button-shaped gap
 * reads as something that failed to load.
 * ==================================================================== */

.ar-list-control {
  margin-bottom: 20px;
}

.ar-list-control .col-left p {
  margin: 0;
}

/* Nothing here yet — a brand the shop has stopped carrying, a promotion that
   has ended. Not an error page: it says so and offers the way on. */
.ar-list-empty {
  display: grid;
  justify-items: start;
  gap: 14px;
  padding: 28px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
}

.ar-list-empty p {
  margin: 0;
}

/* ---- a chip ----
   One thing to press, named, with how many are behind it. The same shape does
   the departments under a search that found nothing, the departments a brand
   is sold in, and the jump list on the table of contents — it is the same
   offer in all three places. */
.ar-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--text-primary);
  font-size: 14px;
  line-height: 22px;
  white-space: nowrap;
  transition: border-color .25s ease, background .25s ease, color .25s ease;
}

.ar-chip span {
  color: var(--text-mute);
  font-size: 12px;
}

.ar-chip:hover,
.ar-chip.is-all {
  border-color: var(--text-primary);
  color: var(--text-primary);
}

.ar-chip.is-all {
  background: var(--surface);
}

.ar-chip:hover span {
  color: var(--text-secondary);
}

.ar-find-depts_list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* ==================================================================== *
 * The search results
 * ==================================================================== */

/* The panel stays above the results so a query can be narrowed without going
   back. It is a real GET form to the same route — the shop searches with
   scripting switched off. */
.ar-find-panel {
  display: grid;
  gap: 14px;
  margin-bottom: 24px;
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
  background: var(--surface);
}

.ar-find-row {
  display: grid;
  gap: 12px;
  grid-template-columns: 1fr;
}

@media (min-width: 768px) {
  .ar-find-row {
    grid-template-columns: minmax(0, 1fr) 240px auto;
    align-items: center;
  }
}

.ar-find-field {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
  background: var(--white);
}

.ar-find-field:focus-within {
  border-color: var(--text-primary);
}

.ar-find-field .icon {
  flex-shrink: 0;
  font-size: 20px;
  color: var(--text-secondary);
}

.ar-find-field input {
  flex: 1 1 auto;
  min-width: 0;
  height: 46px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-primary);
  outline: 0;
}

.ar-find-field input::placeholder {
  color: var(--text-mute);
}

.ar-find-go {
  justify-content: center;
}

.ar-find-options {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 24px;
}

/* The word that was searched for, wherever it is quoted back. */
.ar-find-query {
  color: var(--primary);
}

/* Nothing found. The most common answer this page gives, so it is written
   rather than left as one grey line. */
.ar-find-none {
  display: grid;
  justify-items: center;
  gap: 14px;
  max-width: 640px;
  margin: 0 auto;
  padding: 20px 0 40px;
  text-align: center;
}

.ar-find-none p {
  margin: 0;
}

.ar-find-none_mark {
  width: 56px;
  height: 56px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--surface);
  color: var(--text-secondary);
}

.ar-find-none_mark svg {
  width: 28px;
  height: 28px;
}

.ar-find-tips {
  display: grid;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
  color: var(--text-secondary);
  font-size: 15px;
  line-height: 24px;
}

.ar-find-depts {
  display: grid;
  justify-items: center;
  gap: 10px;
  width: 100%;
  margin-top: 6px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
}

.ar-find-depts .ar-find-depts_list {
  justify-content: center;
}

/* ==================================================================== *
 * One brand
 * ==================================================================== */

.ar-brand-head {
  display: grid;
  gap: 20px;
  align-items: center;
  margin-bottom: 24px;
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
}

@media (min-width: 768px) {
  .ar-brand-head {
    grid-template-columns: auto minmax(0, 1fr);
  }
}

/* The logo keeps its own proportions on a light plate: a wordmark cropped to a
   square is a wordmark with its ends cut off. */
.ar-brand-logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 160px;
  height: 72px;
  padding: 12px 20px;
  border-radius: var(--ar-radius);
  background: var(--surface);
}

.ar-brand-logo img {
  max-width: 160px;
  max-height: 48px;
  width: auto;
  height: auto;
  object-fit: contain;
}

.ar-brand-depts {
  display: grid;
  gap: 10px;
}

.ar-brand-depts p {
  margin: 0;
}

.ar-brand-depts_alone {
  margin-bottom: 24px;
}

/* ==================================================================== *
 * The brands
 * ==================================================================== */

.ar-brands {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}

.ar-brand-card {
  display: grid;
  gap: 16px;
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
}

.ar-brand-card_img {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 120px;
  padding: 16px;
  border-radius: var(--ar-radius);
  background: var(--surface);
}

.ar-brand-card_img img {
  max-width: 100%;
  max-height: 88px;
  width: auto;
  height: auto;
  object-fit: contain;
}

.ar-brand-card_body {
  display: grid;
  gap: 10px;
  justify-items: start;
}

.ar-brand-card_body h5,
.ar-brand-card_body p {
  margin: 0;
}

.ar-brand-card_go {
  margin-top: 4px;
}

/* ==================================================================== *
 * The catalogue's table of contents
 * ==================================================================== */

/* The whole page in one line. On a phone it scrolls sideways rather than
   wrapping to three rows and pushing the catalogue below the fold. */
.ar-cats-jump {
  flex-wrap: nowrap;
  overflow-x: auto;
  margin-bottom: 28px;
  padding-bottom: 4px;
  scrollbar-width: none;
}

.ar-cats-jump::-webkit-scrollbar {
  display: none;
}

.ar-cats-dept + .ar-cats-dept {
  margin-top: 40px;
}

.ar-cats-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px 12px;
  margin-bottom: 16px;
}

.ar-cats-name {
  margin: 0;
}

/* Pushed to the far end, whichever way the page reads. */
.ar-cats-all {
  margin-inline-start: auto;
}

.ar-cats-grid {
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

.ar-cat-tile {
  display: grid;
  gap: 12px;
  padding: 16px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
  color: var(--text-primary);
  transition: border-color .25s ease;
}

.ar-cat-tile:hover {
  border-color: var(--text-primary);
}

.ar-cat-tile_img {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 120px;
  border-radius: var(--ar-radius);
  background: var(--surface);
}

.ar-cat-tile_img img {
  max-width: 100%;
  max-height: 104px;
  width: auto;
  height: auto;
  object-fit: contain;
  mix-blend-mode: multiply;
}

.ar-cat-tile_body {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.ar-cat-tile_name {
  font-weight: 600;
  line-height: 22px;
}

.ar-cat-tile_n {
  flex-shrink: 0;
  color: var(--text-mute);
  font-size: 13px;
}

/* ==================================================================== *
 * The comparison table
 *
 * Carried over from the old design rather than drawn again: the table is the
 * same table in both — a column per product, a row per fact, the product row
 * sticky and each sheet folding — and only the ink differs. The rules below
 * are that stylesheet's, with its near-black swapped for this design's navy.
 *
 * --eu-header-h is what the sticky row is told to stop below. This design's
 * header is 64px once it has stuck, where the old one is 90.
 * ==================================================================== */

:root {
  --eu-header-h: 64px;
}

/* ==========================================================================
   Comparison
   ==========================================================================
   A column per product, a row per fact, and three devices that make 133 rows
   of specification readable instead of exhausting.

   1. The product row sticks to the top of the screen, so the column being read
      is always named. That only works where the table is *not* inside a
      scrolling box — a sticky element sticks to its nearest scrollport, and a
      wrapper with overflow-x:auto becomes one for both axes. So the wrapper
      only scrolls below 992px, where the table genuinely cannot fit; above it
      the table is laid out to fit the container and sticks to the viewport.

   2. Below 992px the label column pins to the left edge instead. Different
      affordance, same purpose: on a phone you swipe between products and the
      row still says which figure you are looking at.

   3. Each specification sheet folds. Only the first is open — see the
      <noscript> in the template for what happens without scripting. */

.eu-cmp-bar {
  display: flex;
  align-items: center;
  gap: 10px 22px;
  flex-wrap: wrap;
  padding-bottom: 16px;
  margin-bottom: 4px;
}

.eu-cmp-tally {
  font-size: 13px;
  color: var(--text-secondary);
  margin-right: auto;
}

/* The differences switch. Built rather than borrowed: the theme has no toggle
   of its own, and a bare checkbox beside a black button reads as a form. */
.eu-cmp-switch {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  user-select: none;
  font-size: 14px;
  margin: 0;
}

.eu-cmp-switch input { position: absolute; opacity: 0; width: 0; height: 0; }

.eu-cmp-switch-track {
  width: 38px;
  height: 22px;
  border-radius: 999px;
  background: var(--line);
  position: relative;
  transition: background .22s ease;
  flex: 0 0 38px;
}

.eu-cmp-switch-track::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--white);
  transition: transform .22s ease;
}

.eu-cmp-switch input:checked + .eu-cmp-switch-track { background: var(--text-primary); }
.eu-cmp-switch input:checked + .eu-cmp-switch-track::after { transform: translateX(16px); }
.eu-cmp-switch input:focus-visible + .eu-cmp-switch-track { outline: 2px solid var(--text-primary); outline-offset: 2px; }

/* The colour is stated, not inherited: the theme paints every <button> white
   for its dark pills, and leaving it unstated here is white text on white. */
.eu-cmp-expand {
  border: 1px solid var(--line);
  background: none;
  color: var(--text-primary);
  border-radius: var(--ar-radius);
  padding: 7px 16px;
  font-size: 13px;
  transition: .22s ease;
}

.eu-cmp-expand:hover { border-color: var(--text-primary); background: var(--text-primary); color: var(--white); }

/* ---- the table ---- */

.eu-cmp-scroll { overflow: visible; }

.eu-cmp-table {
  width: 100%;
  border-collapse: collapse;
  /* Fixed, so the four products get equal columns whatever their names and
     specifications happen to be. Left to itself the browser sized columns by
     content and a drone with a long paragraph took half the page. */
  table-layout: fixed;
}

.eu-cmp-table th,
.eu-cmp-table td {
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
  font-size: 13px;
  line-height: 20px;
  overflow-wrap: anywhere;
}

.eu-cmp-label {
  width: 190px;
  font-weight: 400;
  color: var(--text-secondary);
  background: var(--white);
}

/* Opaque, not a wash. The label column is pinned to the left edge on a phone
   and the product columns slide underneath it — a translucent stripe let the
   specification read straight through the label sitting on top of it. */
.eu-cmp-table tbody tr:nth-child(even) > * { background: var(--ar-cmp-zebra); }

/* ---- the product row ---- */

.eu-cmp-head > * {
  position: sticky;
  top: var(--eu-header-h, 90px);
  z-index: 3;
  background: var(--white);
  border-bottom: 1px solid var(--line);
  padding-top: 18px;
  padding-bottom: 18px;
  vertical-align: bottom;
}

.eu-cmp-head .eu-cmp-label { vertical-align: bottom; padding-bottom: 22px; }

.eu-cmp-photo {
  display: block;
  width: 100%;
  max-width: 150px;
  margin-bottom: 12px;
  border-radius: 10px;
  background: rgb(242, 243, 245);
  overflow: hidden;
  isolation: isolate;
  transition: width .25s ease, max-width .25s ease, margin .25s ease;
}

/* Multiply, as everywhere else in the shop: the pack shots are on white, and
   without it each one sits in a white box on the grey. */
.eu-cmp-photo img {
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: contain;
  padding: 8%;
  display: block;
  mix-blend-mode: multiply;
}

/* Two lines, always. The cells are bottom-aligned so that the buy buttons form
   one line across the row, and a name that runs to two lines in one column and
   one in the next would break that line by exactly its own height. */
.eu-cmp-name {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 40px;
  font-size: 14px;
  line-height: 20px;
  font-weight: 500;
  margin-bottom: 6px;
}

.eu-cmp-price { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.eu-cmp-price .current-price { font-size: 15px; font-weight: 600; }
.eu-cmp-price .old-price { text-decoration: line-through; opacity: .5; font-size: 12px; }

/* The catalogue's button, to the letter: outline by default and filled on
   hover. .btn-main-product only looks like that inside .card-product, and
   there is no card here — so the rule is restated rather than the class being
   borrowed and quietly coming out as a solid black slab. */
/* Written .eu-cmp .eu-cmp-buy, not .eu-cmp-buy: the Polish storefront turns
   off the template's title case with html[lang="pl"] button, which outweighs a
   single class and takes this button's small caps with it. The uppercase here
   is the design's, not the template's, so it needs the extra weight. */
.eu-cmp .eu-cmp-buy {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 38px;
  padding: 6px 12px;
  border: 1px solid var(--text-primary);
  border-radius: var(--ar-radius);
  background-color: transparent;
  color: var(--text-primary);
  font-size: 12px;
  line-height: 20px;
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  transition: all .4s ease;
}

.eu-cmp-buy:hover { background-color: var(--text-primary); color: var(--white); }

.eu-cmp-remove {
  display: inline-block;
  margin-top: 8px;
  font-size: 12px;
  text-decoration: underline;
  color: var(--text-secondary);
}

.eu-cmp-remove:hover { color: var(--critical); }

/* Once the row has stuck it is furniture, not a card: the photograph drops to
   a thumbnail and the row gives the screen back to the specification. The
   class is added by eu-shop.js when a sentinel above the table leaves view. */
.eu-cmp.is-stuck .eu-cmp-head > * { padding-top: 10px; padding-bottom: 10px; }
.eu-cmp.is-stuck .eu-cmp-photo { max-width: 46px; margin-bottom: 8px; }
.eu-cmp.is-stuck .eu-cmp-name { margin-bottom: 4px; }
.eu-cmp.is-stuck .eu-cmp-price { margin-bottom: 0; }
.eu-cmp.is-stuck .eu-cmp-buy,
.eu-cmp.is-stuck .eu-cmp-remove { display: none; }

/* ---- the seven facts ---- */

.eu-cmp-basic .current-price { font-weight: 600; }
.eu-cmp-basic .old-price { text-decoration: line-through; opacity: .5; margin-left: 6px; }
.eu-cmp-stars { display: inline-flex; gap: 2px; margin-right: 6px; }
.eu-cmp-stars .icon { font-size: 12px; }
.eu-cmp-about td { font-size: 12px; line-height: 19px; }

/* ---- the specification sheets ---- */

.eu-cmp-sheet-head > th {
  padding: 0;
  border-bottom: 1px solid var(--line);
  background: var(--surface);
}

.eu-cmp-toggle {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 13px 16px;
  background: none;
  border: 0;
  text-align: left;
  font-size: 14px;
  font-weight: 500;
  color: var(--text-primary);
}

.eu-cmp-sheet-n {
  font-size: 11px;
  line-height: 1;
  padding: 4px 8px;
  border-radius: 999px;
  background: var(--white);
  color: var(--text-secondary);
  border: 1px solid var(--line);
}

/* A chevron drawn from a square, so it needs no icon font and turns cleanly. */
.eu-cmp-caret {
  width: 8px;
  height: 8px;
  margin-left: auto;
  margin-right: 4px;
  border-right: 1.6px solid currentColor;
  border-bottom: 1.6px solid currentColor;
  transform: rotate(45deg);
  transform-origin: 60% 60%;
  transition: transform .25s ease;
  opacity: .6;
}

.eu-cmp-toggle[aria-expanded="true"] .eu-cmp-caret { transform: rotate(-135deg); }
.eu-cmp-sheet.is-closed > tr:not(.eu-cmp-sheet-head) { display: none; }

/* With the differences switch on: rows every product agrees about go, and a
   sheet where nothing at all differs goes with them — heading included, since
   opening it would show an empty list. */
.eu-cmp.is-diff [data-eu-same="1"] { display: none; }
.eu-cmp.is-diff .eu-cmp-sheet[data-eu-nodiff="1"] { display: none; }

/* ---- below the desktop ---- */

@media (max-width: 991px) {
  /* Now the table is wider than the screen, so the wrapper scrolls and the
     label column pins to its left edge. Sticking the product row to the top
     is given up here: a scrolling box is the sticky ancestor, and it has no
     vertical scroll of its own to stick against. */
  /* Flush with the page container, not bled to the screen edge. The bleed was
     margin-inline:-15px with padding to match, and the padding is what broke
     the pinned label: a sticky left:0 comes to rest against the content edge,
     leaving a fifteen-pixel strip beside it where the scrolled-away column
     showed through in slivers. */
  .eu-cmp-scroll {
    overflow-x: auto;
    overscroll-behavior-x: contain;
  }

  /* The label column plus 145 for each product actually being compared. Two
     products and the label come to exactly 390, so the narrowest phone in
     common use shows a pair side by side — which is what a comparison is — and
     145 leaves the buy button room for its own text.

     Counted from the products on the page rather than from the four it can
     hold: with one product the table still reserved four columns, so the one
     column came out four times too wide and its buy button ran off the side of
     the screen (client, 2026-08-29). The fallback of 4 is for a page rendered
     from a cached template that has no counter on it yet. */
  .eu-cmp-table { min-width: calc(100px + var(--ar-cmp-cols, 4) * 145px); }

  /* The product row stops being sticky here, and it has to give up its stacking
     order with it: at z-index 3 the photographs painted over the pinned label
     column instead of sliding under it. */
  .eu-cmp-head > * { position: static; z-index: auto; }

  .eu-cmp-label {
    position: sticky;
    left: 0;
    z-index: 4;
    width: 100px;
    background: var(--white);
    box-shadow: 1px 0 0 var(--line);
  }

  .eu-cmp-table tbody tr:nth-child(even) .eu-cmp-label { background: var(--ar-cmp-zebra); }
  .eu-cmp-sheet-head > th { z-index: auto; }

  /* The product row's label is the one cell that does not pin. Its row is far
     taller than the cell's own box, so a sticky label there covers the bottom
     of the row and leaves the top of the card next to it showing through — and
     the word it holds is "Produkt", which nothing on the row needs explained.
     The specification rows below still pin, which is the pin that matters. */
  .eu-cmp-head .eu-cmp-label { position: static; }

  .eu-cmp-table th,
  .eu-cmp-table td { padding: 10px 12px; font-size: 12px; line-height: 18px; }

  .eu-cmp-photo { max-width: 96px; }
  .eu-cmp-name { font-size: 13px; min-height: 36px; }

  /* Four columns in 640px leaves about a hundred pixels of content per cell.
     The button's desktop letter-spacing and side padding are wider than that
     and pushed "DO KOSZYKA" out through both ends of its own pill. */
  .eu-cmp-buy {
    font-size: 10px;
    letter-spacing: .3px;
    padding: 6px 4px;
    min-height: 34px;
  }

  .eu-cmp-toggle { font-size: 13px; padding: 11px 12px; }

  .eu-cmp-tally { width: 100%; margin-right: 0; }
}

@media (max-width: 575px) {
  /* A swipe that lands on the next product rather than between two.
   *
   * scroll-padding-left is what makes it land in the right place. The snap
   * points are the product columns and "start" means the left edge of the
   * scrolling box — which on this table is under the pinned label column. So
   * the browser snapped to the first product the moment the page opened, came
   * to rest a hundred pixels in, and hid that product behind the very column
   * of labels meant to name its rows: on the client's screen the first
   * product's price, code and brand were blank (2026-08-29).
   *
   * A hundred is the label's own width, set a dozen rules above. Told to keep
   * that much clear, the first column comes to rest at scroll position nought
   * and every column after it stops just past the label rather than under it. */
  .eu-cmp-scroll {
    scroll-snap-type: x proximity;
    scroll-padding-left: 100px;
  }

  .eu-cmp-head .eu-cmp-cell { scroll-snap-align: start; }
}

/* The list pages have no view switcher — search, Promocje, one brand — so
   their grid has to answer the width on its own (client, 2026-08-27). Four
   across is right on a desktop and unreadable on a phone: at 390px it left
   about eighty pixels a card, and a name, a price and a button do not fit in
   eighty pixels. Two across is the width a card was drawn for.

   The catalogue is deliberately not included: it has the switcher, and the
   client asked for three-across to stay available there. */
@media (max-width: 1199.98px) {
  .ar-page .wrapper-shop.tf-col-4 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 767.98px) {
  .ar-page .wrapper-shop.tf-col-4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* The heart on a card, on a phone (client, 2026-08-27).

   The template hides .wishlist and .compare below 576px — its own cards carry
   four marks up that column and it was thinning them out. Ours carry three,
   and one of the three is the wish list, which is the whole reason a shopper
   presses anything in that corner. Our compare button never had the .compare
   class, so it survived the cull and the heart did not — which is why the
   column read as though one icon had failed to load.

   Everywhere at once: the same file draws the cards in the catalogue, on the
   home page, in the search results and on a brand's page. */
@media (max-width: 575px) {
  .card-product .product-action_list .wishlist {
    display: block;
  }
}

/* The corner marks at three across (client, 2026-08-27).

   At three cards to a 390px screen a card is about 110px wide, and 28px
   buttons in the corner of it took a quarter of the picture. They come down
   with everything else on that card — the type, the badge and the button all
   have their own smaller sizes a few hundred lines up in v4.css.

   20px rather than the literal half of 28. Fourteen pixels is a mark, not a
   button: a finger cannot reliably hit it, and the glyph inside would be seven
   pixels tall. Twenty is the smallest these stay both legible and pressable,
   and it reads as half the weight because the gap and the inset come down with
   it. If the size matters more than the tap, say so and it goes to 14.

   Both class names, because two things can put a card in three columns: the
   grid the server sends (tf-col-3) and the one v4-shop.js switches to
   (ar-cols-3). */
@media (max-width: 767px) {
  .tf-grid-layout.tf-col-3 .product-action_list,
  .tf-grid-layout.ar-cols-3 .product-action_list {
    top: 6px;
    inset-inline-end: 6px;
    gap: 5px;
  }

  .tf-grid-layout.tf-col-3 .product-action_list .box-icon,
  .tf-grid-layout.ar-cols-3 .product-action_list .box-icon {
    width: 20px;
    height: 20px;
    border-radius: 4px;
  }

  .tf-grid-layout.tf-col-3 .product-action_list .box-icon .icon,
  .tf-grid-layout.ar-cols-3 .product-action_list .box-icon .icon {
    font-size: 11px;
  }
}

/* ==================================================================== *
 * The one-click order, once it has been taken  (client, 2026-08-27)
 *
 * It covers the panel; it does not replace it. Laid over the form as a sheet
 * of the same size, so the block keeps the height it had and nothing below it
 * moves — which is what the client asked for after the first version, which
 * grew the panel by half again and pushed the rest of the page down.
 *
 * The form underneath goes to visibility:hidden rather than display:none:
 * that keeps its space, which is the whole point, and takes it out of the tab
 * order, which stops anyone reaching a form they have already sent.
 *
 * The tick is drawn rather than set: an icon font would put a glyph there at
 * whatever weight the font happens to have, and this is the moment the block
 * exists for. It draws itself in — half a second, once — which is the
 * difference between a page that answered and a page that was always going to
 * say that.
 * ==================================================================== */

.ar-quick {
  position: relative;
}

/* Still there, still the same size, just not to be read or reached. */
.ar-quick.is-done .ar-quick_title,
.ar-quick.is-done .ar-quick_note,
.ar-quick.is-done .ar-quick_form {
  visibility: hidden;
}

.ar-quick_done {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 20px;
  border-radius: inherit;
  border: 1px solid rgba(22, 163, 74, .3);
  background: linear-gradient(180deg, rgba(233, 248, 238, 1) 0%, rgba(243, 251, 246, 1) 100%);
  animation: ar-quick-cover .25s ease;
}

.ar-quick_done[hidden] {
  display: none;
}

@keyframes ar-quick-cover {
  from { opacity: 0; }
}

.ar-quick_done_mark {
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  color: #16a34a;
}

.ar-quick_done_mark svg {
  width: 100%;
  height: 100%;
  display: block;
}

/* Each line is drawn from nothing to its full length. The dash array is the
   length of the path itself, so the offset can run from "all of it hidden" to
   none of it. */
.ar-quick_done_ring {
  stroke-dasharray: 110;
  stroke-dashoffset: 110;
  animation: ar-quick-ring .45s ease forwards;
}

.ar-quick_done_tick {
  stroke-dasharray: 24;
  stroke-dashoffset: 24;
  /* After the ring has closed, not with it: the mark reads as being made. */
  animation: ar-quick-tick .3s .35s ease forwards;
}

@keyframes ar-quick-ring {
  to { stroke-dashoffset: 0; }
}

@keyframes ar-quick-tick {
  to { stroke-dashoffset: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .ar-quick_done,
  .ar-quick_done_ring,
  .ar-quick_done_tick {
    animation: none;
    stroke-dashoffset: 0;
  }
}

.ar-quick_done_text {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.ar-quick_done_title {
  color: var(--text-primary);
  font-size: 16px;
  line-height: 24px;
  font-weight: 600;
}

.ar-quick_done_note {
  color: var(--text-secondary);
  font-size: 13px;
  line-height: 19px;
}

@media (max-width: 575px) {
  .ar-quick_done {
    gap: 12px;
    padding: 0 14px;
  }

  .ar-quick_done_mark {
    width: 34px;
    height: 34px;
  }

  .ar-quick_done_title {
    font-size: 15px;
    line-height: 22px;
  }
}

/* ==================================================================== *
 * The language and currency menus  (client, 2026-08-27)
 *
 * Two things were wrong with the currency one. It was 150px wide for two
 * three-letter words, and its little arrow was nowhere near the word it
 * belongs to.
 *
 * The arrow is the interesting half. The theme draws it on the MENU, centred
 * on the menu's own width — which happens to work for the languages, because
 * "Polski" makes a 90px button under a 100px menu and the two centres are five
 * pixels apart. Under a 49px "PLN" button the same arrow sits 75px along and
 * points at nothing.
 *
 * So it is drawn on the button instead, where it can be centred on the word
 * itself and stay centred whatever the word is — "PLN", "UAH", "English". Same
 * shape, same white, same place on the seam: the square straddles the line
 * where the menu begins, its lower half swallowed by the menu's own white and
 * its upper half showing as the point. It needs no z-index of its own for
 * that; the menu is above it and does the swallowing.
 * ==================================================================== */

/* ---- the strip itself ---- */

/* 5px instead of the theme's 12. The strip carries one line of small text and
   two menus; twelve above and below made it taller than what it holds, and it
   is the first thing on the page (client, 2026-08-31).

   Written here rather than edited into v4/css/styles.css: that file is the
   theme's own, and every edit in it is lost the next time the theme is
   replaced. This file loads after it, so a plain selector is enough — no
   !important needed for two rules of equal weight. */
.tf-topbar {
  padding-top: 5px;
  padding-bottom: 5px;
}

/* ---- the two menus in the top strip ---- */

/* Sized to what it holds, like the language menu beside it. */
.tf-topbar .tf-dropdown-select.type-currencies > .dropdown-menu {
  min-width: 92px !important;
  width: 92px !important;
}

/* And the language menu widened to what it actually has to hold. The theme
   pins it at 100px, which fitted "Polski" and "English" and cut "Українська"
   in half, with a scrollbar under it (client, 2026-08-27).

   Not scoped to the top strip: the same switch is in the slide-out menu on a
   phone, and that copy had the same scrollbar. */
.tf-dropdown-select.type-languages > .dropdown-menu {
  min-width: 148px !important;
  width: 148px !important;
}

/* And nothing in either menu scrolls sideways. bootstrap-select gives its
   list an inner box that scrolls; with the box a few pixels narrower than the
   longest name it answered by growing a horizontal bar, which is a bar to
   read one word that is already legible. */
.tf-dropdown-select > .dropdown-menu,
.tf-dropdown-select > .dropdown-menu > .inner {
  overflow-x: hidden;
}

/* The menu's own arrow steps aside. */
.tf-topbar .tf-dropdown-select.style-default > .dropdown-menu::after {
  display: none;
}

.tf-topbar .tf-dropdown-select > .dropdown-toggle {
  position: relative;
}

.tf-topbar .tf-dropdown-select > .dropdown-toggle.show::before {
  content: "";
  position: absolute;
  /* The menu is dropped twelve pixels clear of the button, so the square is
     centred twelve pixels below it — on the menu edge rather than in the gap,
     where it read as a floating diamond. Its lower half is then swallowed by
     the menu, which paints above it, and what shows is the point. */
  bottom: -12px;
  left: 50%;
  width: 16px;
  height: 16px;
  transform: translate(-50%, 50%) rotate(45deg);
  background: var(--white);
  /* Between the two things it sits across: above the header at 1030, which
     would otherwise paint its white over the half that shows, and below the
     menu at 1040, which is meant to swallow the other half. The button does
     not make a stacking context, so this number is read against those two. */
  z-index: 1035;
}

/* bootstrap-select marks the button open, not the wrapper — .show lands on
   .dropdown-toggle and on .dropdown-menu, and a rule written against the
   wrapper simply never matches.

   No guard for a menu that flips upward: this strip is the first thing in the
   document, so there is never a shortage of room below it. */

/* ==================================================================== *
 * Choosing a Nova Poshta branch
 *
 * The town is a search, not a select: the carrier has a few thousand of
 * them and no dropdown holds that. The list is the same shape as the live
 * search under the header — a panel hung off the field, scrolling inside
 * itself rather than growing the step it sits in.
 * ==================================================================== */

.ar-np-town {
  position: relative;
}

.ar-np-list {
  position: absolute;
  z-index: 6;
  inset-inline: 0;
  top: calc(100% + 4px);
  max-height: 240px;
  overflow-y: auto;
  margin: 0;
  padding: 4px;
  list-style: none;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
  background: var(--white);
  box-shadow: 0 12px 24px rgba(19, 41, 89, .10);
}

.ar-np-list[hidden] {
  display: none;
}

.ar-np-list li {
  padding: 8px 10px;
  border-radius: var(--ar-radius);
  color: var(--text-primary);
  font-size: 14px;
  line-height: 20px;
  cursor: pointer;
}

.ar-np-list li:hover {
  background: var(--surface);
}

/* ==================================================================== *
 * The kicker on a hero slide  (client, 2026-08-27)
 *
 * It was a line of plain white semibold text the full width of the column,
 * sitting on a photograph — which over a busy picture reads as a caption
 * somebody forgot to style rather than as the line that introduces the
 * headline.
 *
 * Made into what it actually is: an eyebrow. Small, tracked out, in capitals,
 * and set on a frosted plate the width of its own words. The plate is what
 * makes it premium rather than merely small — it lifts the words off whatever
 * happens to be behind them, so the same three words read as cleanly over a
 * bright sky as over the dark side of a drone.
 *
 * The dot is the shop's raspberry: one point of colour in a block that is
 * otherwise white on a photograph, and the only thing on the slide that
 * echoes the accent of the button below it.
 * ==================================================================== */

.sld__tag {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
  padding: 6px 15px 6px 12px;
  border: 1px solid rgba(255, 255, 255, .28);
  border-radius: 999px;
  /* Frosted rather than flat: a solid plate would read as a label stuck on
     the photograph, and this belongs to it. */
  background: rgba(255, 255, 255, .12);
  -webkit-backdrop-filter: blur(10px) saturate(140%);
  backdrop-filter: blur(10px) saturate(140%);
  font-size: 12px;
  line-height: 16px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
}

.sld__tag::before {
  content: "";
  width: 6px;
  height: 6px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--primary);
  /* A ring of its own colour at low opacity, so the dot has a little depth
     against the frost instead of sitting flat on it. */
  box-shadow: 0 0 0 3px rgba(234, 15, 91, .28);
}

/* A browser without backdrop-filter gets a slightly heavier plate rather than
   a transparent one, which would leave the words back on the photograph. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .sld__tag {
    background: rgba(19, 41, 89, .55);
  }
}

@media (max-width: 767px) {
  .sld__tag {
    margin-bottom: 12px;
    padding: 5px 13px 5px 10px;
    font-size: 11px;
    letter-spacing: .12em;
  }
}

/* The service under the carrier's name (client, 2026-08-27). Its own line,
   quieter and a size down: the name is what a shopper looks for and the
   service is what they choose between, so the two should not compete. Set as
   a block inside the title rather than as a sibling, so the two lines stay
   together whatever the row does with its space. */
.ar-co-method_sub {
  display: block;
  margin-top: 2px;
  color: var(--text-secondary);
  font-size: 13px;
  line-height: 18px;
  font-weight: 400;
  letter-spacing: 0;
}

/* The tab strip beside a section heading, on a phone (client, 2026-08-27).

   The capitals are gone from the markup; this takes one more step off the
   size, because on a 390px screen the heading wraps to two lines and the
   strip has three or four names to fit beside it. Fifteen against the
   heading twenty-two is a hierarchy a reader does not have to work out. */
@media (max-width: 767px) {
  .sect-heading .tf-btn-tab {
    font-size: 15px;
    line-height: 22px;
  }
}

/* The captcha, which the port had left unstyled (2026-08-27).

   The markup calls itself a row and in the new design was not one: with no
   rule to match, `.eu-captcha-row` fell back to `display: block`, so the
   picture dropped under the field, and with nothing overriding them the
   `width`/`height` attributes drew a 150×35 image at 80×30 — squashed, and
   too small to read the code off.

   Beside the field, then, and at its own size to the pixel. The generator
   draws exactly 150×35 — see extension/captcha/basic — and this is the one
   picture on the site that must never be resampled: the smudging that makes
   it hard for a machine to read makes it impossible for a person once it has
   been stretched. Padding, not a height, brings the box level with the field
   beside it, and the field's own border and square corners make the two read
   as one control. */
.eu-captcha-row {
  display: flex;
  align-items: center;
  gap: 12px;
}

.eu-captcha-row input {
  flex: 1 1 auto;
  min-width: 0;
}

.eu-captcha-row img {
  flex: 0 0 auto;
  box-sizing: content-box;
  width: 150px;
  height: 35px;
  padding: 7px 10px;
  border: 1px solid var(--line);
  background: var(--white);
}

/* ==================================================================== *
 * Language and currency on a phone  (client, 2026-08-28)
 *
 * Below xl there is no top bar, so both switches had gone into the side
 * menu — three taps away, and a visitor arriving from Ukraine on the Polish
 * storefront never found them. The client pointed at the gap between the
 * logo and the magnifier and asked for them there, "красиво и не наляписто".
 *
 * "Not cluttered" is the constraint and not the wish, so: one control
 * instead of two, a flag with no word beside it, and a currency symbol
 * rather than its three letters. The badge is the smallest thing in that
 * bar, which is right: it is the one control a shopper touches once and
 * then never again.
 * ==================================================================== */

/* Nothing around it. It sits in a row of bare icons, and a pill with a border
   round it read as a control that had wandered in from a form (client,
   2026-08-28). The button is now the same empty cell every other icon in that
   bar sits in. */
.ar-mswitch-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  background: transparent;
}

/* Flag and currency as one mark, the way the basket wears its count and the
   account its tick — in the corner of the thing itself, not beside it. */
.ar-mswitch-mark {
  position: relative;
  display: block;
  width: 26px;
  height: 26px;
}

/* Round. These flags are horizontal bands, so a circle keeps every one of
   them readable; the hairline is what stops a white or yellow band from
   dissolving into the header behind it. */
.ar-mswitch-flag {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  box-shadow: 0 0 0 1px rgba(19, 41, 89, .14);
}

/* The currency, in the top-right corner of the flag.
 *
 * A circle wherever the symbol is one glyph — ₴, € — and a shade wider for
 * "zł", which is two. Forcing that one into a circle would either shrink the
 * letters below reading size or crop them, and a currency mark nobody can
 * read is not a currency mark. min-width plus a pill radius gives a circle
 * when the content allows one and the smallest honest oval when it does not.
 *
 * The white ring is what makes it sit on top rather than in: without it the
 * navy disc merges with a dark band of the flag underneath. */
.ar-mswitch-money {
  position: absolute;
  top: -2px;
  right: -6px;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Eleven pixels, the client's own number. The disc grew with it — at 17 the
     glyph has room to breathe and "zł" still fits without the pill turning
     into a stripe. */
  min-width: 17px;
  height: 17px;
  padding: 0 3px;
  border-radius: 999px;
  background: var(--text-primary);
  box-shadow: 0 0 0 2px var(--white);
  color: var(--white);
  font-size: 11px;
  line-height: 1;
  font-weight: 700;
  letter-spacing: 0;
}

/* No ring round the badge when the sheet closes (client, 2026-08-28).
 *
 * Bootstrap hands focus back to whatever opened an offcanvas, and the browser
 * draws its own square outline on it — a blue box around a round mark, which
 * is what the client saw the moment the sheet slid away.
 *
 * Taken off the mouse and the finger, kept for the keyboard: :focus-visible
 * fires only when the browser judges a ring is wanted, which is exactly the
 * case where removing it would strand somebody tabbing through the header. */
.ar-mswitch-btn:focus {
  outline: none;
  box-shadow: none;
}

.ar-mswitch-btn:focus-visible {
  outline: 2px solid var(--text-primary);
  outline-offset: 3px;
  border-radius: 50%;
}

/* As tall as its contents, so every language and every currency is on screen
   at once (client, 2026-08-28). There are six rows here and there will not
   suddenly be forty; a sheet that has to be scrolled to reach the hryvnia is
   asking a person to hunt for something we could simply have shown them.
 *
 * Written against three class names rather than one because Bootstrap's own
 * `.offcanvas-bottom` sets `height: 30vh`, and at equal specificity whichever
 * stylesheet loads last wins — which is not a thing to leave to load order.
 * That 30vh was the whole bug: the sheet stood at 210px while its contents
 * needed 376.
 *
 * The cap stays, because a shop that adds six more languages should get a
 * scrolling sheet rather than one that runs off the top of the screen. */
.offcanvas.offcanvas-bottom.ar-msheet {
  height: auto;
  max-height: 88vh;
  border-top-left-radius: 18px;
  border-top-right-radius: 18px;
  background: var(--white);
  border-top: 0;
}

/* The bar that says "this can be dragged away", which on a sheet is the
   whole of the affordance. */
.ar-msheet_grip {
  flex: 0 0 auto;
  width: 44px;
  height: 4px;
  margin: 10px auto 2px;
  border-radius: 999px;
  background: var(--line);
}

.ar-msheet_body {
  padding: 8px 16px calc(16px + env(safe-area-inset-bottom));
  overflow-y: auto;
}

.ar-msheet_label {
  margin: 12px 0 6px;
  color: var(--text-secondary);
  font-size: 12px;
  line-height: 16px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
}

/* The real controls. Off screen rather than display:none — a select that is
   not laid out cannot be reached by the browser's own validation, and this
   one is the thing the switch actually fires from. */
.ar-msheet_carrier {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.ar-msheet_list {
  display: grid;
  gap: 2px;
}

.ar-msheet_row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 12px;
  border: 0;
  border-radius: var(--ar-radius);
  background: transparent;
  color: var(--text-primary);
  font: inherit;
  font-size: 16px;
  line-height: 22px;
  text-align: start;
  transition: background-color .2s ease;
}

.ar-msheet_row:active {
  background: var(--surface);
}

.ar-msheet_row.is-on {
  background: var(--surface);
  font-weight: 600;
}

.ar-msheet_flag {
  flex: 0 0 auto;
  width: 24px;
  height: 18px;
  object-fit: cover;
  border-radius: 3px;
  box-shadow: 0 0 0 1px rgba(19, 41, 89, .12);
}

/* Where the flag is on the language rows, so the two lists line up down one
   edge. A currency has no country to show a flag for — the euro least of
   all. */
.ar-msheet_sign {
  flex: 0 0 auto;
  width: 24px;
  color: var(--text-secondary);
  font-size: 16px;
  line-height: 22px;
  font-weight: 600;
  text-align: center;
}

.ar-msheet_name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Only on the one in force. Kept in the layout when it is not, so no row
   shifts sideways as the tick comes and goes. */
.ar-msheet_tick {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  color: var(--primary);
  opacity: 0;
}

.ar-msheet_row.is-on .ar-msheet_tick {
  opacity: 1;
}

.ar-msheet_tick svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* ==================================================================== *
 * Account, favourites and comparison in the slide-out menu
 * (client, 2026-08-28)
 *
 * The panel above them is a list of places in the shop; these are three
 * more, so they are rows and not a strip of icons. What separates them from
 * the navigation is a hairline and a little air, not a different shape —
 * the client asked for it "в стиле сайта", and the site's style here is a
 * quiet list.
 * ==================================================================== */

.ar-mb-mine {
  display: grid;
  gap: 2px;
  margin: 4px 0 24px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}

.ar-mb-mine_row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 10px;
  border-radius: var(--ar-radius);
  color: var(--text-primary);
  font-size: 16px;
  line-height: 22px;
  transition: background-color .2s ease, color .2s ease;
}

.ar-mb-mine_row:hover,
.ar-mb-mine_row:active {
  background: var(--surface);
  color: var(--text-primary);
}

.ar-mb-mine_row .icon {
  flex: 0 0 auto;
  width: 22px;
  font-size: 20px;
  line-height: 1;
  color: var(--text-secondary);
  text-align: center;
}

.ar-mb-mine_name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The count, and only when there is one. A grey pill rather than the red of
   the basket badge: the basket's number is a thing to act on, these two are
   a thing to know. */
.ar-mb-mine_count {
  flex: 0 0 auto;
  min-width: 22px;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--surface);
  color: var(--text-secondary);
  font-size: 12px;
  line-height: 18px;
  font-weight: 600;
  text-align: center;
}

.ar-mb-mine_count[hidden] {
  display: none;
}

/* Signed in, said the same way the header says it. */
/* Signed in. A bare raspberry tick at the end of the row read as a piece of
   punctuation rather than as a state — and in the shop's own accent colour,
   which everywhere else means "press this" (client, 2026-08-29). A filled
   green disc says it in the language every interface uses for "done", and it
   is the same mark the account icon in the bottom bar wears. */
.ar-mb-mine_tick {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #16a34a;
  color: #fff;
}

.ar-mb-mine_tick svg {
  width: 13px;
  height: 13px;
}

/* And the heart leaves the header on a phone (client, 2026-08-28). It was the
   last of the three still there, standing for a group whose other two the
   theme had already hidden — which reads as something forgotten rather than
   something decided. All three are in the menu now. */
@media (max-width: 1199.98px) {
  .nav-icon-list > li.ssm-d-none,
  .nav-icon-list > li.ssm-d-none + li.br-line {
    display: none !important;
  }
}

/* Sixteen pixels on a touch screen, and not a fraction less (client,
   2026-08-28).

   Safari on iOS zooms the whole page in when a field it is about to focus is
   set below sixteen pixels — it decides the text is too small to type into and
   helpfully magnifies. On a fixed header with a list open underneath, that
   reads as the page jumping away from the finger.

   Not a bug to work around with `maximum-scale`, which would also take pinch
   zoom away from everybody who needs it. The cure is the size itself, and only
   where a touch screen is what is being used: on a mouse the design keeps its
   fifteen. */
@media (pointer: coarse) {
  .eu-select-find_input {
    font-size: 16px;
    line-height: 22px;
  }

  /* Swept up with it: the same undersized field, the same zoom, and nobody
     would have called the quantity stepper a search box in the report. Only
     the size changes — its own line-height is what keeps the stepper's two
     arrows level with the number between them. */
  .quantity-product input,
  input.quantity-product {
    font-size: 16px;
  }
}

/* The burger, four pixels bigger (client, 2026-08-28). It is the first thing
   a thumb reaches for on a phone and it was the smallest mark in the bar —
   24px against the 26 of the flag beside it and the 24 of icons that carry a
   badge to make them read larger. Set here rather than by swapping the fs-24
   class in the markup: fs-28 does not exist in the theme, and inventing a
   utility class for one element is how a stylesheet grows a vocabulary nobody
   remembers. */
.box-btn-open-menu .icon-OpenMenu {
  font-size: 28px;
}

/* ==================================================================== *
 * The toast, tightened  (client, 2026-08-28)
 *
 * "Компактный но премиальный при этом скромный." The panel was 125 pixels
 * tall because the link sat on a line of its own, dressed as a button —
 * which made a notification look like a decision to be taken. It is not:
 * the basket has been added to, the shopper knows where the basket is, and
 * the link is there for the one time in ten they want to go straight there.
 *
 * So the link joins the line under the name, as a link. The panel loses a
 * row and about forty pixels, and what is left is a photograph, two lines
 * and a quiet way onward — which is the whole of what happened.
 * ==================================================================== */

.ar-toast__link {
  margin-top: 6px;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  font-size: 12px;
  letter-spacing: .04em;
  /* Underlined rather than boxed: at this size a border reads as a button and
     a button asks to be pressed. The offset keeps the rule off the letters'
     descenders. */
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(19, 41, 89, .35);
}

.ar-toast__link:hover,
.ar-toast__link:focus-visible {
  background: none;
  border-color: transparent;
  color: var(--text-primary, #132959);
  text-decoration-color: currentColor;
}

/* ==================================================================== *
 * The bar offering a visitor their own language  (client, 2026-08-28)
 *
 * Above everything and in the flow, pushing the page down rather than
 * covering it: a strip laid over a fixed header is how a shop loses the
 * first thing somebody came to read.
 *
 * Quiet on purpose. It is a suggestion to a person who has not asked for
 * one, and the two things it must do are be noticed once and then get out
 * of the way. Anything louder — a colour, a modal, an animation — turns a
 * courtesy into an interruption.
 * ==================================================================== */

.ar-geo {
  position: relative;
  z-index: 1040;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}

.ar-geo_row {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  padding-top: 8px;
  padding-bottom: 8px;
}

.ar-geo_line {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--text-primary);
  font-size: 14px;
  line-height: 20px;
}

/* The offer itself. Underlined rather than boxed — see the toast: at this
   size a border reads as a button, and a button asks to be pressed. */
.ar-geo_go {
  flex: 0 0 auto;
  color: var(--text-primary);
  font-size: 14px;
  line-height: 20px;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: rgba(19, 41, 89, .35);
  transition: text-decoration-color .2s ease;
}

.ar-geo_go:hover {
  color: var(--text-primary);
  text-decoration-color: currentColor;
}

.ar-geo_close {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--text-secondary);
  transition: background-color .2s ease, color .2s ease;
}

.ar-geo_close:hover {
  background: var(--white);
  color: var(--text-primary);
}

.ar-geo_close svg {
  width: 14px;
  height: 14px;
}

/* On a phone the sentence takes its own line and the two controls sit under
   it — three things across 390 pixels would each be too small to hit. */
@media (max-width: 575.98px) {
  .ar-geo_row {
    flex-wrap: wrap;
    gap: 4px 12px;
  }

  .ar-geo_line {
    flex: 1 0 100%;
  }

  .ar-geo_go {
    flex: 1 1 auto;
  }
}

/* The globe. Its own strokes, no icon font: three shapes that inherit the
   colour of the words beside them, so it can never be a black square while a
   font is still loading. Muted a shade below the text — it says which kind of
   message this is and then gets out of the way. */
.ar-geo_mark {
  flex: 0 0 auto;
  display: flex;
  width: 20px;
  height: 20px;
  color: var(--text-secondary);
}

.ar-geo_mark svg {
  width: 100%;
  height: 100%;
}

/* The bar on a phone: fixed above the header, two lines, one mark (client,
   2026-08-28).
 *
 * Below xl the header is `position: fixed; top: 0`, and the bar was sitting in
 * the flow at the very same place with a higher z-index — so it covered the
 * header completely. It is fixed here too, stacked above, and the header and
 * its spacer step down by exactly its height.
 *
 * The sentence was cut out of that first fix to save room, and the client
 * asked for it back — rightly: "Перейти на українську" alone says what to
 * press, not why it is being offered. So the two lines stand in a column
 * beside the globe, which spans them, and the close button sits opposite. It
 * is the shape of a notification because that is what it is.
 *
 * The height is one number, `--ar-geo-h`, read three times: the bar's own
 * height, how far the header steps down, and how much taller the spacer
 * becomes. The first version had 52 in two of those and 41 in reality, which
 * left an eleven-pixel band of page showing between the bar and the header. */
@media (max-width: 1199.98px) {
  /* Declared where everything below can read it.

     It stood on .ar-geo, and the rules that step the header, its spacer and
     the pinned blocks down are not inside the bar — a custom property
     inherits downwards, not sideways, so every one of them was quietly
     falling back to the 62 written after the comma. The number came out the
     same; it simply was not one number in one place, which is what this note
     says it is. On the root it is. */
  :root {
    --ar-geo-h: 62px;
  }

  .ar-geo {
    height: var(--ar-geo-h);
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1041;
  }

  /* A grid rather than a flex row: the globe has to stand beside both lines
     rather than beside the first one, and one column that spans two rows says
     that in a way no arrangement of flex boxes does. */
  .ar-geo_row {
    display: grid;
    grid-template-columns: 20px 1fr 28px;
    grid-template-rows: auto auto;
    align-items: center;
    gap: 1px 10px;
    min-height: 0;
    padding-top: 8px;
    padding-bottom: 8px;
  }

  .ar-geo_mark {
    grid-column: 1;
    grid-row: 1 / span 2;
  }

  .ar-geo_line {
    grid-column: 2;
    grid-row: 1;
    font-size: 13px;
    line-height: 18px;
    color: var(--text-secondary);
  }

  .ar-geo_go {
    grid-column: 2;
    grid-row: 2;
    justify-self: start;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* Opposite the pair, not opposite one of them. */
  .ar-geo_close {
    grid-column: 3;
    grid-row: 1 / span 2;
  }

  /* And the header steps down by exactly the height of the bar above it. */
  .ar-geo ~ header.tf-header,
  .ar-geo ~ #wrapper header.tf-header {
    top: var(--ar-geo-h, 62px) !important;
  }

  .ar-geo ~ .ar-head-spacer,
  .ar-geo ~ #wrapper .ar-head-spacer {
    height: calc(var(--ar-head-h, 60px) + var(--ar-geo-h, 62px)) !important;
  }

  /* And so does everything pinned under the header.
   *
   * The theme sets these offsets itself — headerFix() in v4/js/main.js, on a
   * quarter-second timer — as the header's own height and nothing else. With
   * the bar standing above the header that lands the catalogue's sort and
   * filter strip at 60px, and the header now starts at 62. The strip is 54px
   * tall, so it went behind the header completely and stayed there: measured
   * on a 390px screen, header 62..122, strip 60..114.
   *
   * That is what the client photographed in Telegram's browser (2026-08-30),
   * and it is not Telegram's doing — that browser keeps its own cookies, so
   * the bar had never been dismissed there. In Safari, where it had been, the
   * same page is correct. Dismissing the bar removes the element, so these
   * rules stop matching in the same breath.
   *
   * eu-v4.js works the number out correctly and writes it, but it writes it
   * inline and so does the theme, and the theme writes last. Stated here
   * instead: a stylesheet declaration marked important outranks any inline
   * style, so the offset is settled before either script has an opinion.
   *
   * The 15px is the theme's own gap for a pinned block; `no-offset` is its
   * mark for the ones that sit flush, and the strip carries it. */
  .ar-geo ~ .sticky-top,
  .ar-geo ~ * .sticky-top {
    top: calc(var(--ar-head-h, 60px) + var(--ar-geo-h, 62px) + 15px) !important;
  }

  .ar-geo ~ .sticky-top.no-offset,
  .ar-geo ~ * .sticky-top.no-offset {
    top: calc(var(--ar-head-h, 60px) + var(--ar-geo-h, 62px)) !important;
  }
}

/* ------------------------------------------------------------------ *
 * The comparison, tidied (client, 2026-08-29)
 *
 * Two things: it is on the design's own colours now rather than on a handful
 * of greys typed in while it was being built, and the sheet headings stay
 * where they can be read on a phone.
 * ------------------------------------------------------------------ */

:root {
  /* The alternating row. Between white and --surface and carrying the same
     bias toward the brand navy, so the table's own banding belongs to the
     palette rather than being a neutral grey laid over it. Opaque on purpose:
     the label column is pinned and the product columns slide underneath it, so
     a translucent stripe would let a specification read straight through the
     label sitting on top of it. */
  --ar-cmp-zebra: #f8f9fb;
}

.eu-cmp-sheet-pin {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

@media (max-width: 991px) {
  /* A sheet heading is one cell spanning every column, so the cell is as wide
     as the whole table and its words went off the left edge with it — the
     client's screen showed "…racteristics" and "…elektryczne" where the names
     should have been. The words are pinned to the near edge and the chevron to
     the far one; the cell's own background travels the full width, so there is
     always something opaque behind both. */
  .eu-cmp-sheet-pin {
    position: sticky;
    left: 12px;
  }

  .eu-cmp-caret {
    position: sticky;
    right: 12px;
  }
}

/* The two radios on the newsletter page — the only place in the account where
   a choice is made between two named answers rather than by ticking a box.
   Laid out as rows so the label is part of the target, not a word beside it. */
.ar-ac-choice {
  display: grid;
  gap: 10px;
  margin-top: 6px;
}

.ar-ac-radio {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--ar-radius);
  cursor: pointer;
  transition: border-color .2s ease;
}

.ar-ac-radio:hover,
.ar-ac-radio:has(input:checked) {
  border-color: var(--text-primary);
}

.ar-ac-radio input {
  accent-color: var(--text-primary);
  width: 18px;
  height: 18px;
  flex: none;
}

/* ====================================================================
 * The gallery, when Swiper's own stylesheet does not arrive
 *
 * The client photographed a product page in Telegram's browser with no
 * thumbnails and every photograph full width, one under another, down the
 * whole page (2026-08-30). That shape has exactly one cause, and it was
 * reproduced by hand: switch swiper-bundle.min.css off and the gallery goes
 * from a 473px box to a 1415px ribbon. Switching only the script off does
 * not do it — the box stays a box — so the script had run and the
 * stylesheet had not.
 *
 * Which is odd for one file among twelve, and why it did not arrive was not
 * established: it is served correctly (200, text/css, 18KB, over HTTP/3),
 * and this file did arrive in the same page load — the bar above the header
 * was in its fixed position, which only these rules give it.
 *
 * So rather than explain it, survive it. Three declarations, copied from
 * Swiper 11.0.5 with the same values, which is why they change nothing at
 * all while the vendor file is there: the slide row is a row, the frame
 * clips it, and a slide holds its width instead of collapsing. When Swiper's
 * script runs it writes its own widths inline and those still win, so the
 * thumbnails keep their six-and-a-bit to a screen.
 *
 * The gallery is the product page. It is worth three rules not to have it
 * depend on one request landing.
 * ==================================================================== */
.swiper {
  position: relative;
  overflow: hidden;
}

.swiper-wrapper {
  display: flex;
  box-sizing: content-box;
}

.swiper-slide {
  position: relative;
  flex-shrink: 0;
  width: 100%;
}

/* ====================================================================
 * Режим списка: кнопки карточки к ближнему краю (клиент, 2026-08-30)
 *
 * In the grid they hold the top-right corner of the photograph, where they
 * belong — nothing else is there. Turned into a list the theme keeps them
 * pinned right, and the photograph is now a narrow column on the left: that
 * corner is the middle of the card, a finger's width from the name and the
 * price, so they read as belonging to the wording rather than to the picture.
 * Measured on a 390px screen: the photograph runs 27..190, the buttons stand
 * at 154..190 — right against the text.
 *
 * Moved to the leading edge, the only free corner of the picture in a list.
 * Nothing is displaced: this card carries no sale flash and no badge over the
 * image, the stock label lives in the text column.
 *
 * No !important: the theme's own rule is the same weight and this file is
 * read after it.
 * ==================================================================== */
.product-style_list .product-action_list {
  left: 0;
  right: auto;
}

/* ====================================================================
 * Переключатель светлой и тёмной версии (клиент, 2026-08-31)
 *
 * Живёт в обеих версиях, поэтому правила здесь, а не в eu-dark.css: в
 * светлой он показывает месяц и обещает тёмную, в тёмной — солнце и
 * обещает светлую. Значок называет то, что произойдёт, а не то, что сейчас
 * на экране: кнопка обещает действие.
 *
 * На широких экранах стоит в верхней полосе рядом с языком и валютой, на
 * узких — строкой в мобильном меню. Полоса на телефоне спрятана целиком, и
 * значок в ней был бы недоступен.
 * ==================================================================== */
.ar-theme {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex: none;
  /* Полоса тёмная и в светлой версии — отсюда «белый». В тёмной эта
     переменная перевёрнута, и значок чинится сгенерированным разделом
     eu-dark.css наравне со всем остальным белым текстом. */
  color: var(--white);
  opacity: .7;
  transition: opacity .2s ease;
}

.ar-theme:hover,
.ar-theme:focus-visible {
  color: var(--white);
  opacity: 1;
}

.ar-theme_ic {
  width: 18px;
  height: 18px;
  display: block;
}

/* В меню значок встаёт на место иконочного и потому повторяет его размер. */
.ar-mb-mine_ic {
  color: var(--text-secondary);
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
}

/* ====================================================================
 * Наведение на товар — цветом, а не подчёркиванием (клиент, 2026-08-31)
 *
 * Тема помечает название карточки классом `link-underline`: подчёркивание
 * нарисовано всегда, а до наведения ему просто выставлен прозрачный цвет.
 *
 * Вместо линии — малиновый `--primary`, тот же, которым подсвечен выбранный
 * таб над полками. Новый цвет заводить незачем: на витрине уже есть цвет со
 * значением «вот это сейчас в фокусе», и название под курсором — ровно оно.
 *
 * Отзывается вся карточка, а не только надпись: наводят на товар, а не на
 * строку из двадцати букв. Подчёркивание гасится в обоих случаях — иначе при
 * наведении точно на буквы оно возвращалось бы поверх нового цвета.
 *
 * Сначала было сделано только для тёмной версии, где линия под светлым
 * текстом заметнее и грубее; клиент попросил и в светлую, и это правильно —
 * поведение одного и того же элемента не должно зависеть от того, какого
 * цвета вокруг него страница.
 * ==================================================================== */
.card-product:hover .name-product,
.card-product .name-product:hover {
  /* С важностью, и это не небрежность: цвет названию задаёт утилита темы
     .cl-text-main, у которой !important стоит в самой теме. Правило без
     важности проигрывает ей при любой специфичности — ховера просто не было
     ни в тёмной версии, ни в светлой (клиент, 2026-08-31). Та же ловушка,
     что раньше увела в белое полосу над шапкой. */
  color: var(--primary) !important;
  text-decoration-color: transparent;
}


/* ====================================================================
 * A section that is not open yet
 *
 * A category taken off the shelf for a while answers with a page, not with
 * "not found": the shop is being prepared, not broken. The page says so in
 * three lines and offers the only thing that is real right now — a
 * conversation (client, 2026-08-31).
 * ==================================================================== */

.eu-soon {
  max-width: 620px;
  padding: 8px 0 8px;
}

/* The word carries the whole message, so it is set like a label rather than
   like a heading: small, spaced, in the accent — the eye reads it before the
   sentence under it. */
.eu-soon_badge {
  display: inline-block;
  margin: 0 0 14px;
  padding: 5px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--primary);
}

.eu-soon_lead {
  margin: 0 0 10px;
  font-size: 20px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--text-primary);
}

.eu-soon p {
  color: var(--text-secondary);
}

.eu-soon .tf-btn {
  margin-top: 18px;
}

/* The document column is centred and narrowed for a long legal text, which is
   right for one and wrong for three lines: the block ended up indented from
   its own heading. Undone only where this block is, so nothing else moves. */
.ar-page .row:has(.eu-soon) > [class*="col-"] {
  flex: 0 0 100%;
  max-width: 100%;
  margin-left: 0;
}

/* .ar-doc underlines links, because in a legal text a link is a reference.
   A button is not a reference. */
.eu-soon .tf-btn,
.eu-soon .tf-btn span {
  text-decoration: none;
}


/* ====================================================================
 * The wide banner's button, kept at its own height
 *
 * .bn-content is a flex column inside a banner of fixed height. A headline
 * one line longer than the mock-up's overflows it, and the button — the only
 * child that can give — is squeezed from 50px to 26 and stops looking like a
 * button at all (client, 2026-08-31).
 *
 * The headline was shortened back to two lines, but a third language is one
 * long word away from doing it again: Ukrainian and English say the same thing
 * in different widths, and nobody will remember this rule when they translate.
 * flex: none takes the button out of the argument for good.
 * ==================================================================== */

.banner-v01 .bn-content .tf-btn {
  flex: none;
}
