@import url("../fonts/plex/plex.css");

/* ==========================================================================
   Rafeindir og Tæki
   --------------------------------------------------------------------------
   The product line is a set of devices that report a state: a sensor trips, a
   temperature crosses a threshold, the power comes back on. The visual system
   leans on that — instrument type for anything numeric, the brand orange used
   as an indicator rather than as decoration, and warm neutrals so the varied
   product photography (some shot on white, some on black) can sit together.
   ========================================================================== */

:root {
  --ground: #ffffff;
  --band: #f6f4f1;          /* warm off-white: section bands and image tiles */
  --ink: #221e1a;           /* warm charcoal */
  --ink-soft: #5c554c;
  --ink-faint: #8a8175;
  --rule: #e4dfd8;
  --brand: #f58c0c;         /* the logo orange — fills, indicators, buttons */
  --brand-deep: #a85304;    /* the same orange as text on light, contrast-safe */
  --brand-wash: #fdf1e2;
  --night: #221e1a;
  --night-text: #cfc7bc;
  --night-faint: #a49a8c;   /* muted on night: labels and legal, still AA */

  --display: "IBM Plex Sans Condensed", "IBM Plex Sans", system-ui, sans-serif;
  --body: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --readout: "IBM Plex Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;

  --step: clamp(3rem, 6vw, 5.5rem);   /* vertical rhythm between bands */
  --nav-gap: 15px;                    /* horizontal padding on a main-menu link */
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */

body {
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.65;
  color: var(--ink);
  background: var(--ground);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6,
.sppb-addon-title {
  font-family: var(--display);
  font-weight: 700;
  letter-spacing: -0.012em;
  line-height: 1.1;
  color: var(--ink);
  text-wrap: balance;
}

h1 { font-size: clamp(2.1rem, 5vw, 3.25rem); }
h2 { font-size: clamp(1.7rem, 3.6vw, 2.4rem); }
h3 { font-size: clamp(1.3rem, 2.4vw, 1.6rem); }

p { max-width: 68ch; }

a { color: var(--brand-deep); text-underline-offset: 2px; }
a:hover, a:focus { color: var(--brand); }

:focus-visible {
  outline: 2px solid var(--brand-deep);
  outline-offset: 2px;
  border-radius: 2px;
}

/* An eyebrow above a heading names the section; it is a label, not ornament. */
.rt-eyebrow {
  display: block;
  font-family: var(--readout);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--brand-deep);
  margin-bottom: 0.65rem;
}

.rt-lede {
  font-size: 1.12rem;
  color: var(--ink-soft);
  max-width: 60ch;
}

/* Releases a lede from the reading measure so it spans its container. Used
   where the 60ch limit fights the layout rather than helping it: a one-line
   intro that 60ch would wrap for no reason, or a lede sitting above full-width
   content, where the short measure reads as a mistake rather than a choice. */
.rt-lede--full { max-width: none; }

/* --------------------------------------------------------------------------
   Header and navigation
   -------------------------------------------------------------------------- */

/* Helix ships 100px of dead space above and below the main body; the page's own
   sections carry their spacing, so it only needs enough to breathe. */
#sp-main-body { padding-block: clamp(2rem, 5vw, 3.5rem) clamp(3rem, 7vw, 5rem); }

/* The home page opens on the hero and closes on the contact band, both of which
   want to meet the header and footer directly, so it keeps no padding at all. */
.rt-page-home #sp-main-body { padding-block: 0; }

#sp-header {
  border-bottom: 1px solid var(--rule);
  box-shadow: none;
}

#sp-header.header-sticky {
  box-shadow: 0 1px 16px -8px rgba(34, 30, 26, 0.35);
}

/* The bar runs in the body face rather than the condensed display face: the
 * condensed family is only loaded at 600 and 700, and two weights that close
 * together cannot separate the current page from its neighbours. Plex Sans
 * carries 500 and 600, so the resting items sit at a weight that reads as quiet
 * and 600 is left to mean "you are here". Uppercase at 500 needs the wider
 * tracking to hold together. It also keeps the condensed face to the logo and
 * the headings, so the nav stops competing with the lockup beside it.
 *
 * Every rule here is qualified with #sp-header because the template stylesheet
 * targets `.sp-megamenu-parent > li > a` at exactly this specificity and lands
 * later in the cascade: it sets the active item to font-weight 500, lighter than
 * the 600 around it, and it strips the right padding off the last link. The
 * qualifier wins the weights and the padding back.
 *
 * Helix will also emit an inline font-family for this same selector if the
 * template style's Typography → Navigation option is switched on. That option is
 * off, which is where it belongs — the type is set here — but the qualifier
 * keeps this file authoritative if anyone turns it back on. */
#sp-header .sp-megamenu-parent > li > a,
#sp-header .sp-megamenu-parent > li > span {
  position: relative;
  padding-inline: var(--nav-gap);
  font-family: var(--body);
  font-weight: 500;
  font-size: 0.95rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
  transition: color 0.16s ease;
}

/* Three states, and only the third spends the orange: resting items are muted,
 * hover darkens the word and previews the rule in a neutral, and the current
 * page takes the weight and the indicator colour. Keeping hover off the orange
 * means the colour still marks one thing on the page rather than wherever the
 * pointer happens to rest. */
#sp-header .sp-megamenu-parent > li > a:hover { color: var(--ink); }

#sp-header .sp-megamenu-parent > li.active > a,
#sp-header .sp-megamenu-parent > li.current-item > a {
  font-weight: 600;
  color: var(--brand-deep);
}

/* The marker hangs off ::before because Helix draws the submenu caret in ::after
 * on these same links, at a specificity this file does not outrank — an item
 * with children would otherwise render its caret squashed into a 2px box.
 *
 * The link's line-height is the full header height, so a block-level marker
 * would sit below the whole line box — around 39px under the text. Anchoring it
 * to the vertical centre instead keeps it a fixed distance under the words, and
 * expressing that distance in em means it follows the font size. */
#sp-header .sp-megamenu-parent > li > a::before {
  content: "";
  position: absolute;
  left: var(--nav-gap);
  right: var(--nav-gap);
  top: 50%;
  transform: translateY(0.95em);
  height: 2px;
  background: var(--ink-faint);
  opacity: 0;
  transition: opacity 0.16s ease;
}

#sp-header .sp-megamenu-parent > li > a:hover::before { opacity: 1; }

#sp-header .sp-megamenu-parent > li.active > a::before,
#sp-header .sp-megamenu-parent > li.current-item > a::before {
  background: var(--brand);
  opacity: 1;
}

/* Helix tightens the links to 10px below 1200px and strips the right padding off
 * the last one entirely. Both are overridden above, so the narrowing is done on
 * the variable instead — that way the indicator inset stays in step with the
 * padding it is matching. */
@media (max-width: 1199px) {
  :root { --nav-gap: 11px; }
}

#offcanvas-toggler > .fa,
#offcanvas-toggler > .far,
#offcanvas-toggler > .fas { color: var(--ink); }

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.rt-btn,
.sppb-btn-primary,
.btn-primary {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 0.8rem 1.5rem;
  border: 0;
  border-radius: 2px;
  background: var(--brand);
  color: #ffffff;
  text-decoration: none;
  transition: background 0.16s ease;
}

.rt-btn:hover,
.rt-btn:focus,
.sppb-btn-primary:hover,
.btn-primary:hover {
  background: var(--brand-deep);
  color: #ffffff;
}

.rt-btn--ghost {
  background: transparent;
  color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--rule);
}

.rt-btn--ghost:hover,
.rt-btn--ghost:focus {
  background: var(--band);
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   The price readout — the one loud element on the site.
   Every product page and every card carries the same object, because the price
   is what visitors came for and what the company's own copy leads with.
   -------------------------------------------------------------------------- */

.rt-price {
  display: inline-flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.7rem 1rem 0.75rem;
  background: var(--brand-wash);
  border-left: 3px solid var(--brand);
  border-radius: 0 3px 3px 0;
}

.rt-price__label {
  font-family: var(--readout);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--brand-deep);
}

.rt-price__value {
  font-family: var(--readout);
  font-weight: 600;
  font-size: 1.55rem;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.rt-price__unit {
  font-size: 0.78em;
  color: var(--ink-soft);
  margin-left: 0.25rem;
}

.rt-price__note {
  font-family: var(--body);
  font-size: 0.82rem;
  color: var(--ink-soft);
}

/* --------------------------------------------------------------------------
   Spec lists — the bulleted capability lists that every product carries.
   The marker is an indicator dot, echoing the LEDs on the hardware.
   -------------------------------------------------------------------------- */

.rt-specs {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.55rem;
  max-width: 62ch;
}

.rt-specs > li {
  position: relative;
  padding-left: 1.5rem;
  line-height: 1.55;
}

.rt-specs > li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--brand);
}

/* --------------------------------------------------------------------------
   Product detail layout
   -------------------------------------------------------------------------- */

.rt-product {
  display: grid;
  gap: clamp(1.75rem, 4vw, 3rem);
  align-items: start;
}

@media (min-width: 900px) {
  .rt-product { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

.rt-product__media {
  display: grid;
  gap: 0.75rem;
}

.rt-product__media--multi {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* A fixed tile with contained images lets photos shot on white and photos shot
   on black sit in the same grid without one of them looking broken. */
.rt-shot {
  display: block;
  background: var(--band);
  border: 1px solid var(--rule);
  border-radius: 3px;
  aspect-ratio: 4 / 3;
  overflow: hidden;
}

.rt-shot img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.rt-product__media--multi .rt-shot:first-child {
  grid-column: 1 / -1;
  aspect-ratio: 16 / 9;
}

.rt-product__detail { display: grid; gap: 1.4rem; }

.rt-product__intro {
  font-size: 1.1rem;
  color: var(--ink-soft);
  margin: 0;
}

/* The intro's margin is zeroed so a card can space it with flex gap. On a
   product page the intro and the product block are adjacent siblings instead,
   with nothing between them — so the gap is set on that pairing only, and the
   card listing is left alone. */
.rt-product__intro + .rt-product { margin-top: clamp(1.75rem, 3.5vw, 2.75rem); }

/* --------------------------------------------------------------------------
   Product cards (SP Page Builder Articles addon, and any hand-built grid)
   -------------------------------------------------------------------------- */

.rt-grid {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 290px), 1fr));
}

.rt-card,
.sppb-addon-articles .sppb-addon-article {
  display: flex;
  flex-direction: column;
  background: var(--ground);
  border: 1px solid var(--rule);
  border-radius: 4px;
  overflow: hidden;
  transition: border-color 0.16s ease, box-shadow 0.16s ease, transform 0.16s ease;
}

.rt-card:hover,
.sppb-addon-articles .sppb-addon-article:hover {
  border-color: var(--brand);
  box-shadow: 0 14px 30px -22px rgba(34, 30, 26, 0.55);
  transform: translateY(-2px);
}

.rt-card__tile {
  display: block;
  background: var(--band);
  border-bottom: 1px solid var(--rule);
  aspect-ratio: 4 / 3;
  overflow: hidden;
}

.rt-card__tile img,
.sppb-addon-articles .sppb-article-img-wrap img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.sppb-addon-articles .sppb-article-img-wrap {
  background: var(--band);
  aspect-ratio: 4 / 3;
  overflow: hidden;
}

.rt-card__body {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  padding: 1.15rem 1.25rem 1.35rem;
  flex: 1;
}

.rt-card__title {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.22rem;
  line-height: 1.15;
  margin: 0;
}

.rt-card__title a { color: var(--ink); text-decoration: none; }
.rt-card__title a:hover { color: var(--brand-deep); }

.rt-card__intro {
  margin: 0;
  font-size: 0.95rem;
  color: var(--ink-soft);
  flex: 1;
}

/* A range price such as "28.900–35.900 kr." plus the link is wider than the
   narrowest card in the grid, so the pair wraps rather than colliding. */
.rt-card__foot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.35rem 1rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--rule);
}

.rt-card__price {
  font-family: var(--readout);
  font-weight: 600;
  font-size: 1.05rem;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.rt-card__more {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.82rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brand-deep);
  text-decoration: none;
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   Section bands
   -------------------------------------------------------------------------- */

.rt-band { background: var(--band); }

.rt-section { padding-block: var(--step); }

.rt-section__head {
  max-width: 62ch;
  margin-bottom: clamp(1.75rem, 3vw, 2.75rem);
}

/* --------------------------------------------------------------------------
   Contact block
   -------------------------------------------------------------------------- */

.rt-contact {
  display: grid;
  gap: 0.55rem;
  font-style: normal;
}

.rt-contact__line {
  display: flex;
  align-items: baseline;
  gap: 0.7rem;
}

/* The key is a fixed-width gutter. Without flex-shrink:0 a long label such as
   HEIMILISFANG is squeezed to the min-width and its text spills over the value
   beside it — which is exactly what happens in the narrow footer columns. */
.rt-contact__key {
  font-family: var(--readout);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  min-width: 5.5rem;
  flex-shrink: 0;
}

.rt-contact__val { font-size: 1.02rem; }

.rt-contact__val--tel {
  font-family: var(--readout);
  font-weight: 600;
  font-size: 1.2rem;
  letter-spacing: 0.02em;
}

/* --------------------------------------------------------------------------
   Joomla article rendering
   -------------------------------------------------------------------------- */

.article-details .article-header h1,
.article-details .article-header h2 { margin-bottom: 1.25rem; }

.article-details .article-body img { max-width: 100%; height: auto; }

.com-content-article__body > p:first-child { margin-top: 0; }

.article-details .article-body::after { content: ""; display: block; clear: both; }

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

/* The footer content lives in mod_custom modules on the Helix positions
   bottom1–bottom4 and footer1–footer2. Helix paints those rows from its own
   template params (white text, its own module-title scale) and emits that CSS
   after this file, so the type and colour here are stated at a specificity
   that wins rather than relying on load order. */

#sp-footer,
#sp-bottom {
  background: var(--night);
  color: var(--night-text);
}

/* Orange is the indicator colour, so it is not spent on a field of navigation
   links. In the footer it marks only the two things a visitor acts on: the
   phone number and the email address. */
#sp-footer a,
#sp-bottom a {
  color: var(--night-text);
  text-decoration: none;
}

#sp-footer a:hover, #sp-footer a:focus,
#sp-bottom a:hover, #sp-bottom a:focus { color: #ffffff; }

#sp-bottom .rt-contact a { color: #f5a93f; }
#sp-bottom .rt-contact a:hover,
#sp-bottom .rt-contact a:focus { color: #ffffff; }

#sp-bottom .sp-module .sp-module-title,
#sp-footer .sp-module .sp-module-title {
  font-family: var(--display);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--night-faint);
  margin-bottom: 1.15rem;
}

#sp-footer .rt-contact__key,
#sp-bottom .rt-contact__key { color: var(--night-faint); }

/* A footer column is too narrow for the key/value gutter the page body uses —
   at that width the longest label pushes its value onto a second line. Here the
   pair stacks instead, which keeps every value on one line. */
#sp-bottom .rt-contact { gap: 0.85rem; }

#sp-bottom .rt-contact__line {
  display: grid;
  gap: 0.1rem;
}

#sp-bottom .rt-contact__key { min-width: 0; }

#sp-footer .container-inner { border-top: 1px solid rgba(255, 255, 255, 0.08); }

/* --- Footer column balance — delete this whole block to revert -------------
   The Helix row is 3+3+3+3, so the columns are already exact: 285px each with
   identical 30px gutters. Nothing is misaligned. What reads as uneven is the
   ink rather than the grid — the four text blocks measure 254 / 132 / 111 /
   224px, which leaves white rivers of 31 / 153 / 174px between them. Column
   one fills its column edge to edge and crowds "Vörur", while the two link
   columns trail 120-140px of air apiece.

   Sizing each column to what it actually holds — a paragraph, two short link
   lists, an address — evens those rivers to 113 / 107 / 117px. Only the lg
   breakpoint is touched; below 992px the columns stack two-up then one-up and
   there are no rivers to balance. */
@media (min-width: 992px) {
  #sp-bottom .col-lg-3:nth-child(1) { flex: 0 0 34%; max-width: 34%; }
  #sp-bottom .col-lg-3:nth-child(2) { flex: 0 0 21%; max-width: 21%; }
  #sp-bottom .col-lg-3:nth-child(3) { flex: 0 0 20%; max-width: 20%; }
  #sp-bottom .col-lg-3:nth-child(4) { flex: 0 0 25%; max-width: 25%; }

  /* 34ch measures 309px in this face, wider than the old 255px column — so the
     blurb was capped by the grid, not by its own measure. Widening column one
     hands it that slack back, and without a tighter cap it sprawls to the full
     34ch and crowds column two exactly as before. */
  #sp-bottom .rt-footer-blurb { max-width: 31ch; }
}
/* --- end footer column balance -------------------------------------------- */

/* The same asset the header uses. Its ink is entirely orange, so it survives
   the move onto --night without a second file. The height steps down from the
   header's 56px: in a footer column the mark is a signature, not the thing the
   eye lands on first. The bottom margin matches the module-title step above so
   the logo sits on the column's existing rhythm rather than beside it. */
.rt-footer-logo {
  display: block;
  height: 44px;
  width: auto;
  max-width: 100%;
  margin-bottom: 1.15rem;
}

.rt-footer-blurb {
  margin: 0;
  font-size: 0.95rem;
  max-width: 34ch;
}

.rt-footer-links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.55rem;
}

/* Helix spaces these with "#sp-bottom .sp-module ul > li { margin-bottom:15px }",
   which would otherwise stack on top of the grid gap. Matching its .sp-module
   step is what makes the reset outrank it. */
#sp-bottom .sp-module .rt-footer-links li,
#sp-footer .sp-module .rt-footer-links li { margin: 0; }

.rt-footer-links a { font-size: 0.97rem; }

.rt-legal {
  margin: 0;
  font-size: 0.85rem;
  color: var(--night-faint);
}

.rt-legal--end { text-align: right; }

@media (max-width: 767px) {
  .rt-legal--end { text-align: left; margin-top: 0.35rem; }
}

/* --------------------------------------------------------------------------
   Home page
   -------------------------------------------------------------------------- */

.rt-page-home .page-header,
.rt-page-home .article-header { display: none; }

.rt-hero {
  display: grid;
  gap: clamp(1.75rem, 4vw, 2.75rem);
  padding-block: clamp(2.25rem, 5vw, 4rem) 0;
}

.rt-hero__copy { display: grid; gap: 1rem; justify-items: start; }
.rt-hero__copy h1 { margin: 0; }
.rt-hero__copy .rt-lede { margin: 0; }

.rt-hero__actions { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 0.4rem; }

/* The only slide artwork that exists is 960x301, so it is presented as a wide
   banner at its own proportions rather than stretched into a full-bleed hero. */
.rt-hero__media {
  border-radius: 4px;
  overflow: hidden;
  background: var(--band);
  border: 1px solid var(--rule);
}

.rt-hero__media img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 360px;
  object-fit: cover;
  object-position: center 40%;
}

/* --- text beside a three-up image row --- */

.rt-split { display: grid; gap: clamp(1.75rem, 4vw, 3rem); align-items: start; }

@media (min-width: 900px) {
  .rt-split { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
}

.rt-split__copy { display: grid; gap: 0.9rem; justify-items: start; }
.rt-split__copy h2 { margin: 0; }
.rt-split__copy p { margin: 0; }

.rt-split__grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr));
}

.rt-tile { margin: 0; display: grid; gap: 0.6rem; }

.rt-tile figcaption {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.86rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* --- warm band panel --- */

.rt-band {
  background: var(--band);
  border-radius: 4px;
  padding: clamp(1.75rem, 4vw, 3rem);
}

.rt-band .rt-section__head { margin-bottom: 1rem; }
.rt-band p:last-child { margin-bottom: 0; }

/* --- three column footer-ish row on the home page --- */

.rt-trio {
  display: grid;
  gap: clamp(1.75rem, 4vw, 2.5rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  align-items: start;
}

.rt-trio__title {
  font-size: 1.05rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0 0 1rem;
  padding-bottom: 0.6rem;
  border-bottom: 2px solid var(--brand);
}

.rt-trio p { margin: 0; }

/* --------------------------------------------------------------------------
   Long-form article page
   -------------------------------------------------------------------------- */

.rt-page-article .article-header { display: none; }

.rt-figure { margin: 0 0 1.25rem; max-width: 320px; }

@media (min-width: 760px) {
  .rt-figure--left  { float: left;  margin: 0.4rem 1.75rem 1rem 0; }
  .rt-figure--right { float: right; margin: 0.4rem 0 1rem 1.75rem; }
}

.rt-figure .rt-shot { aspect-ratio: 3 / 4; }

.rt-page-article h2 {
  clear: both;
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  /* border-top: 1px solid var(--rule); */
}

/* --------------------------------------------------------------------------
   Product listing — Joomla's blog layout turned into the card grid
   -------------------------------------------------------------------------- */

.rt-page-products .page-header h1 {
  font-size: clamp(2rem, 4.5vw, 2.9rem);
  margin-bottom: 0.5rem;
}

.rt-page-products .category-desc {
  color: var(--ink-soft);
  font-size: 1.08rem;
  margin-bottom: clamp(1.75rem, 4vw, 2.75rem);
  padding-bottom: clamp(1.5rem, 3vw, 2rem);
  border-bottom: 1px solid var(--rule);
}

/* Joomla's blog layout emits one .row per line of three. Collapsing those rows
   with display:contents lets every card join a single continuous grid, so the
   columns stay even no matter how many products there are. */
.rt-page-products .article-list {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
}

.rt-page-products .article-list > .row {
  display: contents;
  margin: 0;
}

.rt-page-products .article-list [class*="col-"] {
  width: auto;
  max-width: none;
  flex: none;
  padding: 0;
}

.rt-page-products .article {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--ground);
  border: 1px solid var(--rule);
  border-radius: 4px;
  overflow: hidden;
  transition: border-color 0.16s ease, box-shadow 0.16s ease, transform 0.16s ease;
}

.rt-page-products .article:hover {
  border-color: var(--brand);
  box-shadow: 0 14px 30px -22px rgba(34, 30, 26, 0.55);
  transform: translateY(-2px);
}

/* The intro image is floated by the core layout; here it is the card's tile. */
.rt-page-products .article-intro-image {
  float: none;
  margin: 0;
  background: var(--band);
  border-bottom: 1px solid var(--rule);
  aspect-ratio: 4 / 3;
  overflow: hidden;
}

.rt-page-products .article-intro-image a { display: block; height: 100%; }

.rt-page-products .article-intro-image img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.rt-page-products .article-body {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  padding: 1.15rem 1.25rem 1.35rem;
  flex: 1;
}

.rt-page-products .article-header h2 {
  font-size: 1.22rem;
  line-height: 1.15;
  margin: 0;
}

.rt-page-products .article-header h2 a { color: var(--ink); text-decoration: none; }
.rt-page-products .article-header h2 a:hover { color: var(--brand-deep); }

.rt-page-products .article-introtext {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  flex: 1;
}

.rt-page-products .rt-product__intro {
  margin: 0;
  font-size: 0.95rem;
  color: var(--ink-soft);
  flex: 1;
}

/* The card foot pairs the price with the link, so it owns the bottom rule and
   the push to the bottom of the card that the bare readmore used to carry. */
.rt-page-products .rt-card__foot { margin-top: auto; }

.rt-page-products .rt-card__foot .readmore { margin: 0; padding: 0; }

.rt-card__price-unit {
  font-size: 0.8em;
  font-weight: 500;
  color: var(--ink-soft);
  margin-left: 0.15rem;
}

.rt-page-products .readmore { margin-top: auto; padding-top: 0.4rem; }

.rt-page-products .readmore a {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.82rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brand-deep);
  text-decoration: none;
}

.rt-page-products .readmore a::after { content: " →"; }
.rt-page-products .readmore a:hover { color: var(--brand); }

.rt-page-products .pagination-wrapper {
  margin-top: clamp(2rem, 4vw, 3rem);
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
}

/* --------------------------------------------------------------------------
   Contact page
   -------------------------------------------------------------------------- */

.rt-page-contact .contact-address { margin-bottom: 2rem; }

.rt-page-contact .rt-contact-page {
  display: grid;
  gap: clamp(1.75rem, 4vw, 2.5rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  align-items: start;
  margin-block: clamp(1.75rem, 4vw, 2.5rem);
}

.rt-page-contact .com-contact__form {
  background: var(--band);
  border-radius: 4px;
  padding: clamp(1.5rem, 3vw, 2.25rem);
  margin-top: clamp(1.75rem, 4vw, 2.5rem);
}

.rt-page-contact .com-contact__form legend,
.rt-page-contact .com-contact__form h3 {
  font-family: var(--display);
  font-size: 1.3rem;
  font-weight: 700;
}

.rt-page-contact label { font-weight: 500; }

.rt-page-contact input[type="text"],
.rt-page-contact input[type="email"],
.rt-page-contact textarea {
  border: 1px solid var(--rule-strong, #d6cfc5);
  border-radius: 3px;
  padding: 0.6rem 0.75rem;
  background: var(--ground);
  font-family: var(--body);
  width: 100%;
}

/* --------------------------------------------------------------------------
   SP Page Builder output
   --------------------------------------------------------------------------
   The pages are built from Page Builder addons, so the design system has to
   reach their markup too. Each addon carries an rt-sppb-* class set in the
   builder, which is what these rules hook onto.
   -------------------------------------------------------------------------- */

.sppb-section { overflow: hidden; }

.sppb-addon-title { font-family: var(--display); }

/* Addons stack with no gap of their own, so a heading needs breathing room
   before the text that follows it. */
.sppb-addon-header { margin-bottom: 1rem; }
.sppb-addon-header .sppb-addon-title { margin-bottom: 0; }

.sppb-addon-text-block p:last-child,
.sppb-addon-text p:last-child { margin-bottom: 0; }

/* Inside a Page Builder layout the column width is already the measure the page
   author chose, so the global 68ch cap sits on top of that choice and empties
   the right-hand side of any wide column. Here the column is left to decide.
   Paragraphs carrying a component class are excluded, so .rt-lede and the rest
   keep the measures they set for themselves — only unclassed body copy fills
   its column. Narrow columns are unaffected either way: they were already
   narrower than 68ch. */
.sppb-addon-content p:not([class]) { max-width: none; }

/* A button addon brings no top margin of its own, so it sits flush against the
   text above it. The space is put on the button rather than on that text so
   that hiding the button in the builder takes the space with it, instead of
   leaving a gap above the next section. .sppb-button-wrapper is emitted only by
   the button addon — the hero slider and the contact form use their own markup
   — so this stays clear of every other button on the site. */
.sppb-button-wrapper { margin-top: 1.6rem; }

/* --- hero slideshow --- */

/* The hero is the page's opening statement, so it meets the header and the two
   viewport edges directly rather than sitting inside the 1140px text column
   with white margins either side. Only the first section on the home page is
   released; the slide's own .sppb-container still carries the page width, so
   the headline stays aligned with the sections underneath it. */
.rt-page-home .sppb-section:first-of-type .sppb-row-container {
  max-width: none;
  padding-left: 0;
  padding-right: 0;
}

/* The slide image stopped a little short of the container's right edge, letting
   the dark layer behind the slider show through as a thin vertical band. */
.rt-sppb-hero .sp-item .sp-background {
  width: 100%;
  background-size: cover;
  background-position: center;
}

/* A scrim over the photograph, so white copy stays legible against a bright
   sky. It sits on .sp-background, which is the layer holding the image. */
.rt-sppb-hero .sp-item .sp-background::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(18, 15, 12, 0.78) 0%, rgba(18, 15, 12, 0.5) 45%, rgba(18, 15, 12, 0.05) 78%);
  pointer-events: none;
}

/* With the hero running full-bleed, the slide's own .sppb-container centres on
   the page's 1140px measure — so the copy needs nothing more than the grid's
   gutter to land on the same left edge as the headings in the sections below.
   (While the hero was boxed this carried a much larger inset, to keep the copy
   off the photograph's edge; full-bleed makes that inset a misalignment.) */
.rt-sppb-hero .sp-item > .sppb-container {
  position: relative;
  z-index: 2;
  padding-left: 15px;
  padding-right: 15px;
}

.rt-sppb-hero .sppb-sp-slider-title {
  font-family: var(--display);
  font-weight: 700;
  letter-spacing: -0.015em;
  font-size: clamp(1.9rem, 4.4vw, 3rem);
  line-height: 1.05;
  margin: 0 0 0.6rem;
  color: #fff;
  max-width: 18ch;
}

.rt-sppb-hero .sppb-sp-slider-text p {
  margin: 0;
  max-width: 42ch;
  color: rgba(255, 255, 255, 0.92);
}

/* The stock arrows are large translucent circles that land on top of the
   headline; these are smaller, squared off, and out of the text's way. */
.rt-sppb-hero .sp-nav-control .nav-control {
  width: 40px;
  height: 40px;
  line-height: 40px;
  font-size: 17px;
  background: rgba(18, 15, 12, 0.45);
  border-radius: 2px;
  color: #fff;
  transition: background 0.16s ease;
}

.rt-sppb-hero .sp-nav-control .nav-control:hover { background: var(--brand); }

.rt-sppb-hero .sp-dots .dot-indicator { background: rgba(255, 255, 255, 0.5); }
.rt-sppb-hero .sp-dots .dot-indicator.active { background: var(--brand); }

/* --- image addon: same contained tile as the rest of the site --- */

.rt-sppb-shot .sppb-addon-single-image-container {
  background: var(--band);
  border: 1px solid var(--rule);
  border-radius: 3px;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  display: block;
}

.rt-sppb-shot img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.rt-sppb-tile-title .sppb-addon-title {
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0.75rem 0 0;
}

/* The tiles link through to the overview page. The caption keeps its caption
   colour rather than taking the link colour — three orange labels in a row
   would read as decoration — so the tile marks itself on hover instead, using
   the same border and colour shift the product cards use. */
.rt-sppb-shot a { display: block; }

.rt-sppb-shot a .sppb-addon-single-image-container {
  transition: border-color 0.16s ease;
}

.rt-sppb-shot a:hover .sppb-addon-single-image-container,
.rt-sppb-shot a:focus-visible .sppb-addon-single-image-container {
  border-color: var(--brand);
}

.rt-sppb-tile-title a { text-decoration: none; }

.rt-sppb-tile-title a:hover .sppb-addon-title,
.rt-sppb-tile-title a:focus-visible .sppb-addon-title {
  color: var(--brand-deep);
}

.rt-sppb-trio-title .sppb-addon-title {
  font-size: 1.05rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin: 0 0 1rem;
  padding-bottom: 0.6rem;
  border-bottom: 2px solid var(--brand);
}

/* --- articles addon: reuse the product card treatment --- */

.rt-sppb-articles .sppb-addon-article {
  background: var(--ground);
  border: 1px solid var(--rule);
  border-radius: 4px;
  overflow: hidden;
  height: 100%;
  display: flex;
  flex-direction: column;
  transition: border-color 0.16s ease, box-shadow 0.16s ease, transform 0.16s ease;
}

.rt-sppb-articles .sppb-addon-article:hover {
  border-color: var(--brand);
  box-shadow: 0 14px 30px -22px rgba(34, 30, 26, 0.55);
  transform: translateY(-2px);
}

.rt-sppb-articles .sppb-article-img-wrap {
  background: var(--band);
  border-bottom: 1px solid var(--rule);
  aspect-ratio: 4 / 3;
  overflow: hidden;
  display: block;
}

.rt-sppb-articles .sppb-article-img-wrap img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.rt-sppb-articles .sppb-article-info-wrap { padding: 1.15rem 1.25rem 1.35rem; flex: 1; display: flex; flex-direction: column; gap: 0.7rem; }

/* The addon prints the article title as a bare <h2>, which would otherwise
   pick up the page-level heading scale. */
.rt-sppb-articles .sppb-addon-article h2 {
  font-family: var(--display);
  font-size: 1.2rem;
  line-height: 1.15;
  margin: 0;
}

.rt-sppb-articles .sppb-addon-article h2 a { color: var(--ink); text-decoration: none; }
.rt-sppb-articles .sppb-addon-article h2 a:hover { color: var(--brand-deep); }

/* Author, category and date are switched off, but the wrapper still prints. */
.rt-sppb-articles .sppb-article-meta:empty { display: none; }

/* The addon's trailing "all articles" button has no place on the page that
   already lists every product. */
.rt-sppb-articles > .sppb-addon-content > .sppb-btn { display: none; }

.rt-sppb-articles .sppb-article-introtext { font-size: 0.95rem; color: var(--ink-soft); margin: 0; flex: 1; }

.rt-sppb-articles .sppb-readmore {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.82rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brand-deep);
  text-decoration: none;
  margin-top: auto;
}

.rt-sppb-articles .sppb-readmore::after { content: " →"; }

.rt-sppb-articles .sppb-pagination { margin-top: 2.5rem; padding-top: 1.5rem; border-top: 1px solid var(--rule); }

/* --- map --- */

/* Wide and short: the map only has to place the address, and a 4/3 box left it
   overhanging the two text columns beside it. */
.rt-map {
  border: 1px solid var(--rule);
  border-radius: 3px;
  overflow: hidden;
  aspect-ratio: 16 / 9;
  background: var(--band);
}

.rt-map iframe { width: 100%; height: 100%; border: 0; display: block; }

.rt-map__link {
  margin: 0.6rem 0 0;
  font-family: var(--display);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

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

.rt-sppb-form .sppb-addon-ajax-contact { max-width: 780px; }

.rt-sppb-form input[type="text"],
.rt-sppb-form input[type="email"],
.rt-sppb-form input[type="tel"],
.rt-sppb-form textarea {
  border: 1px solid var(--rule-strong, #d6cfc5);
  border-radius: 3px;
  padding: 0.65rem 0.8rem;
  background: var(--ground);
  font-family: var(--body);
  width: 100%;
}

.rt-sppb-form label {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.rt-sppb-form .sppb-btn {
  font-family: var(--display);
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  border-radius: 2px;
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
}

.rt-sppb-form .sppb-btn:hover { background: var(--brand-deep); border-color: var(--brand-deep); }

/* --------------------------------------------------------------------------
   Motion
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  .rt-card:hover,
  .sppb-addon-articles .sppb-addon-article:hover { transform: none; }
}
