/*
 * Robinhood Widgets — front end
 *
 * No custom property is given a default on the element itself. A property
 * declared on an element beats one declared higher up, so defaults set here
 * would silently cancel anything a widget writes. Every use carries its own
 * fallback instead.
 */

/* ------------------------------------------------------------- materials -- */

/*
 * One recipe, in tokens.
 *
 * Each token falls back to the site's own glass value when the site has one, so
 * a glass button here comes out identical to a glass button anywhere else on
 * that site rather than merely similar — which is what happened when this was a
 * separate, simpler recipe of its own. On a site with no glass of its own the
 * fallbacks take over and it still looks right.
 *
 * Two gradients, not one: a sweep across the surface that reads as light coming
 * from one side, and the body of the material underneath it. Three shadows: a
 * highlight along the top edge, a darker line along the bottom, and the lift
 * that separates the whole thing from what is behind it. Take any of them away
 * and the surface goes flat.
 */

.rhw-glass,
.rhw-matte,
.rhw-frost{
  --rhw-tint: var(--bm-glass-tint, 255,255,255);
  --rhw-sat:  var(--bm-glass-sat, 1.7);
  --rhw-a1:   var(--bm-glass-a1, .20);
  --rhw-a2:   var(--bm-glass-a2, .07);
  --rhw-edge: var(--bm-glass-edge, .24);
  --rhw-hi:   var(--bm-glass-hi, .42);
  --rhw-lift: var(--bm-glass-lift, 0 10px 30px -12px rgba(0,0,0,.55));

  position: relative;
  -webkit-backdrop-filter: blur(var(--rhw-blur, var(--bm-glass-blur, 20px))) saturate(var(--rhw-sat));
          backdrop-filter: blur(var(--rhw-blur, var(--bm-glass-blur, 20px))) saturate(var(--rhw-sat));
  border: 1px solid rgba(var(--rhw-tint), var(--rhw-edge));
  box-shadow:
    inset 0 1px 0 rgba(var(--rhw-tint), var(--rhw-hi)),
    inset 0 -1px 0 rgba(var(--rhw-tint), .10),
    var(--rhw-lift);
}

/*
 * background-image, never background: a colour picked in the panel arrives as
 * background-color, and laying only the gradients over it keeps that colour
 * showing through the material instead of wiping it.
 */
.rhw-glass,
.rhw-matte{
  background-image:
    linear-gradient(115deg,
      rgba(var(--rhw-tint), calc(.22 * var(--rhw-sheen, 1))) 0%,
      rgba(var(--rhw-tint), 0) 34%,
      rgba(var(--rhw-tint), 0) 66%,
      rgba(var(--rhw-tint), calc(.12 * var(--rhw-sheen, 1))) 100%),
    linear-gradient(150deg,
      rgba(var(--rhw-tint), calc(var(--rhw-a1) * var(--rhw-sheen, 1))) 0%,
      rgba(var(--rhw-tint), calc(var(--rhw-a2) * var(--rhw-sheen, 1))) 46%,
      rgba(var(--rhw-tint), calc((var(--rhw-a2) + .05) * var(--rhw-sheen, 1))) 100%);
}

/*
 * A stroke and nothing else.
 *
 * The quietest of the materials: no fill, no blur, no shadow — one line in the
 * colour asked for, and the writing inside it. It takes the colour of the
 * writing unless it is given one of its own.
 */
.rhw-outline{
  background: none;
  border: var(--rhw-stroke-w, 1px) solid var(--rhw-stroke, currentColor);
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* Matte is the same recipe turned up until the backdrop stops reading. */
.rhw-matte{
  --rhw-blur: var(--bm-glass-blur, 30px);
  --rhw-a1:   .74;
  --rhw-a2:   .62;
  --rhw-edge: .55;
  --rhw-hi:   .88;
  --rhw-lift: 0 14px 34px -14px rgba(0,0,0,.30), 0 2px 6px -2px rgba(0,0,0,.14);
}

/* Frost keeps the blur and drops the surface, so what is behind shows as fog. */
.rhw-frost{
  --rhw-blur: var(--bm-glass-blur, 32px);
  --rhw-edge: .30;
  --rhw-hi:   .50;
}

.rhw-plain{ background-color: var(--rhw-bg, rgba(255,255,255,.06)); }

.rhw-bare{
  background: none;
  border: 0;
  box-shadow: none;
  -webkit-backdrop-filter: none;
          backdrop-filter: none;
}

/* -------------------------------------------------------- shared text ----- */

/*
 * Anything on a line whose glyphs carry no descender — an all-caps label, a
 * code made of digits — shares the baseline of the text beside it but reads as
 * sitting above it, because all of its ink is above that baseline. Measured at
 * 14px the gap is 1.29px, which is 0.09em. Set the property to 0 for plain
 * baseline alignment.
 */
/*
 * No transform on the code box. A transform of a fraction of a pixel makes the
 * browser draw its 1px border across two rows of pixels, and the top and bottom
 * edges wash out while the left and right stay solid — which is what made the
 * box look like a lens rather than a rectangle. If it ever needs shifting, it
 * shifts by whole pixels through the control.
 */
.rhw-code{ position: relative; top: var(--rhw-code-shift, 0); }

/*
 * The label is a different matter. At the same size as the product names it is
 * already on their baseline and needs nothing; only when it is set smaller does
 * it start to read as sitting high. So the default is no correction at all, and
 * the control exists for when the sizes differ.
 */
.rhw-label{ transform: translateY(var(--rhw-label-nudge, 0)); }

.rhw-label{
  flex: none;
  font-family: inherit;
  font-size: var(--rhw-label-size, .78em);
  font-weight: 500;
  letter-spacing: 2px;
  line-height: 1;
  color: var(--rhw-dim, rgba(243,239,247,.62));
}

/* ---------------------------------------------------------- price ticker -- */

.rhw-ticker{
  display: flex;
  align-items: center;
  gap: .9rem;
  width: var(--rhw-fill, auto);
  max-width: 100%;
  overflow: hidden;
  padding: .3rem .7rem;
  border-radius: 999px;
  color: var(--rhw-ink, #F3EFF7);
  font-family: inherit;
  font-size: .82rem;
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: -.5px;
  /* No mask unless a fade was asked for. Switching it off by writing zero into
   * the gradient still left a mask on the element, and the compositing that
   * comes with one is not free. */
  -webkit-mask-image: var(--rhw-mask, none);
          mask-image: var(--rhw-mask, none);
}

.rhw-viewport{ flex: 1 1 auto; min-width: 0; min-height: 0; overflow: hidden; }

.rhw-track{
  display: flex;
  width: max-content;
  animation: rhw-run var(--rhw-speed, 45s) linear infinite;
  will-change: transform;
}
.rhw-set{
  display: flex;
  gap: var(--rhw-item-gap, 2.4rem);
  padding-inline-end: var(--rhw-item-gap, 2.4rem);
}
.rhw-item{
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  white-space: nowrap;
  text-decoration: none;
  color: inherit;
}
/*
 * With linking on, every item is an anchor, and a theme's own link colour
 * outranks anything set on the item. These match that specificity and come
 * later in the document, so the chosen colours win.
 */
body .rhw-ticker a.rhw-item,
body .rhw-ticker a.rhw-item:visited,
body .rhw-ticker .rhw-name{ color: var(--rhw-ink, #F3EFF7); }
body .rhw-ticker a.rhw-item:hover,
body .rhw-ticker a.rhw-item:hover .rhw-name{ color: var(--rhw-accent, #C77BD4); }
a.rhw-item:hover .rhw-name{ text-decoration: underline; }

.rhw-name{ font-weight: inherit; }
/*
 * The digits are shifted inside their own wrapper rather than by padding or by
 * moving the box. Padding grew the box until it met the rows above and below;
 * moving the box by a fraction of a pixel made its 1px border draw as a lens.
 * A wrapper moves only the ink.
 *
 * Measured inside the border before the correction: 2.17px of space above the
 * ink against 4.37px below, because digits carry no descender.
 */
.rhw-code-text{
  display: block;
  transform: translateY(var(--rhw-code-ink, .125em));
}

.rhw-price{
  color: var(--rhw-accent, #C77BD4);
  font-variant-numeric: tabular-nums;
}

/*
 * A fixed height with symmetric padding, so the border draws a clean rounded
 * box. Uneven padding made the box shorter on one side and the corners came
 * out ragged at this size.
 */
/*
 * The box wraps its own text rather than standing at a fixed height. A fixed
 * height taller than the row was being cut in half by the strip's overflow, so
 * the border showed as two vertical bars with no top or bottom — and it broke
 * again at every font size. max-height keeps it inside the row whatever the
 * size, so the border is always drawn whole.
 */
.rhw-code{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  /*
   * As tall as its own contents, not as tall as the row. Filling the row left
   * no space between one row and the next, so at a larger size the boxes above
   * and below ran into each other and read as one shape. A height typed into
   * the control is used exactly as typed — nothing clamps it any more.
   */
  height: var(--rhw-code-h, auto);
  min-width: var(--rhw-code-min, 2.6em);
  padding: var(--rhw-code-pad-y, .18em) var(--rhw-code-pad-x, .5em);
  font-size: .76em;
  font-weight: 400;
  letter-spacing: .09em;
  line-height: 1;
  color: var(--rhw-dim, rgba(243,239,247,.62));
  background-color: var(--rhw-code-bg, transparent);
  border: 1px solid currentColor;
  border-radius: .45em;
}

@keyframes rhw-run{
  from{ transform: translate3d(0,0,0); }
  to  { transform: translate3d(-50%,0,0); }
}

/*
 * One product at a time, rising. The viewport is locked to one row so the bar
 * can never change height, and every item is that same row height whether it
 * carries a code or not. No row-height default is declared on the element, so
 * a widget can set it.
 */
/*
 * Exactly one row tall and never stretched. Align Items set to stretch made the
 * window as tall as the bar, so the row on its way in was visible underneath
 * the one being read — two products at once, which is the one thing this mode
 * exists to avoid.
 */
.rhw-ticker-vertical .rhw-viewport{
  height: var(--rhw-row, 1.9rem);
  min-height: var(--rhw-row, 1.9rem);
  max-height: var(--rhw-row, 1.9rem);
  flex: 1 1 auto;
  align-self: center;
}
.rhw-ticker-vertical .rhw-track{ flex-direction: column; width: 100%; animation: none; }
.rhw-ticker-vertical .rhw-set{ flex-direction: column; gap: 0; padding-inline-end: 0; }
.rhw-ticker-vertical .rhw-item{
  height: var(--rhw-row, 1.9rem);
  min-height: var(--rhw-row, 1.9rem);
  align-items: center;
}

/*
 * Pausing lets a price be read while it scrolls past. One product at a time
 * there is nothing to catch — each one already stands still for its turn — and
 * pausing halfway through the rise froze a row mid-move, half in and half out.
 */
.rhw-ticker:hover .rhw-track,
.rhw-ticker:focus-within .rhw-track{ animation-play-state: paused; }
.rhw-ticker-vertical:hover .rhw-track,
.rhw-ticker-vertical:focus-within .rhw-track{ animation-play-state: running; }

[dir="rtl"] .rhw-track{ animation-direction: reverse; }

/* ---------------------------------------------------------- order number -- */

.rhw-order{
  display: inline-flex;
  align-items: center;
  gap: var(--rhw-gap, .6rem);
  width: var(--rhw-fill, auto);
  max-width: 100%;
  border-radius: 999px;
  color: var(--rhw-ink, #F3EFF7);
  font-family: inherit;
}
.rhw-order.rhw-glass,
.rhw-order.rhw-matte,
.rhw-order.rhw-frost,
.rhw-order.rhw-plain{ padding: .35rem 1rem; }

.rhw-order-stack{
  flex-direction: column;
  align-items: var(--rhw-stack-align, flex-start);
  gap: var(--rhw-gap, .15rem);
}

/*
 * One unbreakable run. This is the reason the widget exists: a counter let the
 * area code wrap away from the digits, and grew a digit at a time so the box
 * changed width on every frame.
 */
body .rhw-order-value,
body a.rhw-order-value,
body a.rhw-order-value:visited{
  display: inline-flex;
  align-items: baseline;
  gap: .04em;
  direction: ltr;
  white-space: nowrap;
  text-decoration: none;
  color: var(--rhw-ink, #F3EFF7);
  font-size: 1.4rem;
  font-weight: 600;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
body a.rhw-order-value:hover{ color: var(--rhw-accent, #C77BD4); }

.rhw-order-sep{ opacity: .55; }

/*
 * The icon takes the colour of whatever it sits beside unless it is given one,
 * and is sized in its own em so a change of size does not move anything else.
 */
/*
 * Inline, not a flex item. Inline layout lines an icon up on the text's own
 * middle — baseline plus half the x-height — which is where the eye expects it
 * and which stays right at any font size without a number being typed in.
 */
.rhw-order-icon{
  display: inline-block;
  flex: none;
  line-height: 1;
  color: inherit;
  margin-inline-end: var(--rhw-icon-gap, .4em);
  /*
   * The label is set in capitals. `vertical-align: middle` centres an icon on
   * the middle of the x-height, which for capitals reads as sitting high — this
   * puts it on the middle of the cap band instead. Measured on a rendered strip:
   * the gap closes to nothing at 0.17em, and it is a control, so any icon family
   * that sits differently can be corrected without touching this.
   */
  vertical-align: middle;
  transform: translateY(var(--rhw-icon-shift, .17em));
}

/* Beside the number the run is a flex row, where vertical-align does not apply,
 * so the icon is centred on the line and carries the same correction. */
.rhw-order-value > .rhw-order-icon{
  align-self: center;
  transform: translateY(var(--rhw-icon-shift, .17em));
}
.rhw-order-icon svg{
  width: 1em;
  height: 1em;
  fill: currentColor;
  display: block;
}
.rhw-order-icon i{ font-size: inherit; line-height: 1; }


/* ------------------------------------------------------- reduced motion --- */

/*
 * Nobody should be made to chase a moving price. The strip stops and becomes an
 * ordinary scrollable row, and the duplicate set is dropped so the list is not
 * repeated. The count is skipped in the script.
 */
@media (prefers-reduced-motion: reduce){
  .rhw-track{ animation: none !important; width: auto; }
  .rhw-set[aria-hidden="true"]{ display: none; }
  .rhw-viewport{ overflow-x: auto; }
  .rhw-ticker-vertical .rhw-viewport{ height: auto; overflow: visible; }
}

/* ------------------------------------------------------------ hero slider -- */

/*
 * Nothing below names a left or a right. The arrangement is start and end, so a
 * right-to-left page turns the whole thing round — picture, text, arrows — with
 * nothing set anywhere. The Reading direction control can pin one widget the
 * other way when that is wanted on purpose.
 */

.rhw-hero{
  position: relative;
  width: var(--rhw-fill, 100%);
  max-width: 100%;
  /* A picture told to hang past the bottom has to be allowed out. */
  overflow: visible;
}

.rhw-hero-track{ display: grid; }

/*
 * Every slide occupies the same cell, so the block never changes height as one
 * replaces another and nothing on the page below it moves.
 */
.rhw-slide{
  grid-area: 1 / 1;
  display: flex;
  align-items: center;
  gap: var(--rhw-gap, 3rem);
  opacity: 0;
  visibility: hidden;
  /*
   * The one leaving fades for as long as the one arriving does, and only
   * becomes hidden once its fade has finished — the delayed visibility is
   * what turns a fade-in into a true cross-fade. The arriving slide, below,
   * drops that delay so it can be seen fading.
   */
  transition: opacity var(--rhw-xfade, .5s) ease, visibility 0s linear var(--rhw-xfade, .5s);
}
.rhw-slide.is-active{
  opacity: 1;
  visibility: visible;
  transition: opacity var(--rhw-xfade, .5s) ease, visibility 0s;
}

.rhw-hero-copy{
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.rhw-hero-copy > *{ margin: 0; }

/* Positioned, so it can be layered over what follows once it hangs past the
   edge. Without a position of its own a z-index means nothing. */
.rhw-hero-media{ flex: 0 0 42%; max-width: 42%; min-width: 0; position: relative; }
.rhw-hero-media img{
  display: block;
  width: 100%;
  height: auto;
  /* Named so a change of colour or fade eases rather than snapping. The
     duration is a control, and zero there means no transition at all. */
  transition-property: opacity, filter;
  transition-duration: .4s;
  transition-timing-function: ease;
}

/* Above or below the writing, the picture takes the full width whatever was
   set for it beside the writing.

   This used to look for the direction in an inline style, which was only ever
   true while the widget was being previewed. The choice reaches the page as a
   rule in the document's own stylesheet, so it left no trace to look for and
   the picture stayed at its beside-the-writing share: a 123px crop of a face
   in the middle of a phone. The choice now writes a class as well, one per
   screen size, and that is what is read here.

   `!important` because the share control writes its own width on this element
   from the document stylesheet, which is more specific than anything a plugin
   stylesheet can say. The share is meaningless once the two are stacked, so
   overruling it is not a fight, it is the answer.

   Going the other way is not supported: a picture set above or below at a wide
   size and back beside the writing at a narrow one keeps the full width. No
   design has ever wanted that, and reversing it would need the share's number,
   which a plain stylesheet cannot know. */
.rhw-side-above .rhw-hero-media,
.rhw-side-below .rhw-hero-media{
  flex: 0 0 auto !important;
  max-width: 100% !important;
  width: 100%;
}

@media (max-width: 1024px){
  .rhw-side-tablet-above .rhw-hero-media,
  .rhw-side-tablet-below .rhw-hero-media{
    flex: 0 0 auto !important;
    max-width: 100% !important;
    width: 100%;
  }
}

@media (max-width: 767px){
  .rhw-side-mobile-above .rhw-hero-media,
  .rhw-side-mobile-below .rhw-hero-media{
    flex: 0 0 auto !important;
    max-width: 100% !important;
    width: 100%;
  }
}

/* Behind the writing.

   The picture leaves the row and is drawn across the whole slide, with the
   writing over it. This is what a band whose background is a photograph wants,
   and it is the one arrangement the row cannot express: a row shares its width
   between the two, and here there is nothing to share.

   `!important` for the same reason as above and below: the share, the width and
   the height are written on these elements from the document's own stylesheet,
   which outranks anything a plugin stylesheet can say, and all three are
   meaningless once the picture is the backdrop.

   The one-way rule of the block above holds here too. A picture set behind the
   writing at a wide size and back beside it at a narrow one is not supported. */
.rhw-side-behind .rhw-slide{ position: relative; }
.rhw-side-behind .rhw-hero-media{
  position: absolute;
  inset: 0;
  flex: 0 0 auto !important;
  max-width: none !important;
  width: auto;
  z-index: 0;
}
.rhw-side-behind .rhw-hero-media img{
  width: 100% !important;
  height: 100% !important;
  object-fit: cover;
}
/* Over the picture, and positioned so the z-index means something. */
.rhw-side-behind .rhw-hero-copy{ position: relative; z-index: 1; }

@media (max-width: 1024px){
  .rhw-side-tablet-behind .rhw-slide{ position: relative; }
  .rhw-side-tablet-behind .rhw-hero-media{
    position: absolute;
    inset: 0;
    flex: 0 0 auto !important;
    max-width: none !important;
    width: auto;
    z-index: 0;
  }
  .rhw-side-tablet-behind .rhw-hero-media img{
    width: 100% !important;
    height: 100% !important;
    object-fit: cover;
  }
  .rhw-side-tablet-behind .rhw-hero-copy{ position: relative; z-index: 1; }
}

@media (max-width: 767px){
  .rhw-side-mobile-behind .rhw-slide{ position: relative; }
  .rhw-side-mobile-behind .rhw-hero-media{
    position: absolute;
    inset: 0;
    flex: 0 0 auto !important;
    max-width: none !important;
    width: auto;
    z-index: 0;
  }
  .rhw-side-mobile-behind .rhw-hero-media img{
    width: 100% !important;
    height: 100% !important;
    object-fit: cover;
  }
  .rhw-side-mobile-behind .rhw-hero-copy{ position: relative; z-index: 1; }
}

.rhw-slide[style*="column"] .rhw-hero-media,
.rhw-hero-track .rhw-slide:where([style*="flex-direction:column"]) .rhw-hero-media{
  flex: 1 1 auto;
  max-width: 100%;
}

.rhw-hero-eyebrow{ line-height: 1.2; }
.rhw-hero-title{ line-height: 1.02; }
/* The space between the two halves. On its own line it becomes an indent, so
   the control that moves it also takes this to zero. */
.rhw-hero-title-accent{ margin-inline-start: var(--rhw-title-gap, .3em); }
.rhw-hero-subtitle{ line-height: 1.2; }
.rhw-hero-text{ line-height: 1.65; }
.rhw-hero-text p{ margin: 0 0 .6em; }
.rhw-hero-text p:last-child{ margin-bottom: 0; }

/*
 * A material on the button needs its own stacking to blur what is behind it,
 * and the border the materials draw must not fight the one set by hand.
 */
.rhw-hero-button{
  display: inline-block;
  /* Sized by its writing, not by the column it stands in. A column set to
     stretch its children would otherwise pull the button the whole width of
     the slide. Alignment still decides where it sits; --rhw-hero-button-w
     set to 100% gives back the full-width button for anyone who wants one. */
  width: var(--rhw-hero-button-w, fit-content);
  max-width: 100%;
  position: relative;
  isolation: isolate;
  padding: .7em 1.6em;
  border-radius: 999px;
  text-decoration: none;
  cursor: pointer;
  transition: transform .2s cubic-bezier(.16,.84,.32,1), background-color .2s ease, color .2s ease;
  will-change: transform;
}
/*
 * A custom property set on the widget flows down into everything inside it, so
 * a blur chosen for the box was quietly deciding the button's blur too. This
 * hands the button back its own default; the button's own control still wins,
 * because Elementor writes that at a higher specificity.
 */
.rhw-hero-button{ --rhw-blur: initial; --rhw-sheen: initial; }

/*
 * A button is not a small panel: it takes the same tokens but a recipe of its
 * own. The sweep across it has three stops rather than four and the body of the
 * material has two rather than three, and there is no dark line along the
 * bottom edge — on something this small that line reads as a smudge.
 *
 * Taken from the site's own glass button so the two match rather than merely
 * resemble each other.
 */
.rhw-hero-button.rhw-glass,
.rhw-hero-button.rhw-matte{
  background-image:
    linear-gradient(115deg,
      rgba(var(--rhw-tint), calc(.24 * var(--rhw-sheen, 1))) 0%,
      rgba(var(--rhw-tint), 0) 36%,
      rgba(var(--rhw-tint), calc(.14 * var(--rhw-sheen, 1))) 100%),
    linear-gradient(150deg,
      rgba(var(--rhw-tint), calc(var(--rhw-a1) * var(--rhw-sheen, 1))) 0%,
      rgba(var(--rhw-tint), calc(var(--rhw-a2) * var(--rhw-sheen, 1))) 100%);
}
.rhw-hero-button.rhw-glass,
.rhw-hero-button.rhw-matte,
.rhw-hero-button.rhw-frost{
  box-shadow:
    inset 0 1px 0 rgba(var(--rhw-tint), var(--rhw-hi)),
    var(--rhw-lift);
}

/* The lift, and the easing it moves on — the same one the site uses. */
.rhw-hero-button.rhw-glass:hover,
.rhw-hero-button.rhw-matte:hover,
.rhw-hero-button.rhw-frost:hover{ transform: translateY(-2px); }

/* ---------------------------------------------------------- arrows, dots -- */

/*
 * The theme styles every button on the page — padding, height, line-height —
 * and those rules outweigh a single class, which once squashed these to a
 * two-pixel sliver. So everything the theme could touch is set again here,
 * under a heavier selector.
 */
.rhw-hero .rhw-hero-arrow{
  position: absolute;
  z-index: 3;
  inset-block-start: var(--rhw-arrow-top, 50%);
  translate: 0 -50%;
  width: var(--rhw-arrow, 34px);
  height: var(--rhw-arrow, 34px);
  min-width: 0;
  min-height: 0;
  padding: 0;
  margin: 0;
  border: 0;
  border-radius: 50%;
  background: var(--rhw-nav-bg, transparent);
  box-shadow: none;
  color: var(--rhw-nav, rgba(255,255,255,.65));
  font-size: 0;
  line-height: 0;
  cursor: pointer;
}
.rhw-hero .rhw-hero-arrow:hover{
  color: var(--rhw-nav-on, #fff);
  background: var(--rhw-nav-bg-on, var(--rhw-nav-bg, transparent));
}
/*
 * The chevron is a shape, not a piece of text, so it is drawn with physical
 * borders — a logical border-inline-start swapped sides on a right-to-left page
 * and turned the arrows into a caret pointing up and down. Which way each one
 * points is decided below instead, where it can be read.
 */
.rhw-hero .rhw-hero-arrow::before{
  content: "";
  display: block;
  width: 38%;
  height: 38%;
  margin: 0 auto;
  /* The stroke keeps pace with the size control instead of staying hairline. */
  border-top: max(2px, calc(var(--rhw-arrow, 34px) / 15)) solid currentColor;
  border-left: max(2px, calc(var(--rhw-arrow, 34px) / 15)) solid currentColor;
}
/* Placed by the side the page starts on, so they swap round with it. They
   rest outside the box — sitting on the edge lands them on the writing — and
   stay visible there because the hero never clips. The distance control moves
   them from this resting place, inward past zero if wanted. */
.rhw-hero .rhw-hero-prev{
  inset-inline-start: var(--rhw-arrow-inset, calc(-1 * var(--rhw-arrow, 34px) - 10px));
}
.rhw-hero .rhw-hero-next{
  inset-inline-end: var(--rhw-arrow-inset, calc(-1 * var(--rhw-arrow, 34px) - 10px));
}

/* Pointing outwards, away from the middle. */
.rhw-hero-prev::before{ rotate: -45deg; translate: 22% 0; }
.rhw-hero-next::before{ rotate: 135deg; translate: -22% 0; }
[dir="rtl"] .rhw-hero-prev::before{ rotate: 135deg; translate: -22% 0; }
[dir="rtl"] .rhw-hero-next::before{ rotate: -45deg; translate: 22% 0; }

.rhw-hero .rhw-hero-dots{
  position: absolute;
  inset-block-end: var(--rhw-dots-inset, 0px);
  inset-inline-start: 50%;
  translate: -50% 0;
  z-index: 3;
  display: flex;
  gap: var(--rhw-dot-gap, .5rem);
  padding: 0;
  margin: 0;
}
/* A button, so the theme's button rules reach for it too — everything they
   could stretch is pinned here, the same as the arrows above. */
.rhw-hero .rhw-hero-dot{
  width: var(--rhw-dot, 8px);
  height: var(--rhw-dot, 8px);
  min-width: 0;
  min-height: 0;
  flex: 0 0 auto;
  padding: 0;
  margin: 0;
  border: 0;
  border-radius: 50%;
  background: var(--rhw-nav, rgba(255,255,255,.4));
  box-shadow: none;
  font-size: 0;
  line-height: 0;
  cursor: pointer;
}
.rhw-hero .rhw-hero-dot.is-active{ background: var(--rhw-nav-on, #fff); }

/* ------------------------------------------------------------ arriving ----- */

/*
 * Each piece arrives a little after the one above it, which is what makes the
 * sequence read as one movement rather than five separate ones.
 */
.rhw-hero[data-rhw-anim]:not([data-rhw-anim="none"]) .rhw-slide.is-active > .rhw-hero-copy > *,
.rhw-hero[data-rhw-anim]:not([data-rhw-anim="none"]) .rhw-slide.is-active > .rhw-hero-media{
  animation-duration: .7s;
  animation-timing-function: cubic-bezier(.22,.61,.36,1);
  animation-fill-mode: both;
}
.rhw-hero .rhw-slide.is-active > .rhw-hero-copy > :nth-child(1){ animation-delay: .05s; }
.rhw-hero .rhw-slide.is-active > .rhw-hero-copy > :nth-child(2){ animation-delay: .14s; }
.rhw-hero .rhw-slide.is-active > .rhw-hero-copy > :nth-child(3){ animation-delay: .23s; }
.rhw-hero .rhw-slide.is-active > .rhw-hero-copy > :nth-child(4){ animation-delay: .32s; }
.rhw-hero .rhw-slide.is-active > .rhw-hero-copy > :nth-child(5){ animation-delay: .41s; }
.rhw-hero .rhw-slide.is-active > .rhw-hero-media{ animation-delay: .12s; }

.rhw-hero[data-rhw-anim="rise"]   .rhw-slide.is-active > .rhw-hero-copy > *,
.rhw-hero[data-rhw-anim="rise"]   .rhw-slide.is-active > .rhw-hero-media{ animation-name: rhw-rise-in; }
.rhw-hero[data-rhw-anim="blur"]   .rhw-slide.is-active > .rhw-hero-copy > *,
.rhw-hero[data-rhw-anim="blur"]   .rhw-slide.is-active > .rhw-hero-media{ animation-name: rhw-focus-in; }
.rhw-hero[data-rhw-anim="slide"]  .rhw-slide.is-active > .rhw-hero-copy > *,
.rhw-hero[data-rhw-anim="slide"]  .rhw-slide.is-active > .rhw-hero-media{ animation-name: rhw-slide-in; }

@keyframes rhw-rise-in{
  from{ opacity: 0; translate: 0 28px; }
  to  { opacity: 1; translate: 0 0; }
}
@keyframes rhw-focus-in{
  from{ opacity: 0; filter: blur(12px); scale: 1.03; }
  to  { opacity: 1; filter: blur(0); scale: 1; }
}
/* The slide comes from the side the page starts on, so it reverses with the
   page rather than always coming from the left. */
@keyframes rhw-slide-in{
  from{ opacity: 0; translate: calc(-1 * var(--rhw-from, 40px)) 0; }
  to  { opacity: 1; translate: 0 0; }
}
[dir="rtl"] .rhw-hero[data-rhw-anim="slide"]{ --rhw-from: -40px; }

/* Reveal wipes each line up from behind its own edge, so it needs a clip
   rather than a move. */
.rhw-hero[data-rhw-anim="reveal"] .rhw-slide.is-active > .rhw-hero-copy > *,
.rhw-hero[data-rhw-anim="reveal"] .rhw-slide.is-active > .rhw-hero-media{
  animation-name: rhw-reveal-in;
  animation-duration: .85s;
}
@keyframes rhw-reveal-in{
  from{ opacity: 1; clip-path: inset(0 0 100% 0); translate: 0 12px; }
  to  { opacity: 1; clip-path: inset(0 0 -20% 0); translate: 0 0; }
}

/* Letter by letter: the script wraps each character, and they follow one
   another across the title only. */
.rhw-hero-letter{ display: inline-block; white-space: pre; }
.rhw-hero[data-rhw-anim="letters"] .rhw-slide.is-active .rhw-hero-letter{
  animation: rhw-rise-in .5s cubic-bezier(.22,.61,.36,1) both;
  animation-delay: calc(var(--rhw-i, 0) * 28ms);
}

/*
 * Asked for less motion, the pieces are simply there. Nothing fades, nothing
 * slides, and the slideshow stops moving on its own.
 */
@media (prefers-reduced-motion: reduce){
  .rhw-hero *{ animation: none !important; transition: none !important; }
  .rhw-slide{ transition: none; }
}

@media (max-width: 767px){
  .rhw-slide{ flex-direction: column; }
  .rhw-hero-media{ flex: 1 1 auto; max-width: 100%; }
}

/* ================================================================== rope == */

/*
 * A strand hung down the page as ornament.
 *
 * Elementor lays widgets out as flex items in a column, and a flex column with
 * a gap gives every item a gap — even one with nothing in it. So the widget's
 * own box is taken out of the flow entirely: it claims the width of the
 * container it was dropped into, has no height of its own, and the rope hangs
 * from that corner. Nothing above it moves, nothing below it moves, and the
 * column spaces itself as though the widget were not there.
 */
.elementor-element.rhw-rope-host,
.rhw-rope-host{
  position: absolute;
  inset-inline: 0;
  inset-block-start: 0;
  block-size: 0;
  margin: 0;
  padding: 0;
  pointer-events: none;
}

/* Left where the rope used to be, so its measurements keep their meaning. It
   is out of the flow itself, or it would leave behind the very gap the rope
   was taken out of the flow to avoid. */
.rhw-rope-mark{
  position: absolute;
  inline-size: 0;
  block-size: 0;
  margin: 0;
  padding: 0;
  pointer-events: none;
}

/*
 * The rope is two layers, and it has to be.
 *
 * The strand itself is drawn on an inner layer because it is masked — faded at
 * the top, at the bottom, or both — and a mask cuts away everything painted
 * outside the box it is on. Whoever is climbing the rope is far wider than the
 * rope, so on the same layer they were being sliced down to the width of the
 * strand. On their own layer they hang over it freely.
 */
.rhw-rope{
  position: absolute;
  inset-block-start: var(--rhw-rope-top, 120px);
  inline-size: var(--rhw-rope-w, 60px);
  block-size: var(--rhw-rope-h, 1400px);
  z-index: var(--rhw-rope-z, 1);
  pointer-events: none;

  /* Turned from where it hangs, the way a real rope would be. */
  transform-origin: top center;
  rotate: var(--rhw-rope-tilt, 0deg);
  /* Set by the script only when the rope, or whoever is on it, would otherwise
     have hung off the side of a narrow window. */
  translate: var(--rhw-rope-fit, 0px) 0;

  /*
   * One number shrinks the whole thing at once — strand, length, whoever is on
   * it, and every nudge that placed them — so a rope tuned on a wide screen
   * keeps its proportions on a narrow one instead of towering over the page.
   * Scaled from the point it hangs from, so it stays hanging where it was put.
   */
  scale: var(--rhw-rope-k, 1);
}

.rhw-rope-line{
  position: absolute;
  inset: 0;
  opacity: var(--rhw-rope-op, 1);

  background-image: var(--rhw-rope-img);
  /* Its own width decides the scale, and it carries on repeating down — so the
     picture is never stretched no matter how long the rope is asked to be. */
  background-size: 100% auto;
  background-repeat: repeat-y;
  background-position: top center;
}

.rhw-rope--start{ inset-inline-start: var(--rhw-rope-side, 40px); }
.rhw-rope--end  { inset-inline-end:   var(--rhw-rope-side, 40px); }

/*
 * Kept clear of the reading column.
 *
 * A distance measured from the edge of the screen is a different distance on
 * every screen, and on a narrow one it lands on the words. Measured from the
 * middle instead, the rope always stands the same gap outside the column,
 * whatever the screen is; and when the screen runs out of margin the rope has
 * no room left, so it narrows to nothing and takes itself off the page rather
 * than crossing it.
 */
.rhw-rope--clear{
  /* A tilt of a single degree over a rope four thousand pixels long carries its
     foot the better part of a hundred pixels sideways, and the climber hanging
     on it is far wider than the rope. Both are counted here, so what is kept
     clear of the column is everything the widget actually draws, not the thin
     line at the middle of it. */
  --rhw-rope-lean: max(
    calc( var(--rhw-rope-h, 1400px) * tan(var(--rhw-rope-tilt, 0deg)) ),
    calc( -1 * var(--rhw-rope-h, 1400px) * tan(var(--rhw-rope-tilt, 0deg)) )
  );
  /*
   * How far the widest thing on the rope sticks out to the side. The rider is
   * wider than the rope and is nudged sideways to line its own painted rope up
   * with this one, so the nudge counts too: nudged left, it reaches further
   * left, and that is the edge the clearance has to keep off the content.
   */
  --rhw-rider-shift: max( calc(-1 * var(--rhw-rider-nudge, 0px)), var(--rhw-rider-nudge, 0px) );
  --rhw-rope-reach: max(
    calc(var(--rhw-rope-w, 60px) / 2),
    calc(var(--rhw-rider-w, 0px) / 2 + var(--rhw-rider-shift))
  );
  --rhw-rope-room: max(0px, calc(50% - var(--rhw-rope-hold, 600px) - var(--rhw-rope-gap, 24px)));
}
.rhw-rope--clear.rhw-rope--start{
  inset-inline-start: max(calc(var(--rhw-rope-reach) - calc(var(--rhw-rope-w, 60px) / 2)), calc(var(--rhw-rope-room) - var(--rhw-rope-reach) - var(--rhw-rope-lean) - calc(var(--rhw-rope-w, 60px) / 2)));
}
.rhw-rope--clear.rhw-rope--end{
  inset-inline-end: max(calc(var(--rhw-rope-reach) - calc(var(--rhw-rope-w, 60px) / 2)), calc(var(--rhw-rope-room) - var(--rhw-rope-reach) - var(--rhw-rope-lean) - calc(var(--rhw-rope-w, 60px) / 2)));
}

/* Fixed to the screen rather than to the page. The insets mean the same thing;
   they are just measured against the window now. */
.rhw-rope--screen{ position: fixed; }

/* One length of picture, stretched to the rope's length instead of repeating. */
.rhw-rope--once .rhw-rope-line{ background-size: 100% 100%; background-repeat: no-repeat; }

/* Only the strand turns round; whoever is on it is left facing as they were. */
.rhw-rope--flip .rhw-rope-line{ scale: -1 1; }

/*
 * Not cut off at the end but lost into the page. Both spellings are given
 * because Safari still wants the prefixed one.
 */
.rhw-rope-line{
  --rhw-rope-mask: linear-gradient(to bottom,
    transparent 0,
    #000 var(--rhw-rope-fade-top, 0%),
    #000 calc(100% - var(--rhw-rope-fade, 0%)),
    transparent 100%);
  -webkit-mask-image: var(--rhw-rope-mask);
  mask-image: var(--rhw-rope-mask);
}

.rhw-rope--fx-grey      .rhw-rope-line{ filter: grayscale(1); }
.rhw-rope--fx-grey-soft .rhw-rope-line{ filter: grayscale(.5); }
.rhw-rope--fx-dark      .rhw-rope-line{ filter: brightness(.7); }
.rhw-rope--fx-light     .rhw-rope-line{ filter: brightness(1.25); }
.rhw-rope--fx-warm      .rhw-rope-line{ filter: sepia(.35) saturate(1.2); }
.rhw-rope--fx-cool      .rhw-rope-line{ filter: hue-rotate(180deg) saturate(.8); }

/*
 * The sway is a transform and the tilt is the separate `rotate` property, so
 * the two compose instead of one wiping out the other — a tilted rope sways
 * around its tilt rather than snapping upright.
 */
@keyframes rhw-rope-sway{
  0%, 100%{ transform: rotate(calc(-1deg * var(--rhw-rope-swing, 1))); }
  50%     { transform: rotate(calc(1deg * var(--rhw-rope-swing, 1))); }
}
.rhw-rope--sway{
  animation: rhw-rope-sway var(--rhw-rope-swing-time, 9s) ease-in-out infinite;
}

/*
 * Held still while it is being measured.
 *
 * The script sets the three turns of the swing one after another and reads
 * what is drawn at each, so for those few lines the rope must be exactly where
 * it is put and nowhere else. The transition goes with the animation: the
 * correction is written while the rope is held, and it is to be in force the
 * moment it is let go, not sliding towards it afterwards.
 */
.rhw-rope--hold{
  animation: none !important;
  transition: none !important;
}

/* ------------------------------------------------------------ on the rope -- */

/*
 * Inside the rope rather than beside it, so the sway and the tilt carry the
 * figure with them — a climber that stayed upright while the rope moved would
 * give the whole thing away.
 */
.rhw-rope-rider{
  position: absolute;
  inset-block-start: var(--rhw-rider-at, 60%);
  /*
   * `left`, not `inset-inline-start`. On a right-to-left page the logical
   * property measures from the other edge, so the box's far side lands on the
   * middle and the -50% below pushes it a whole width clear of the strand. The
   * nudge underneath is a distance across the picture, and the picture does not
   * turn round with the page, so both have to be read the same way in either
   * direction.
   */
  left: 50%;
  inline-size: var(--rhw-rider-w, 260px);
  /*
   * Held by the top of the picture, not its middle. What is at the top of a
   * picture of someone on a rope is the rope they are holding — so "how far
   * down" now means where that end of their rope meets this one, and a
   * hundred per cent lands it exactly on the foot of the strand. Held by the
   * middle, as it was, the join could never be made: half the figure always
   * sat past wherever it was aimed.
   */
  translate: calc(-50% + var(--rhw-rider-nudge, 0px)) var(--rhw-rider-lift, 0px);
  /* Turned about its own middle, on top of whatever tilt the rope itself has,
     so a rope drawn inside the picture can be laid along the rope on the page. */
  rotate: var(--rhw-rider-turn, 0deg);
}
/*
 * On a right-to-left page the whole design is mirrored, and the rope with it.
 * The nudge is what lays the rope drawn inside the picture along the rope on
 * the page, so when the page turns round the nudge has to turn round too, or
 * the figure leans away from the strand instead of onto it. One rule, one
 * setting, and the same widget serves both languages.
 */
[dir="rtl"] .rhw-rope-rider{
  translate: calc(-50% - var(--rhw-rider-nudge, 0px)) var(--rhw-rider-lift, 0px);
}

.rhw-rope-rider img{
  display: block;
  inline-size: 100%;
  block-size: auto;
}
.rhw-rope-rider--flip{ scale: -1 1; }

@media (prefers-reduced-motion: reduce){
  .rhw-rope{ animation: none; }
}

/* ---------------------------------------------------------- in the editor -- */

/* It has to be reachable, or there is no way to select it. */
.elementor-editor-active .rhw-rope-host,
.elementor-editor-active .rhw-rope{ pointer-events: auto; }

/*
 * Elementor draws a grey bar wherever a widget takes up no room, so an empty
 * one can still be found and clicked. This one takes up no room on purpose —
 * that is the whole point of it — and the bar was pushing everything below it
 * down and making the page being built look nothing like the page. So the bar
 * is turned off here, and the rope is left clickable in its place: clicking the
 * rope selects the widget, which is what the bar was for.
 */
.elementor-editor-active .elementor-widget-robinhood-rope,
.elementor-editor-active .elementor-widget-robinhood-rope.elementor-widget-empty{
  min-height: 0 !important;
  padding: 0 !important;
  background: none !important;
}
.elementor-editor-active .elementor-widget-robinhood-rope > .elementor-widget-empty-icon{
  display: none !important;
}

/* ============================================================== body map == */

.rhw-map{
  display: flex;
  align-items: flex-start;
  gap: 3rem;

  /* How one panel gives way to the next, before anybody has said otherwise:
     one fades into the other, over however long the change beside it takes,
     with neither of them travelling. Movement is asked for, not assumed. */
  --rhw-card-far: 14;
  --rhw-card-time: var(--rhw-map-ease, .35s);
  --rhw-card-wait: 0s;
}

/*
 * The figure and whatever is written under it stand in one column, so the line
 * sits under its feet without stretching the picture — every region is measured
 * in hundredths of that picture, and a taller box would move all of them.
 */
.rhw-map-side{
  inline-size: var(--rhw-map-fig, 45%);
  flex: 0 0 auto;
}
.rhw-map-caption{
  margin: 14px 0 0;
  text-align: center;
  line-height: 1.5;
}

.rhw-map-figure{
  position: relative;
  inline-size: 100%;
  line-height: 0;

  /*
   * Reading the figure means pressing and moving across it, which is also how
   * a browser is asked to select things and to drag a picture away. Neither is
   * wanted here, and either leaves a coloured block over the body.
   */
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}
.rhw-map-figure img{
  -webkit-user-drag: none;
  user-select: none;
  -webkit-user-select: none;
  pointer-events: none;
}

/*
 * Two pictures, and the top one is the one that gets cut.
 *
 * A hole opens in the picture on top wherever the reader is looking, and what
 * shows through it is the picture below. Laying the lower picture over the
 * upper one instead would leave the statue showing through wherever the
 * skeleton is transparent — which is not what a scan looks like.
 */
.rhw-map-below{
  position: absolute;
  inset: 0;
}
.rhw-map-under{
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: contain;
}

.rhw-map-over{
  position: relative;
  display: block;
  inline-size: 100%;
  block-size: auto;
  transition: filter var(--rhw-map-ease, .35s) ease;
}
.rhw-map.is-live .rhw-map-over{ filter: brightness(var(--rhw-map-dim, 1)); }

/*
 * The picture underneath is the body alone, clear all round it. Repeating the
 * upper picture behind it means that inside the opening, away from the body,
 * the room simply carries on — while on the body itself the lower picture is
 * opaque and nothing of the upper one is left.
 */
.rhw-map-ghost{
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: contain;
}

/* ------------------------------------------------------- living cluster ---- */

/*
 * An opening that is alive. Its outline changes on every frame, so it cannot be
 * written as a gradient — the picture underneath is painted onto a canvas, cut
 * to the cluster, and laid over the picture on top.
 *
 * The canvas is only as big as the opening and is moved about the figure, not
 * stretched across it. A canvas covering a tall figure is several million dots
 * handed to the screen on every frame, which is what made the movement come in
 * steps rather than a slide.
 */
.rhw-map-ink{
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  display: none;
  pointer-events: none;
  z-index: 3;
  transform-origin: 0 0;
  will-change: transform;
}
/* Only a drawing source — what is seen of it is drawn on the canvas. */
.rhw-map--cluster .rhw-map-under{ visibility: hidden; }

/* ------------------------------------------------------------ the scan ---- */

/*
 * A band that follows the pointer down the body, solid at its edges and clear
 * through the middle, so the hole travels with the reader. The bright line is
 * a separate strip drawn over the join, which is what makes it read as an
 * instrument passing over rather than a picture fading.
 */
.rhw-map--scan .rhw-map-over{
  --rhw-map-cut: linear-gradient(to bottom,
    #000 0,
    #000 calc(var(--rhw-map-py, -9999px) - var(--rhw-map-band, 120px)),
    transparent calc(var(--rhw-map-py, -9999px) - var(--rhw-map-band, 120px) * .35),
    transparent calc(var(--rhw-map-py, -9999px) + var(--rhw-map-band, 120px) * .35),
    #000 calc(var(--rhw-map-py, -9999px) + var(--rhw-map-band, 120px)),
    #000 100%);
}
.rhw-map--scan.rhw-map--across .rhw-map-over{
  --rhw-map-cut: linear-gradient(to right,
    #000 0,
    #000 calc(var(--rhw-map-px, -9999px) - var(--rhw-map-band, 120px)),
    transparent calc(var(--rhw-map-px, -9999px) - var(--rhw-map-band, 120px) * .35),
    transparent calc(var(--rhw-map-px, -9999px) + var(--rhw-map-band, 120px) * .35),
    #000 calc(var(--rhw-map-px, -9999px) + var(--rhw-map-band, 120px)),
    #000 100%);
}

.rhw-map-beam{
  position: absolute;
  inset-inline: 0;
  inset-block-start: var(--rhw-map-py, -9999px);
  block-size: var(--rhw-map-line-w, 2px);
  translate: 0 -50%;
  background: var(--rhw-map-line, #fff);
  box-shadow: 0 0 var(--rhw-map-line-glow, 14px) var(--rhw-map-line, #fff);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--rhw-map-ease, .35s) ease;
}
.rhw-map--across .rhw-map-beam{
  inset-inline: auto;
  inset-block: 0;
  inset-inline-start: var(--rhw-map-px, -9999px);
  inline-size: var(--rhw-map-line-w, 2px);
  block-size: auto;
  translate: -50% 0;
}
.rhw-map.is-live .rhw-map-beam{ opacity: 1; }

/* ------------------------------------------------- the other ways to cut -- */

/* The region being read: its own shape, softly edged. */
.rhw-map--zone .rhw-map-over{
  --rhw-map-cut: radial-gradient(
    ellipse var(--rhw-map-zw, 0%) var(--rhw-map-zh, 0%)
    at var(--rhw-map-zx, -50%) var(--rhw-map-zy, -50%),
    transparent 0,
    transparent calc(100% - var(--rhw-map-soft, 60%)),
    #000 100%);
}

/* A round window under the pointer. */
.rhw-map--pointer .rhw-map-over{
  --rhw-map-cut: radial-gradient(
    circle var(--rhw-map-r, 200px)
    at var(--rhw-map-px, -9999px) var(--rhw-map-py, -9999px),
    transparent 0,
    transparent calc(100% - var(--rhw-map-soft, 60%)),
    #000 100%);
}

.rhw-map--scan .rhw-map-over,
.rhw-map--zone .rhw-map-over,
.rhw-map--pointer .rhw-map-over{
  -webkit-mask-image: var(--rhw-map-cut);
  mask-image: var(--rhw-map-cut);
}

/*
 * A shape of the reader's own. The picture on top is masked by itself minus
 * that shape, so wherever the shape is solid the top picture is gone — which
 * is the same hole, cut to whatever outline was supplied.
 */
.rhw-map--image .rhw-map-over{
  -webkit-mask-image: linear-gradient(#000, #000), var(--rhw-map-mask-img);
  mask-image: linear-gradient(#000, #000), var(--rhw-map-mask-img);
  -webkit-mask-size: 100% 100%, var(--rhw-map-mask-size, 280px) auto;
  mask-size: 100% 100%, var(--rhw-map-mask-size, 280px) auto;
  -webkit-mask-position:
    0 0,
    calc(var(--rhw-map-px, -9999px) - var(--rhw-map-mask-size, 280px) / 2)
    calc(var(--rhw-map-py, -9999px) - var(--rhw-map-mask-size, 280px) / 2);
  mask-position:
    0 0,
    calc(var(--rhw-map-px, -9999px) - var(--rhw-map-mask-size, 280px) / 2)
    calc(var(--rhw-map-py, -9999px) - var(--rhw-map-mask-size, 280px) / 2);
  -webkit-mask-repeat: no-repeat, no-repeat;
  mask-repeat: no-repeat, no-repeat;
  -webkit-mask-composite: xor;
  mask-composite: exclude;
}

/* --------------------------------------------------------- the regions ---- */

/*
 * Never drawn — only where the pointer is listened for. The dotted outline is
 * for placing them and nothing else.
 */
.rhw-map-zones{
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  overflow: visible;
}
.rhw-map-zones ellipse,
.rhw-map-zones rect{
  fill: transparent;
  stroke: none;
  pointer-events: all;
  cursor: pointer;
}
/*
 * A click must not leave a ring behind.
 *
 * A region and a marker are both things a browser can put focus on, and having
 * been clicked it draws its own focus ring around them — which on a shape the
 * size of a waist is a thick blue band with a white edge sitting across the
 * body. Keyboard users still get a ring; a mouse no longer asks for one.
 */
.rhw-map .rhw-map-zones ellipse:focus,
.rhw-map .rhw-map-zones rect:focus,
.rhw-map .rhw-map-zones:focus,
.rhw-map .rhw-map-pin:focus{
  outline: none;
}
.rhw-map .rhw-map-zones ellipse:focus-visible,
.rhw-map .rhw-map-zones rect:focus-visible,
.rhw-map .rhw-map-pin:focus-visible{
  outline: 2px solid var(--rhw-map-pin-ring, rgba(255,255,255,.8));
  outline-offset: 3px;
}

.rhw-map--outline .rhw-map-zones ellipse,
.rhw-map--outline .rhw-map-zones rect{
  stroke: rgba(255,255,255,.5);
  stroke-width: 1;
  stroke-dasharray: 3 3;
  vector-effect: non-scaling-stroke;
}

/* --------------------------------------------------------------- marks ---- */

/*
 * On the lower picture by default, so a marker is seen only where the hole has
 * opened onto it — a note written on the skeleton, not on the statue.
 */
.rhw-map-pins{
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
}
/*
 * A marker is shown only for the region being read, which is the region the
 * opening is standing on — a note appearing where the instrument has reached.
 * Turned off, every marker is shown at once.
 */
.rhw-map .rhw-map-pin{
  opacity: 0;
  pointer-events: none;
}
.rhw-map .rhw-map-pin.is-on,
.rhw-map--pins-always .rhw-map-pin{
  opacity: 1;
  pointer-events: auto;
}

/*
 * On a screen read with a finger every marker is shown, because they are the
 * only thing there is to take hold of. The button is grown to something a
 * finger can find while the dot inside it keeps the size it was given.
 */
.rhw-map.is-touch .rhw-map-pin{
  opacity: 1;
  pointer-events: auto;
  inline-size: max(26px, var(--rhw-map-pin, 12px));
  block-size: max(26px, var(--rhw-map-pin, 12px));
}
.rhw-map.is-touch .rhw-map-dot{
  inset: calc((100% - var(--rhw-map-pin, 12px)) / 2);
}
.rhw-map.is-touch .rhw-map-pin::before{
  inset: calc((100% - var(--rhw-map-pin, 12px)) / 2 - var(--rhw-map-halo, 12px));
}
.rhw-map.is-touch .rhw-map-pin::after{
  inset: calc((100% - var(--rhw-map-pin, 12px)) / 2 - 2px);
}

/*
 * While the page is being built, every marker, every name and every region
 * shape is shown at once. On the finished page a marker appears only where the
 * opening has reached, which leaves nothing to aim at when placing them.
 */
.elementor-editor-active .rhw-map .rhw-map-pin{ opacity: 1; pointer-events: auto; }
.elementor-editor-active .rhw-map .rhw-map-pin-name{ opacity: 1; }
.elementor-editor-active .rhw-map-zones ellipse,
.elementor-editor-active .rhw-map-zones rect{
  fill: rgba(125,125,125,.16);
  stroke: rgba(255,255,255,.7);
  stroke-width: 1;
  stroke-dasharray: 4 3;
  vector-effect: non-scaling-stroke;
}

.rhw-map .rhw-map-pin{
  position: absolute;
  inset-block-start: var(--rhw-map-py-pin, 50%);
  /* Measured from the left edge, always. The number is a place on a picture
     of a body, and the picture does not turn round when the page is read from
     the right. Written as inset-inline-start it did turn round, and every
     marker on the Persian site landed on the opposite side of the figure. */
  left: var(--rhw-map-px-pin, 50%);
  translate: -50% -50%;
  inline-size: var(--rhw-map-pin, 12px);
  block-size: var(--rhw-map-pin, 12px);
  min-inline-size: 0;
  min-block-size: 0;
  max-inline-size: none;
  padding: 0;
  margin: 0;
  border: 0;
  border-radius: 50%;
  background: var(--rhw-map-pin-bg, #fff);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--rhw-map-pin-bg, #fff) 30%, transparent);
  font-size: 0;
  line-height: 0;
  pointer-events: auto;
  cursor: pointer;
  appearance: none;
  transition: background var(--rhw-map-ease, .35s) ease,
              scale var(--rhw-map-ease, .35s) ease,
              opacity var(--rhw-map-ease, .35s) ease;
}
.rhw-map .rhw-map-pin:hover,
.rhw-map .rhw-map-pin.is-on{
  scale: 1.35;
}

/*
 * The dot itself, painted after the glow behind it. As the button's own colour
 * it was drawn first and the glow went over the top of it, so a white marker
 * came out the colour of its glow.
 */
.rhw-map .rhw-map-dot{
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--rhw-map-pin-bg, #fff);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--rhw-map-pin-bg, #fff) 30%, transparent);
  transition: background var(--rhw-map-ease, .35s) ease;
  pointer-events: none;
}
.rhw-map .rhw-map-pin:hover .rhw-map-dot,
.rhw-map .rhw-map-pin.is-on .rhw-map-dot{
  background: var(--rhw-map-pin-on, var(--rhw-map-pin-bg, #fff));
}

/*
 * A region can ask for nothing to be shown. The marker keeps its place and
 * still answers the pointer — it is simply not painted, so a spot like the eyes
 * can be reached without anything sitting on the face.
 */
.rhw-map .rhw-map-pin.is-blank{
  background: none;
  box-shadow: none;
  scale: 1;
}
.rhw-map .rhw-map-pin.is-blank .rhw-map-dot{ display: none; }
.rhw-map .rhw-map-pin.is-blank::before,
.rhw-map .rhw-map-pin.is-blank::after{ content: none; }

/*
 * A marker is two things beyond the dot: a glow that stays with it, and a
 * ripple that leaves it and fades. Between them a marker reads as something
 * live standing on the body rather than a full stop printed on it.
 */
.rhw-map .rhw-map-pin::before{
  content: "";
  position: absolute;
  inset: calc(var(--rhw-map-halo, 12px) * -1);
  border-radius: 50%;
  /* Solid to the middle of it, then out to nothing. Where that fading starts
     is what makes the same colour read as a disc or as a breath of smoke. */
  background: radial-gradient(closest-side,
    var(--rhw-map-pin-halo, rgba(196,124,255,.55)) 0,
    var(--rhw-map-pin-halo, rgba(196,124,255,.55)) calc((100 - var(--rhw-map-halo-soft, 85)) * 1%),
    transparent 100%);
  opacity: calc(var(--rhw-map-halo-ink, 100) / 100);
  pointer-events: none;
}
.rhw-map--pulse .rhw-map-pin::before{
  animation: rhw-map-swell var(--rhw-map-beat-time, 2.6s) ease-in-out infinite;
}

.rhw-map .rhw-map-pin::after{
  content: "";
  position: absolute;
  inset: -2px;
  border-radius: 50%;
  border: 1px solid var(--rhw-map-pin-ring, rgba(196,124,255,.75));
  opacity: 0;
  pointer-events: none;
}
.rhw-map--pulse .rhw-map-pin::after{
  animation: rhw-map-breathe var(--rhw-map-beat-time, 2.6s) ease-out infinite;
}
.rhw-map--pulse .rhw-map-pin.is-on::after{ animation: none; opacity: 0; }

@keyframes rhw-map-breathe{
  0%   { opacity: .85; scale: 1; }
  70%  { opacity: 0;   scale: var(--rhw-map-far, 2.8); }
  100% { opacity: 0;   scale: var(--rhw-map-far, 2.8); }
}
@keyframes rhw-map-swell{
  0%, 100% { scale: 1; opacity: calc(var(--rhw-map-halo-ink, 100) / 100 * .72); }
  50%      { scale: calc(1 + var(--rhw-map-beat, 35) / 100);
             opacity: calc(var(--rhw-map-halo-ink, 100) / 100); }
}
@media (prefers-reduced-motion: reduce){
  .rhw-map--pulse .rhw-map-pin::after,
  .rhw-map--pulse .rhw-map-pin::before{ animation: none; }
}

/*
 * The names ride in a layer of their own, above both pictures. Kept inside the
 * marker they were drawn under the upper picture along with it, so the half of
 * a name that crossed the body vanished behind the statue.
 */
.rhw-map-tags{
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
}

.rhw-map .rhw-map-pin-name{
  position: absolute;
  inset-block-start: var(--rhw-map-py-pin, 50%);
  left: var(--rhw-map-px-pin, 50%);
  translate: calc(var(--rhw-map-pin, 12px) / 2 + .55em) -50%;
  padding: .25em .6em;
  border-radius: 999px;
  background: rgba(0,0,0,.55);
  color: #fff;
  font-size: 12px;
  line-height: 1.6;
  white-space: nowrap;
  opacity: 0;
  transition: opacity var(--rhw-map-ease, .35s) ease;
  pointer-events: none;
}
/* A name in the far half of the picture reads back the other way, or it would
   hang off the frame. */
.rhw-map .rhw-map-pin-name.is-far{
  translate: calc(-100% - var(--rhw-map-pin, 12px) / 2 - .55em) -50%;
}
.rhw-map--names-always .rhw-map-pin-name{ opacity: 1; }
.rhw-map--names-never  .rhw-map-pin-name{ display: none; }
.rhw-map .rhw-map-pin-name.is-on{ opacity: 1; }

/* --------------------------------------------------------------- panel ---- */

/*
 * Every panel occupies the same cell, so the panel is as tall as its tallest
 * one from the first frame and nothing below it moves as the reader goes from
 * region to region. Swapping them by taking one out of the page and putting
 * another in is what made the picture jump.
 */
/*
 * The panel is as tall as whatever region is open, and no taller.
 *
 * A container outside this widget can be set to stretch what is inside it,
 * which Elementor passes down as a custom property every widget reads for its
 * own height. Inside a panel that takes its height from its contents that is a
 * circle — the contents ask the panel how tall it is while the panel is asking
 * them — and the browser answers with a page that grows by a factor on every
 * pass until it is hundreds of thousands of pixels tall. The chain is cut here:
 * inside the panel, a widget is as tall as what it holds.
 */
.rhw-map-panel{
  display: grid;

  /* Takes the room left beside the figure and asks its contents for nothing.
     Sized from its contents instead, anything inside it that is measured
     against the panel would be measuring itself. */
  flex: 1 1 0;
  min-inline-size: 0;
  min-block-size: 0;

  --container-widget-height: auto;
  --container-widget-width: 100%;
  --container-widget-flex-grow: 0;
}
/*
 * The panel takes the height a control gives it. Unset it is the tallest card,
 * which is what a grid of stacked cards comes to on its own; set to the
 * measured height of the card being shown, the empty room under a short card
 * goes away. The change is eased so a taller card does not snap the page.
 */
.rhw-map-panel{
  block-size: var(--rhw-panel-fit, auto);
  transition: block-size var(--rhw-card-time, .35s) var(--rhw-card-curve, cubic-bezier(.22,.61,.36,1));
}
@media (prefers-reduced-motion: reduce){
  .rhw-map-panel{ transition: none; }
}
.rhw-map-panel .elementor-widget,
.rhw-map-panel .elementor-widget-container{ height: auto; }
.rhw-map-panel .rhw-map-card{ min-inline-size: 0; }

/* Narrow screens.
 *
 * The cards are stacked in one cell and the ones not being shown wait a little
 * to one side, which is where they slide in from. They are invisible, but they
 * are still laid out, and off the side of a phone that means the whole page can
 * be dragged sideways to a strip of nothing. Below the point where the page
 * stops being one zoomed design, the stack is clipped to its own width: the
 * card still arrives from the side, it is simply not allowed to widen the page
 * on its way in.
 */
/*
 * Nothing scrolls sideways below the point where the page stops being one
 * zoomed design.
 *
 * A phone or a tablet that can be dragged sideways to a strip of nothing is
 * always a fault, and it is caused by things that are laid out off the side
 * while being drawn somewhere else entirely: a carousel's slides waiting their
 * turn, a caption hung on the middle of a small figure, a card parked to one
 * side ready to slide in. Each of those is worth fixing where it stands, and
 * the ones we own are fixed above. This is the floor under all of them, so a
 * widget we do not own cannot widen the page either.
 *
 * `clip` rather than `hidden`: hidden would make the page a scroll container
 * and quietly break anything sticky inside it. Above 1024 nothing is said,
 * because there the page is one fixed design that is only scaled.
 */
@media (max-width: 1024px){
  html{ overflow-x: clip; }
}

/* A slide is a picture beside a column of writing. Below the point where the
 * page stops being one zoomed design there is no room for both, so the row is
 * allowed to wrap: give the picture and the writing a full width each in the
 * panel and they take a line each instead of squeezing into one. */
@media (max-width: 1024px){
  .rhw-slide{ flex-wrap: wrap; }
}

/* A row of figures on a phone.
 *
 * Ten figures sharing 370px leaves each of them 30px wide, which is a row of
 * slivers rather than a row of people. Below the point where the page stops
 * being one zoomed design the row keeps them at a readable size and scrolls
 * sideways instead, which is what a phone does with a row that is longer than
 * the screen. The scrollbar is hidden because the figures themselves say the
 * row continues.
 *
 * Only where the caption stands under or over the whole row: those are the
 * two arrangements that keep it in the flow. Where the caption is hung on one
 * figure it sits outside the row's own box, and a row that scrolls would cut
 * it off.
 */
@media (max-width: 1024px){
  .rhw-strip--below .rhw-strip-row,
  .rhw-strip--above .rhw-strip-row{
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
  }

  .rhw-strip--below .rhw-strip-row::-webkit-scrollbar,
  .rhw-strip--above .rhw-strip-row::-webkit-scrollbar{ display: none; }

  /* A width of their own, because the height control cannot reach them: an
     Elementor rule sets every picture in a widget to `height: auto` and beats
     it. Until that is untangled the figure is sized across instead, and the
     picture follows. */
  .rhw-strip--below .rhw-strip-one,
  .rhw-strip--above .rhw-strip-one{
    flex: 0 0 auto;
    inline-size: 88px;
  }

  .rhw-strip--below .rhw-strip-img,
  .rhw-strip--above .rhw-strip-img{
    inline-size: 100%;
    block-size: auto;
  }
}

@media (min-width: 768px) and (max-width: 1024px){
  .rhw-strip--below .rhw-strip-one,
  .rhw-strip--above .rhw-strip-one{ inline-size: 120px; }
}

@media (max-width: 1024px){
  .rhw-map-panel{ overflow-x: clip; }


  /* A pin's name is one unbroken line beside its dot. Beside a dot near the
     edge of a phone that line leaves the page. It is allowed to break here and
     kept to a share of the screen, which is the only thing that can be said
     about a box hung on a point rather than on a container. */
  .rhw-map .rhw-map-pin-name{
    white-space: normal;
    max-inline-size: 42vw;
  }
}

/* Under the figure rather than beside it, the panel has to be as tall as the
 * card it is holding. `flex: 1 1 0` with a floor of nothing is what lets it
 * take the room left over in a row; in a column it means it takes no room at
 * all, and the card spills out of the widget and lands on whatever the
 * section put after it. This is said only where the widget has actually
 * stacked: said in a row it would size the panel to its widest card instead
 * of to the space beside the figure, which is thousands of pixels of card
 * squeezed off the side.
 */
@media (max-width: 767px){
  .rhw-map-panel{
    flex: 0 0 auto;
    min-block-size: auto;
  }
}

/*
 * One panel giving way to the next.
 *
 * The panels are stacked in one cell, so a plain cross-fade has them dissolve
 * through each other in the same place and reads as nothing having moved. Here
 * the one arriving comes from somewhere and the one leaving goes the other way,
 * which is what makes it a change rather than a swap. Where it came from is
 * held on the card at rest; where the last one went is put on it by hand for as
 * long as the leaving takes, since the stylesheet cannot know which way a card
 * is travelling on its own.
 */
.rhw-map-card{
  grid-area: 1 / 1;
  opacity: 0;
  visibility: hidden;
  translate: var(--rhw-card-in-x, 0px) var(--rhw-card-in-y, 0px);
  scale: var(--rhw-card-in-s, 1);
  filter: blur(var(--rhw-card-in-b, 0px));
  transition:
    opacity    var(--rhw-card-time, .45s) var(--rhw-card-curve, cubic-bezier(.22,.61,.36,1)),
    translate  var(--rhw-card-time, .45s) var(--rhw-card-curve, cubic-bezier(.22,.61,.36,1)),
    scale      var(--rhw-card-time, .45s) var(--rhw-card-curve, cubic-bezier(.22,.61,.36,1)),
    filter     var(--rhw-card-time, .45s) var(--rhw-card-curve, cubic-bezier(.22,.61,.36,1)),
    visibility 0s linear var(--rhw-card-time, .45s);
}

/* On its way out, and going the other way. It never waits its turn. */
.rhw-map-card.is-going{
  translate: var(--rhw-card-out-x, 0px) var(--rhw-card-out-y, 0px);
  scale: var(--rhw-card-out-s, 1);
  filter: blur(var(--rhw-card-out-b, 0px));
  transition-delay: 0s, 0s, 0s, 0s, var(--rhw-card-time, .45s);
}

.rhw-map-card.is-on{
  opacity: 1;
  visibility: visible;
  translate: 0px 0px;
  scale: 1;
  filter: blur(0px);
  transition:
    opacity    var(--rhw-card-time, .45s) var(--rhw-card-curve, cubic-bezier(.22,.61,.36,1)) var(--rhw-card-wait, .08s),
    translate  var(--rhw-card-time, .45s) var(--rhw-card-curve, cubic-bezier(.22,.61,.36,1)) var(--rhw-card-wait, .08s),
    scale      var(--rhw-card-time, .45s) var(--rhw-card-curve, cubic-bezier(.22,.61,.36,1)) var(--rhw-card-wait, .08s),
    filter     var(--rhw-card-time, .45s) var(--rhw-card-curve, cubic-bezier(.22,.61,.36,1)) var(--rhw-card-wait, .08s),
    visibility 0s;
}

@media (prefers-reduced-motion: reduce){
  .rhw-map-card,
  .rhw-map-card.is-going,
  .rhw-map-card.is-on{ translate: none; scale: 1; filter: none; }
}

.rhw-map-anat{
  display: block;
  inline-size: 100%;
  block-size: auto;
  margin-block-end: 1.25rem;
}
.rhw-map-name{ margin: 0 0 .4rem; }
.rhw-map-note{ margin: 0 0 1.25rem; }

.rhw-map-products{
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: .5rem;
}
/*
 * A line between one product and the next.
 *
 * Drawn on the row rather than under it, so the last row has none — a list
 * that ends on a line looks unfinished.
 */
.rhw-map-product + .rhw-map-product{
  position: relative;
  padding-block-start: var(--rhw-rule-room, 0px);
}

/*
 * The line is drawn on a piece of its own rather than on the row, so it can be
 * shorter than the row and stand where it is put — left, middle or right.
 */
.rhw-map-product + .rhw-map-product::before{
  content: '';
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  inline-size: var(--rhw-rule-len, 100%);
  margin-inline: var(--rhw-rule-pull, 0 auto);
  block-size: var(--rhw-rule-w, 1px);
  background-image: var(--rhw-rule-img, none);
  background-size: var(--rhw-rule-size, 100% var(--rhw-rule-w, 1px));
  background-repeat: repeat-x;
}

.rhw-map-product .rhw-map-product-face{
  display: flex;
  /*
   * Which side the picture sits on is a control, and two of its four answers
   * stand the row up as a column. A column needs more than a direction: the
   * writing has to take the whole width instead of a share of it, and the
   * pieces that were lined up along a row have to line up about a centre.
   * Those follow the direction through these four variables, which the same
   * control sets in the same breath.
   */
  flex-direction: var(--rhw-row-dir, row);
  align-items: center;
  gap: var(--rhw-shot-gap, 1rem);
  padding: .5rem;
  border-radius: 10px;
  text-decoration: none;
  color: inherit;
  transition: background var(--rhw-map-ease, .35s) ease;
}
/*
 * A row that can be opened says so under the pointer.
 *
 * Nothing here moves the row sideways or changes its width: the codes stand in
 * a column down the list, and a row that shifted as it was pointed at would
 * take its code out of that column and put it back on the way out. So the row
 * answers where it can — a plate behind it, the name lighting, and the picture
 * coming forward a little — and the column is left alone.
 *
 * A row that opens nothing answers nothing. It keeps the shape of the others
 * and simply is not a thing to click.
 */
.rhw-map-product a.rhw-map-product-face{
  transition: background var(--rhw-row-time, .25s) ease,
              box-shadow var(--rhw-row-time, .25s) ease;
}

.rhw-map-product a.rhw-map-product-face:hover{
  background: var(--rhw-row-bg, rgba(127,127,127,.12));
  box-shadow: inset 0 0 0 var(--rhw-row-line-w, 0px) var(--rhw-row-line, transparent);
}

/*
 * The name keeps its own colour unless a colour is asked for.
 *
 * Written here with a fallback, any fallback, this rule took the name's colour
 * away and gave it the row's — and the row is a link, which a theme paints. So
 * the colour under the pointer is not written here at all: the setting writes
 * its own rule, and where nothing is set there is no rule and nothing changes.
 */
.rhw-map-product a.rhw-map-product-face:hover .rhw-map-product-name{
  text-underline-offset: .18em;
}

.rhw-map-product .rhw-map-product-shot{
  transition: scale var(--rhw-row-time, .25s) ease;
}
.rhw-map-product a.rhw-map-product-face:hover .rhw-map-product-shot{
  scale: var(--rhw-row-zoom, 1.05);
}

.rhw-map-product .rhw-map-product-name{
  transition: color var(--rhw-row-time, .25s) ease;
}

.rhw-map-product .is-still{ cursor: default; }

@media (prefers-reduced-motion: reduce){
  .rhw-map-product a.rhw-map-product-face:hover .rhw-map-product-shot{ scale: 1; }
}

/*
 * A product row is a link, and a theme colours every link. Said with one more
 * name than the theme uses, so the row takes the colour of the writing around
 * it — and still gives way to this widget's own colour settings, which carry
 * the page and the element in front of them.
 */
.rhw-map .rhw-map-product .rhw-map-product-face,
.rhw-map-loose .rhw-map-product .rhw-map-product-face{ color: inherit; }

.rhw-map-product-shot{
  inline-size: 56px;
  block-size: 56px;
  object-fit: contain;
  flex: 0 0 auto;
}

/*
 * Name, code and price on one line; what the product is for on the next. The
 * two are one column so a long name pushes nothing sideways and the line
 * underneath stays with the name it belongs to.
 */
.rhw-map-product-lines{
  flex: 1 1 auto;
  min-inline-size: 0;
  inline-size: var(--rhw-row-fill, auto);
  text-align: var(--rhw-row-text, inherit);
  display: flex;
  flex-direction: column;
  align-items: var(--rhw-row-cross, stretch);
  gap: var(--rhw-stack-gap, .15rem);
}
.rhw-map-product-head,
.rhw-map-product-above,
.rhw-map-product-under{
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  justify-content: var(--rhw-row-just, flex-start);
  gap: var(--rhw-line-gap, .75rem);
}
.rhw-map-product-name{ flex: var(--rhw-row-grow, 1) 1 auto; min-inline-size: 0; }

/*
 * A column, not a queue.
 *
 * Each row is laid out on its own, so a code and a price sized to their own
 * contents start wherever the row before them happened to end — and a list of
 * codes reads as a ragged edge rather than a column. Every code in a list is
 * given the width of the widest of them, and every price likewise; the widths
 * are measured on the page, since only the page knows what the type is doing.
 */
.rhw-map-product-price{
  white-space: nowrap;
  display: inline-block;
  min-inline-size: var(--rhw-price-w, 0px);
  text-align: end;
}

/*
 * Out at the side of the row, where a piece is lined up against the whole row
 * rather than against a line of writing — so a code and a price can sit level
 * with the middle of a row two lines tall.
 */
.rhw-map-product-side{
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: var(--rhw-row-just, flex-start);
  gap: var(--rhw-line-gap, .75rem);
  align-self: var(--rhw-side-align, center);
}

/*
 * Quieter than the name, by colour rather than by fading the whole thing —
 * a faded piece cannot be given a colour of its own, and a white asked for
 * here came out grey.
 */
.rhw-map-product-code{
  color: color-mix(in srgb, currentColor 62%, transparent);
  display: inline-block;
  min-inline-size: var(--rhw-code-w, 0px);
  text-align: center;
}
.rhw-map-product-note{
  color: color-mix(in srgb, currentColor 74%, transparent);
  font-size: .82em;
  line-height: 1.5;
}

/*
 * The code as a small button.
 *
 * Only the shape is set here — how it is surfaced is the same glass the buttons
 * on the rest of the site are made of, put on as a class. The writing is
 * centred by the box rather than by its baseline: a line of type is taller than
 * the letters in it, and centring the line leaves the code sitting high.
 */
.rhw-map-product-code.is-boxed{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--rhw-code-pad, .3em .7em);
  min-inline-size: max(var(--rhw-code-min, 0px), var(--rhw-code-w, 0px));
  border-radius: var(--rhw-code-round, 999px);
  white-space: nowrap;
  line-height: 1;
  text-align: center;
}

/* On its own, with no material asked for, it is the quietest possible pill. */
.rhw-map-product-code.is-boxed:not(.rhw-plain):not(.rhw-glass):not(.rhw-matte):not(.rhw-frost){
  border: 1px solid var(--rhw-code-line, rgba(127,127,127,.35));
  background: var(--rhw-code-bg, transparent);
}

/*
 * A list in a box of its own.
 *
 * What does not fit is scrolled to rather than laid out, so a category can
 * grow to any length without the page below it moving down.
 */
.rhw-list{
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--rhw-list-bar, rgba(127,127,127,.45)) transparent;
  padding-inline-end: .25rem;
}
.rhw-list::-webkit-scrollbar{ inline-size: 8px; }
.rhw-list::-webkit-scrollbar-track{ background: transparent; }
.rhw-list::-webkit-scrollbar-thumb{
  background: var(--rhw-list-bar, rgba(127,127,127,.45));
  border-radius: 999px;
}
.rhw-list .rhw-map-products{ margin: 0; }

/*
 * Rolling instead of scrolling.
 *
 * Nothing is scrolled to: the row at the top leaves and the one below rises
 * into its place, over and over, so a long category shows itself without
 * anybody having to touch it.
 */
.rhw-list--roll{ overflow: hidden; position: relative; }

/*
 * While the list rolls, the lines between the rows stay where they are.
 *
 * Carried on the rows themselves they would travel with them, and a line that
 * slides upward turns a list into a lift shaft. Here they are laid over the box
 * at the places where one row meets the next, and the rows move behind them.
 */
.rhw-list--roll .rhw-map-product::before{ content: none; }

.rhw-list-rails{
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
}

/*
 * The lines go the instant a row starts to move, and come back once it has
 * settled.
 *
 * Fading them over the length of the move left them half there for the whole
 * of it, which is exactly the moment a row is passing underneath. So: gone at
 * once, and back gently when there is nothing travelling to cut across.
 */
.rhw-list--roll.is-rolling .rhw-list-rails{
  opacity: var(--rhw-rail-hide, 0);
  transition: none;
}
.rhw-list--roll:not(.is-rolling) .rhw-list-rails{
  opacity: 1;
  transition: opacity var(--rhw-rail-back, .28s) ease var(--rhw-rail-wait, .06s);
}
.rhw-rail{
  position: absolute;
  inset-inline: 0;
  inline-size: var(--rhw-rule-len, 100%);
  margin-inline: var(--rhw-rule-pull, 0 auto);
  block-size: var(--rhw-rule-w, 1px);
  background-image: var(--rhw-rule-img, none);
  background-size: var(--rhw-rule-size, 100% var(--rhw-rule-w, 1px));
  background-repeat: repeat-x;
}

/*
 * One row leaves at a time.
 *
 * The row at the top lifts, fades, and folds away; the rows below it rise into
 * the space it gives up. Moving the whole list instead read as a slide, and a
 * slide says nothing about there being more to see.
 */
.rhw-list--roll .rhw-map-product{
  transition: margin-block-start var(--rhw-roll-move, .6s) ease,
              opacity var(--rhw-roll-move, .6s) ease,
              transform var(--rhw-roll-move, .6s) ease;
}
.rhw-list--roll .rhw-map-product.is-leaving{
  opacity: 0;
  transform: translateY(-35%) scale(.97);
}

@media (prefers-reduced-motion: reduce){
  .rhw-list--roll{ overflow-y: auto; }
}

/*
 * The list and its marks.
 *
 * The marks can lie under the list or over it, or stand on either side of it,
 * in which case they turn on their side with it.
 */
.rhw-roller{
  display: flex;
  gap: var(--rhw-bars-gap, 10px);
  align-items: stretch;
  min-inline-size: 0;
}
.rhw-roller .rhw-list{ flex: 1 1 auto; min-inline-size: 0; }

.rhw-roller--bottom{ flex-direction: column; }
.rhw-roller--top{ flex-direction: column-reverse; }
.rhw-roller--start{ flex-direction: row-reverse; }
.rhw-roller--end{ flex-direction: row; }

.rhw-list-bars{
  display: flex;
  flex: 0 0 auto;
  gap: var(--rhw-bar-gap, 6px);
  align-items: center;
  justify-content: center;
}
.rhw-roller--start .rhw-list-bars,
.rhw-roller--end .rhw-list-bars{ flex-direction: column; }

.rhw-list-bars .rhw-bar{
  flex: 0 0 auto;
  padding: 0;
  margin: 0;
  border: 0;
  min-inline-size: 0;
  min-block-size: 0;
  max-inline-size: none;
  font-size: 0;
  line-height: 0;
  border-radius: 999px;
  background: var(--rhw-bar-off, rgba(127,127,127,.4));
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  inline-size: var(--rhw-bar-long, 22px);
  block-size: var(--rhw-bar-thick, 3px);
  transition: background var(--rhw-map-ease, .35s) ease,
              inline-size var(--rhw-map-ease, .35s) ease,
              block-size var(--rhw-map-ease, .35s) ease;
}
.rhw-roller--start .rhw-list-bars .rhw-bar,
.rhw-roller--end .rhw-list-bars .rhw-bar{
  inline-size: var(--rhw-bar-thick, 3px);
  block-size: var(--rhw-bar-long, 22px);
}

.rhw-list-bars .rhw-bar:hover,
.rhw-list-bars .rhw-bar:focus-visible{ background: var(--rhw-bar-over, var(--rhw-bar-on, currentColor)); }
.rhw-list-bars .rhw-bar.is-on{ background: var(--rhw-bar-on, currentColor); }
.rhw-list-bars .rhw-bar:focus{ outline: none; }
.rhw-list-bars .rhw-bar:focus-visible{ outline: 2px solid var(--rhw-bar-on, currentColor); outline-offset: 3px; }

/* How many there are: a quiet line, not a heading. */
.rhw-list-wrap{ display: flex; flex-direction: column; gap: var(--rhw-tally-gap, 6px); }
.rhw-list-tally{
  margin: 0;
  font-size: .78em;
  line-height: 1.5;
  opacity: .7;
}

/* A category with nothing in it yet, and a list standing on its own. */
.rhw-map-soon{ opacity: .7; }
.rhw-map-loose .rhw-map-products{ margin: 0; }

/* ------------------------------------------------------- the off switch ---- */

/*
 * What is left of a widget that has been put to sleep: nothing at all on the
 * finished page, and this in the editor, so it can be found and woken.
 */
.rhw-resting{
  display: inline-block;
  padding: .35em .8em;
  border: 1px dashed currentColor;
  border-radius: 999px;
  font-size: 12px;
  line-height: 1.6;
  opacity: .55;
}

/* ------------------------------------------------- shortcuts to the map ---- */

/*
 * A row of glass circles standing for the map's regions.
 *
 * Glass, because the panel behind them is dark and busy: a translucent disc
 * that blurs what is under it sits on any ground without a box around it, and
 * the one that is open is simply a little brighter than the rest.
 */
.rhw-chips{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  padding: var(--rhw-chip-pad, 0);

  /* Given a height by the column it sits in — a taller thing beside it — the
     row takes all of it and stands its circles in the middle, rather than
     leaving the whole difference underneath them. Where it is given no
     height, this is nothing at all. */
  block-size: 100%;
  align-content: var(--rhw-chip-sits, center);
  gap: var(--rhw-chip-gap, 12px);
  justify-content: center;

  /* The circles are counted once the page is up. The room they will need is
     kept for them, so nothing below moves when they arrive. */
  min-block-size: var(--rhw-chip-size, 52px);
}

.rhw-chips .rhw-chip{
  inline-size: var(--rhw-chip-size, 52px);
  block-size: var(--rhw-chip-size, 52px);
  min-inline-size: 0;
  min-block-size: 0;
  max-inline-size: none;
  flex: 0 0 auto;
  padding: 0;
  margin: 0;
  border: 1px solid var(--rhw-chip-line, rgba(255,255,255,.3));
  border-radius: 50%;
  background: var(--rhw-chip-bg, rgba(255,255,255,.1));
  color: var(--rhw-chip-ink, #fff);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  /* The blur waits for the hand.
   * A shortcut row is a hundred small circles, and a backdrop-filter costs the
   * compositor a layer for each one whether or not anything shows through it.
   * At 52px across the blur is barely readable anyway; asked for only under the
   * pointer, one circle pays instead of a hundred. */
  box-shadow: inset 0 1px 0 rgba(255,255,255,.35), 0 6px 18px rgba(0,0,0,.22);
  transition: background var(--rhw-map-ease, .35s) ease,
              border-color var(--rhw-map-ease, .35s) ease,
              translate var(--rhw-map-ease, .35s) ease;
}

/*
 * The number sits at the centre of the circle by its ink, not by its box.
 *
 * A line of type is taller than the digit inside it and the room above the
 * digit is never the room below it, so a box centred by the browser leaves the
 * digit sitting low. The two shifts are measured on the page from the font
 * actually in use and handed back on --rhw-chip-nx / --rhw-chip-ny.
 */
.rhw-chips .rhw-chip-n{
  display: block;
  margin: 0;
  padding: 0;
  border: 0;
  line-height: 1;
  font-variant-numeric: lining-nums tabular-nums;
  translate: var(--rhw-chip-nx, 0px) var(--rhw-chip-ny, 0px);
}

.rhw-chips .rhw-chip:hover,
.rhw-chips .rhw-chip:focus-visible{
  backdrop-filter: blur(var(--rhw-chip-blur, 10px)) saturate(1.4);
  -webkit-backdrop-filter: blur(var(--rhw-chip-blur, 10px)) saturate(1.4);
  translate: 0 calc(var(--rhw-chip-lift, 3px) * -1);
  background: var(--rhw-chip-hover-bg, var(--rhw-chip-bg, rgba(255,255,255,.1)));
  border-color: var(--rhw-chip-hover-line, var(--rhw-chip-line, rgba(255,255,255,.3)));
  color: var(--rhw-chip-hover-ink, var(--rhw-chip-ink, #fff));
}

/*
 * A word before the numbers.
 *
 * Not a circle — a plain piece of writing that answers the pointer, for the
 * panel that stands there before any region is chosen.
 */
/*
 * It is a button, and a theme dresses buttons. Written out in every state and
 * named on the element, so a plate or a hover colour from somewhere else never
 * arrives unasked — and everything that does dress it is a setting.
 */
.rhw-chips button.rhw-chip-lead,
.rhw-chips button.rhw-chip-lead:hover,
.rhw-chips button.rhw-chip-lead:focus,
.rhw-chips button.rhw-chip-lead:active{
  flex: 0 0 auto;
  margin: 0;
  padding: var(--rhw-lead-pad, 0);
  border: 0;
  border-radius: var(--rhw-lead-round, 0);
  background: var(--rhw-lead-bg, transparent);
  box-shadow: none;
  text-decoration: none;
  color: var(--rhw-lead-ink, rgba(255,255,255,.72));
  font: inherit;
  line-height: 1;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
}

/* The word answers the pointer the way the circles do: it lifts, and lights. */
.rhw-chips button.rhw-chip-lead:hover,
.rhw-chips button.rhw-chip-lead:focus-visible{
  color: var(--rhw-lead-on, #fff);
  background: var(--rhw-lead-hover-bg, var(--rhw-lead-bg, transparent));
  translate: 0 calc(var(--rhw-chip-lift, 3px) * -1);
}
.rhw-chips button.rhw-chip-lead.is-on{
  color: var(--rhw-lead-on, #fff);
  background: var(--rhw-lead-hover-bg, var(--rhw-lead-bg, transparent));
}
.rhw-chips .rhw-chip-lead{
  transition: color var(--rhw-map-ease, .35s) ease,
              translate var(--rhw-map-ease, .35s) ease;
}
.rhw-chips .rhw-chip-lead:focus{ outline: none; }
.rhw-chips .rhw-chip-lead:focus-visible{ outline: 2px solid var(--rhw-lead-on, #fff); outline-offset: 3px; }

/*
 * The name, over the circle.
 *
 * The browser's own tooltip waits about a second, lands under the pointer
 * rather than over the circle, and cannot be styled at all. This one is ours:
 * it sits centred over the number and fades in at once.
 */
.rhw-chips .rhw-chip{ position: relative; }

.rhw-chips .rhw-chip::after{
  content: attr(data-rhw-tip);
  position: absolute;
  bottom: 100%;
  left: 50%;
  z-index: 6;
  translate: -50% calc(var(--rhw-tip-gap, 8px) * -1 + 4px);
  padding: var(--rhw-tip-pad, .42em .68em);
  border-radius: var(--rhw-tip-round, 10px);
  background: var(--rhw-tip-bg, rgba(0, 0, 0, .82));
  color: var(--rhw-tip-ink, #fff);
  font-size: var(--rhw-tip-size, .8rem);
  line-height: 1.3;
  white-space: nowrap;
  max-inline-size: 60vw;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  box-shadow: 0 8px 22px rgba(0, 0, 0, .35);
  transition: opacity var(--rhw-tip-fade, .18s) ease,
              translate var(--rhw-tip-fade, .18s) ease,
              visibility 0s linear var(--rhw-tip-fade, .18s);
}

.rhw-chips .rhw-chip:hover::after,
.rhw-chips .rhw-chip:focus-visible::after{
  opacity: 1;
  visibility: visible;
  translate: -50% calc(var(--rhw-tip-gap, 8px) * -1);
  transition-delay: 0s, 0s, 0s;
}

/* Told to keep quiet, or given no name to say. */
.rhw-chips .rhw-chip:not([data-rhw-tip])::after{ content: none; }

@media (prefers-reduced-motion: reduce){
  .rhw-chips .rhw-chip::after{ transition: none; }
}

/*
 * The one that is open.
 *
 * A change of colour alone was easy to miss among ten of them, so it also
 * stands a little proud of the rest and carries a ring.
 */
.rhw-chips .rhw-chip.is-on{
  backdrop-filter: blur(var(--rhw-chip-blur, 10px)) saturate(1.4);
  -webkit-backdrop-filter: blur(var(--rhw-chip-blur, 10px)) saturate(1.4);
  background: var(--rhw-chip-on, rgba(255,255,255,.24));
  border-color: var(--rhw-chip-on-line, rgba(255,255,255,.65));
  color: var(--rhw-chip-on-ink, var(--rhw-chip-ink, #fff));
  scale: var(--rhw-chip-on-size, 1.08);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.35),
    0 0 0 var(--rhw-chip-ring, 3px) var(--rhw-chip-on-ring, rgba(255,255,255,.18)),
    0 6px 18px rgba(0,0,0,.22);
}

/*
 * How the circles change.
 *
 * Lighting and fading are given a longer, softer curve than the lift under the
 * pointer: the lift answers a hand and should be quick, while a circle coming
 * up or stepping back is the picture being read and should not snap.
 */
.rhw-chips .rhw-chip{
  transition: background   var(--rhw-chip-soft, .45s) var(--rhw-chip-curve, cubic-bezier(.22,.61,.36,1)),
              border-color var(--rhw-chip-soft, .45s) var(--rhw-chip-curve, cubic-bezier(.22,.61,.36,1)),
              color        var(--rhw-chip-soft, .45s) var(--rhw-chip-curve, cubic-bezier(.22,.61,.36,1)),
              box-shadow   var(--rhw-chip-soft, .45s) var(--rhw-chip-curve, cubic-bezier(.22,.61,.36,1)),
              scale        var(--rhw-chip-soft, .45s) var(--rhw-chip-curve, cubic-bezier(.22,.61,.36,1)),
              opacity      var(--rhw-chip-soft, .45s) var(--rhw-chip-curve, cubic-bezier(.22,.61,.36,1)),
              translate    var(--rhw-map-ease, .35s) ease;
}

/*
 * In step with the figure.
 *
 * While the scan stands on a region, the circle for that region is lit and the
 * rest of the row steps back. The stepping back is what makes the two read as
 * one instrument: a brighter circle among ten equally bright ones is easy to
 * miss, a bright one among ten faint ones is not.
 *
 * It lifts the moment the pointer reaches the row. Faded, a circle is a layer
 * of its own and the name over it would be caught behind its neighbours and
 * faded with it — and a circle that stays dim under the pointer reads as a
 * hover that has stopped working. Whoever is on the row is reading the row,
 * not the figure, so the row gives itself back to them whole.
 */
.rhw-chips.is-scan:not(:hover) .rhw-chip:not(.is-on),
.rhw-chips.is-scan:not(:hover) .rhw-chip-lead:not(.is-on){ opacity: var(--rhw-chip-rest, .45); }

.rhw-chips .rhw-chip-lead{
  transition: color     var(--rhw-chip-soft, .45s) var(--rhw-chip-curve, cubic-bezier(.22,.61,.36,1)),
              opacity   var(--rhw-chip-soft, .45s) var(--rhw-chip-curve, cubic-bezier(.22,.61,.36,1)),
              translate var(--rhw-map-ease, .35s) ease;
}

/* And, if the colour alone is still too quiet, a ring that opens out of it. */
.rhw-chips .rhw-chip::before{
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 1px solid var(--rhw-chip-on-line, rgba(255,255,255,.65));
  opacity: 0;
  pointer-events: none;
}

.rhw-chips--beat .rhw-chip.is-on::before{ animation: rhw-chip-beat 1.6s ease-out infinite; }

@keyframes rhw-chip-beat{
  0%       { opacity: .75; transform: scale(1); }
  70%, 100%{ opacity: 0;   transform: scale(1.5); }
}

.rhw-chips .rhw-chip:focus{ outline: none; }
.rhw-chips .rhw-chip:focus-visible{ outline: 2px solid var(--rhw-chip-on-line, #fff); outline-offset: 3px; }

@media (prefers-reduced-motion: reduce){
  .rhw-chips .rhw-chip{ transition: none; }
  .rhw-chips .rhw-chip:hover{ translate: none; }
  .rhw-chips--beat .rhw-chip.is-on::before{ animation: none; }
}

/* ------------------------------------------------------------- the start ---- */

/*
 * A start, for when nobody is reading it.
 *
 * The picture on top blinks out for an instant and what is underneath shows
 * through, while the figure gives a small jolt — enough to catch the corner of
 * an eye without asking for anything.
 */
@keyframes rhw-jolt-flash{
  0%, 100% { opacity: 1; }
  9%, 21%  { opacity: calc(1 - var(--rhw-jolt-show, 100) / 100); }
  15%      { opacity: 1; }
  34%      { opacity: calc(1 - var(--rhw-jolt-show, 100) / 100); }
  44%      { opacity: 1; }
}
@keyframes rhw-jolt-shake{
  0%, 100% { translate: 0 0; }
  10%      { translate: calc(var(--rhw-jolt-shake, 3px) * -1) 0; }
  22%      { translate: var(--rhw-jolt-shake, 3px) 0; }
  34%      { translate: calc(var(--rhw-jolt-shake, 3px) * -.6) 0; }
  46%      { translate: calc(var(--rhw-jolt-shake, 3px) * .35) 0; }
}

.rhw-map.is-jolt .rhw-map-over{
  animation: rhw-jolt-flash var(--rhw-jolt-time, .5s) linear 1;
}
.rhw-map.is-jolt .rhw-map-figure{
  animation: rhw-jolt-shake var(--rhw-jolt-time, .5s) linear 1;
}
/* With a cluster the picture underneath is only a drawing source, so it has to
   be let out for the length of the start. */
.rhw-map--cluster.is-jolt .rhw-map-under{ visibility: visible; }

@media (prefers-reduced-motion: reduce){
  .rhw-map.is-jolt .rhw-map-over,
  .rhw-map.is-jolt .rhw-map-figure{ animation: none; }
}


/* ------------------------------------------------------------- the cue ---- */

/*
 * An arrow that points at the figure and will not sit still.
 *
 * Everything it does is one of four movements, each of them a round that can be
 * given a length and a wait; and every one of them can be turned off, because a
 * page that moves in four places at once moves nowhere.
 */
.rhw-cue{
  display: flex;
  align-items: center;
  line-height: 0;
  color: inherit;
}

.rhw-cue-words{
  display: flex;
  flex-direction: column;
  gap: 4px;
  line-height: 1.5;
  min-inline-size: 0;
}
.rhw-cue-title{ margin: 0; }
.rhw-cue-note{ opacity: .85; }

.rhw-cue-mark{
  display: inline-block;
  flex: 0 0 auto;
  inline-size: var(--rhw-cue-size, 48px);
  block-size: var(--rhw-cue-size, 48px);
  rotate: var(--rhw-cue-turn, 0deg);
  animation-duration: var(--rhw-cue-pace, 1.6s);
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
  animation-name: var(--rhw-cue-anim, none);
}
.rhw-cue-mark svg{
  inline-size: 100%;
  block-size: 100%;
  display: block;
  stroke-width: calc(var(--rhw-cue-weight, 2) * 3);
}

/* On a right-to-left page the start of the line is the other way about. */
[dir="rtl"] .rhw-cue-mark{ rotate: calc(var(--rhw-cue-turn, 0deg) * -1 + 180deg); }

.rhw-cue--glow .rhw-cue-mark{
  filter:
    drop-shadow(0 0 calc(var(--rhw-cue-glow-far, 14px) / 2) var(--rhw-cue-glow, rgba(196,124,255,.85)))
    drop-shadow(0 0 var(--rhw-cue-glow-far, 14px) var(--rhw-cue-glow, rgba(196,124,255,.85)));
}

.rhw-cue--nudge{ --rhw-cue-anim: rhw-cue-nudge; }
.rhw-cue--swim { --rhw-cue-anim: rhw-cue-swim; }
.rhw-cue--beat { --rhw-cue-anim: rhw-cue-beat; }
.rhw-cue--sway { --rhw-cue-anim: rhw-cue-sway; }

/* The wait between rounds is part of the round itself, held at the far end. */
.rhw-cue-mark{
  animation-duration: calc(var(--rhw-cue-pace, 1.6s) + var(--rhw-cue-rest, 0s));
}

/* The mark travels away from the words, so on a Persian page it travels the
   other way: the words are on its left there, and a nudge to the left put it
   on top of them. */
.rhw-cue-mark{ --rhw-cue-way: -1; }
[dir="rtl"] .rhw-cue-mark{ --rhw-cue-way: 1; }

@keyframes rhw-cue-nudge{
  0%, 100% { translate: 0 0; }
  45%      { translate: calc(var(--rhw-cue-far, 14px) * var(--rhw-cue-way, -1)) 0; }
  70%      { translate: 0 0; }
}
@keyframes rhw-cue-swim{
  0%   { translate: 0 0; opacity: 0; }
  15%  { opacity: 1; }
  70%  { translate: calc(var(--rhw-cue-far, 60px) * var(--rhw-cue-way, -1)) 0; opacity: 0; }
  100% { translate: 0 0; opacity: 0; }
}
@keyframes rhw-cue-beat{
  0%, 100% { scale: 1; }
  45%      { scale: var(--rhw-cue-beat, 1.14); }
}
@keyframes rhw-cue-sway{
  0%, 100% { rotate: var(--rhw-cue-turn, 0deg); }
  35%      { rotate: calc(var(--rhw-cue-turn, 0deg) - 9deg); }
  70%      { rotate: calc(var(--rhw-cue-turn, 0deg) + 9deg); }
}
@keyframes rhw-cue-neon{
  0%, 100% { opacity: 1; }
  50%      { opacity: .55; }
}

@media (prefers-reduced-motion: reduce){
  .rhw-cue-mark{ animation: none; }
}

/* ------------------------------------------------------- the figure strip ---- */

/*
 * A row of figures with one name box between them.
 *
 * The name is written once and moved, rather than repeated under every figure.
 * Ten labels are a list to be read; one box that keeps up with the pointer is
 * an instrument being used, and it leaves the pictures to be looked at.
 */
.rhw-strip{ display: block; }

.rhw-strip-row{
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-end;
  justify-content: center;
  gap: var(--rhw-strip-gap, 8px);
  min-inline-size: 0;
}

/* The width each figure carries, written on it when the page is built. With
   it the figures share the row before their pictures have arrived, exactly as
   they do after; without one — a picture read from somewhere we cannot measure
   — it falls back to what it did before. */
.rhw-strip-one{
  inline-size: var(--rhw-one-w, auto);
}

.rhw-strip-one{
  position: relative;
  display: block;
  flex: 0 1 auto;
  min-inline-size: 0;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  opacity: 1;

  /* How much colour they have standing there, before anybody is pointing at
     anything. The pointer takes it off whichever one it is on. */
  filter: grayscale(var(--rhw-strip-base-grey, 0));

  /* Slower than the box, and on a curve that eases out rather than stopping.
     A figure that answers as fast as a word appears reads as a switch being
     thrown; the picture is the thing being looked at, and it should arrive. */
  transition: opacity   var(--rhw-strip-move, .45s) var(--rhw-strip-curve, cubic-bezier(.22,.61,.36,1)),
              filter    var(--rhw-strip-move, .45s) var(--rhw-strip-curve, cubic-bezier(.22,.61,.36,1)),
              translate var(--rhw-strip-move, .45s) var(--rhw-strip-curve, cubic-bezier(.22,.61,.36,1)),
              scale     var(--rhw-strip-move, .45s) var(--rhw-strip-curve, cubic-bezier(.22,.61,.36,1));
}
.rhw-strip-one.is-still{ cursor: default; }


/* A figure that is a link answers the keyboard, and the ring it draws should
 * belong to the page. Left to the browser it is a black rectangle, which on a
 * dark band reads as a box drawn around one figure by mistake. */
.rhw-strip-one:focus-visible{
  outline: 2px solid var(--rhw-strip-focus, #E6B3F4);
  outline-offset: 6px;
  border-radius: 12px;
}

/* The width is named rather than left to the picture.
 *
 * Elementor's own sheet says `height: auto` for every picture inside it, and
 * it weighs more than a single class of ours, so the height here was never
 * the one that applied. With the height taken away and the width left to the
 * picture, a figure whose picture has not arrived yet is nothing at all —
 * no width, so no height either — and the row springs to its full size the
 * moment the pictures land, throwing everything below it down the page.
 *
 * Filling the space it is given is what each of these does once it has
 * arrived, so saying it plainly changes nothing that is seen and gives the
 * browser the one measurement it needs to keep the room from the first paint.
 * The class is written twice to outweigh Elementor's rule without !important. */
.rhw-strip-img.rhw-strip-img{
  inline-size: 100%;
}

.rhw-strip-img{
  display: block;
  block-size: var(--rhw-strip-tall, 320px);
  inline-size: auto;
  max-inline-size: 100%;
  object-fit: contain;
}

/* Whoever is not being looked at steps back, and only while one of them is. */
.rhw-strip-row:hover .rhw-strip-one{
  opacity: var(--rhw-strip-rest, .55);
  filter: grayscale(var(--rhw-strip-grey, 0));
}

.rhw-strip-row:hover .rhw-strip-one:hover,
.rhw-strip-one.is-on{
  opacity: 1;
  filter: none;
  translate: 0 calc(var(--rhw-strip-lift, 10px) * -1);
  scale: var(--rhw-strip-grow, 1.04);
  z-index: 2;
}

.rhw-strip-img{
  transition: filter var(--rhw-strip-move, .45s) var(--rhw-strip-curve, cubic-bezier(.22,.61,.36,1));
}
.rhw-strip-one:hover .rhw-strip-img,
.rhw-strip-one.is-on .rhw-strip-img{
  filter: drop-shadow(0 0 var(--rhw-strip-glow-far, 28px) var(--rhw-strip-glow, transparent));
}

/* The box itself, wherever it has been asked to stand. */
.rhw-strip-box{
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: .15em;
  padding: var(--rhw-strip-box-pad, 10px 16px);
  border-radius: var(--rhw-strip-box-round, 14px);
  background: var(--rhw-strip-box-bg, rgba(0,0,0,.55));
  border: 1px solid var(--rhw-strip-box-line, rgba(255,255,255,.18));
  color: var(--rhw-strip-box-ink, #fff);
  line-height: 1.25;
  text-align: center;
  white-space: nowrap;
  pointer-events: none;
  /*
   * The glass is a layer of the box, not a property of it.
   *
   * A backdrop filter on the box itself is drawn on its own surface, and a
   * surface does not fade the way its contents do — the panel would land in one
   * step after the writing had already arrived. Held on a layer underneath
   * instead, at a strength that never changes, it has nothing of its own to
   * animate and simply fades in with everything else in the box.
   */
  overflow: hidden;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  opacity: 0;
  scale: var(--rhw-strip-box-from, 1);
  transition: opacity   var(--rhw-strip-fade, .22s) var(--rhw-strip-curve, ease) var(--rhw-strip-box-wait, 0s),
              translate var(--rhw-strip-fade, .22s) var(--rhw-strip-curve, ease) var(--rhw-strip-box-wait, 0s),
              scale     var(--rhw-strip-fade, .22s) var(--rhw-strip-curve, ease) var(--rhw-strip-box-wait, 0s);
}
.rhw-strip-box::after{
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  backdrop-filter: blur(var(--rhw-strip-box-blur, 12px)) saturate(var(--rhw-sat, 1));
  -webkit-backdrop-filter: blur(var(--rhw-strip-box-blur, 12px)) saturate(var(--rhw-sat, 1));
  /* Its own fade, because a browser does not dim a backdrop filter along with
     the element carrying it — the blur would land in one step after the writing
     had already arrived. Given an opacity of its own, it travels with it. */
  opacity: 0;
  transition: opacity var(--rhw-strip-fade, .22s) var(--rhw-strip-curve, ease) var(--rhw-strip-box-wait, 0s);
}
@keyframes rhw-strip-glass-in{ from{ opacity: 0 } to{ opacity: 1 } }

/* A keyframe rather than a transition: a transition can be skipped when the
   layer is first laid out, an animation always runs its length. */
.rhw-strip-one:hover .rhw-strip-box::after,
.rhw-strip-one.is-on .rhw-strip-box::after,
.rhw-strip-box.is-said::after{
  opacity: 1;
  animation: rhw-strip-glass-in var(--rhw-strip-fade, .22s) var(--rhw-strip-curve, ease) var(--rhw-strip-box-wait, 0s) both;
}

/* The writing rides above that layer rather than under it. */
.rhw-strip-name,
.rhw-strip-note{ position: relative; z-index: 1; }
/* Asked for a flat panel, there is no layer at all and nothing to step. */
.rhw-strip--no-blur .rhw-strip-box::after{ display: none; }

.rhw-strip-one:hover .rhw-strip-box,
.rhw-strip-one.is-on .rhw-strip-box,
.rhw-strip-box.is-said{ scale: 1; }

/*
 * The words first, the picture after.
 *
 * Asked for, the box keeps its own timing and the figure is the one made to
 * wait, so the name is read and then the picture answers it. Nothing here
 * changes how long either takes — only which of them starts first.
 */
.rhw-strip--words-first .rhw-strip-one{ transition-delay: var(--rhw-strip-hold, .18s); }
.rhw-strip--words-first .rhw-strip-box{ transition-delay: 0s; }
.rhw-strip-name{ color: var(--rhw-strip-box-ink, #fff); }
.rhw-strip-note{ color: var(--rhw-strip-box-note, rgba(255,255,255,.7)); font-size: .82em; }
.rhw-strip-note:empty{ display: none; }

/* Over the figure it is naming: it belongs to that figure and rides with it. */
.rhw-strip-box--over{
  position: absolute;
  inset-block-end: calc(100% + var(--rhw-strip-box-gap, 14px));
  inset-inline-start: 50%;
  translate: -50% 6px;
  z-index: 3;
}
.rhw-strip-one:hover .rhw-strip-box--over,
.rhw-strip-one.is-on .rhw-strip-box--over{ opacity: 1; translate: -50% 0; }

/* Under the figure it is naming: the same box, hung below its own picture
   rather than above it, so it lines up with that one figure instead of
   standing in the middle of the row. */
.rhw-strip-box--under{
  position: absolute;
  inset-block-start: calc(100% + var(--rhw-strip-box-gap, 14px));
  inset-inline-start: 50%;
  translate: -50% -6px;
  z-index: 3;
}
.rhw-strip-one:hover .rhw-strip-box--under,
.rhw-strip-one.is-on .rhw-strip-box--under{ opacity: 1; translate: -50% 0; }

/* In one place above or below the row, where it is the row that is answering. */
.rhw-strip--above .rhw-strip-box,
.rhw-strip--below .rhw-strip-box{
  display: flex;
  inline-size: fit-content;
  margin-inline: auto;
  translate: 0 6px;
}
.rhw-strip--above .rhw-strip-box{ margin-block-end: var(--rhw-strip-box-gap, 14px); }
.rhw-strip--below .rhw-strip-box{ margin-block-start: var(--rhw-strip-box-gap, 14px); }

/* Following the pointer, it is put where the pointer is by the page. */
.rhw-strip--pointer{ position: relative; }
.rhw-strip--pointer .rhw-strip-box{
  position: fixed;
  z-index: 40;
  translate: -50% calc(-100% - var(--rhw-strip-box-gap, 14px));
  inset-block-start: var(--rhw-strip-y, -9999px);
  inset-inline-start: var(--rhw-strip-x, -9999px);
}

/* Shown, once there is something to say. */
.rhw-strip-box.is-said{ opacity: 1; translate: 0 0; }
.rhw-strip--pointer .rhw-strip-box.is-said{ translate: -50% calc(-100% - var(--rhw-strip-box-gap, 14px)); }

@media (prefers-reduced-motion: reduce){
  .rhw-strip-one,
  .rhw-strip-box{ transition: none; }
  .rhw-strip-row:hover .rhw-strip-one:hover,
  .rhw-strip-one.is-on{ translate: none; scale: 1; }
}

/* Narrow screens.
 *
 * The caption is a single unbroken line hung on the middle of one small
 * figure. On a wide page that is exactly right. On a phone the line is wider
 * than the screen, and because the box is only invisible rather than absent it
 * still widens the page: the whole site scrolled sideways by the amount the
 * caption stuck out, with nothing to see there.
 *
 * Below the point where the page stops being one zoomed design, the caption is
 * hung on the row instead of on one figure and allowed to break. Anchored to
 * both edges of the row with automatic side margins, it centres itself and can
 * never be wider than the row it belongs to. Only one is ever shown at a time,
 * so they cannot collide. The pointer variant places itself and is left alone.
 */
@media (max-width: 1024px){
  .rhw-strip:not(.rhw-strip--pointer) .rhw-strip-row{ position: relative; }
  .rhw-strip:not(.rhw-strip--pointer) .rhw-strip-one{ position: static; }

  .rhw-strip:not(.rhw-strip--pointer) .rhw-strip-box{
    white-space: normal;
    inline-size: max-content;
    max-inline-size: 100%;
    inset-inline: 0;
    margin-inline: auto;
  }

  .rhw-strip:not(.rhw-strip--pointer) .rhw-strip-box--over{ translate: 0 6px; }
  .rhw-strip:not(.rhw-strip--pointer) .rhw-strip-box--under{ translate: 0 -6px; }

  .rhw-strip:not(.rhw-strip--pointer) .rhw-strip-one:hover .rhw-strip-box--over,
  .rhw-strip:not(.rhw-strip--pointer) .rhw-strip-one.is-on .rhw-strip-box--over,
  .rhw-strip:not(.rhw-strip--pointer) .rhw-strip-one:hover .rhw-strip-box--under,
  .rhw-strip:not(.rhw-strip--pointer) .rhw-strip-one.is-on .rhw-strip-box--under{ translate: 0 0; }
}

/* A figure still waiting for its picture, and a strip still waiting for a
   figure. Only ever drawn while the page is being worked on. */
.rhw-strip-img--empty{
  display: grid;
  place-items: center;
  inline-size: 140px;
  block-size: var(--rhw-strip-tall, 320px);
  padding: 1rem;
  border: 1px dashed currentColor;
  border-radius: 12px;
  opacity: .5;
  font-size: .8rem;
  text-align: center;
  white-space: normal;
}
.rhw-strip--bare{
  padding: 1.25rem;
  border: 1px dashed currentColor;
  border-radius: 12px;
  opacity: .6;
  text-align: center;
}

/* --------------------------------------------------------- the slider ---- */

/*
 * A listing that moves a page at a time.
 *
 * A page is the whole grid — two across and two deep is four cards, and all
 * four leave together. The track is one long row of pages, each page exactly
 * as wide as the window, so the sliding is a single translate and the browser
 * does all of it. Nothing is measured in script.
 */
.rhw-slider{ position: relative; }

.rhw-slider-window{ overflow: hidden; }

.rhw-slider-track{
  display: flex;
  margin: 0;
  padding: 0;
  list-style: none;
  transition: translate var(--rhw-slider-glide, .6s) cubic-bezier(.22,.61,.36,1);
  translate: calc(var(--rhw-slider-at, 0) * -100%) 0;
}

/* Every card is a fraction of one page, so a page fills the window exactly.
   The space between cards is padding inside that fraction, not a grid gap: a
   gap would be added to the width and a page would no longer be exactly as
   wide as the window it slides across. */
.rhw-slide-card{
  box-sizing: border-box;
  padding-inline: calc(var(--rhw-slider-gap, 18px) / 2);
  padding-block-end: var(--rhw-slider-gap-down, var(--rhw-slider-gap, 18px));
  min-inline-size: 0;
  display: flex;
}
.rhw-slide-card > *{ flex: 1 1 auto; min-inline-size: 0; }

/* A card of the reader's own making arrives wrapped in a plain Elementor
   document whose own height is only as tall as its writing. Left alone the
   cards in a row end at different places. The wrapper and the card inside it
   are told to take the whole cell, so the row decides the height and every
   card in it ends level. */
.rhw-slide-card--own > .elementor{ display: flex; flex-direction: column; }
.rhw-slide-card--own > .elementor > .elementor-element{ flex: 1 1 auto; }

/* A picture put where a product would have been, so a short last page does not
   end in a hole. It carries the same corners and material as the cards. */
.rhw-slide-fill{
  box-sizing: border-box;
  display: block;
  inline-size: 100%;
  block-size: 100%;
  padding: var(--rhw-fill-pad, 24px);
  border: 0;
  border-radius: var(--rhw-fill-round, var(--rhw-slider-card-round, 24px));
}

/* The picture is a layer of its own inside the frame, so what is set behind it
   — a colour, a gradient, a picture of its own — never fights the picture the
   frame was given to hold. */
.rhw-slide-fill-shot{
  display: block;
  inline-size: 100%;
  block-size: 100%;
  background-image: var(--rhw-fill-shot, none);
  background-size: var(--rhw-fill-fit, contain);
  background-position: var(--rhw-fill-pos, 50% 50%);
  background-repeat: no-repeat;
}

/* When the cards of the reader's own template come in with a movement, the
   filled place is wrapped in the same kind of element carrying the same
   classes, so Elementor moves it exactly as it moves the rest. */
.rhw-slide-card--fill > .elementor-element{ display: flex; flex: 1 1 auto; min-inline-size: 0; }
.rhw-slide-card--fill > .elementor-element > *{ flex: 1 1 auto; min-inline-size: 0; }

.rhw-slide-face{
  display: flex;
  align-items: center;
  gap: var(--rhw-slider-gap, 18px);
  block-size: 100%;
  padding: var(--rhw-slider-card-pad, 18px 20px);
  border-radius: var(--rhw-slider-card-round, 24px);
  background: var(--rhw-slider-card-bg, transparent);
  border: 1px solid var(--rhw-slider-card-line, transparent);
  color: inherit;
  text-decoration: none;
}

.rhw-slider--above .rhw-slide-face{ flex-direction: column; text-align: center; }

.rhw-slide-shot{
  flex: 0 0 auto;
  inline-size: var(--rhw-slider-shot, 120px);
  block-size: auto;
  object-fit: contain;
}

.rhw-slide-words{
  display: flex;
  flex-direction: column;
  gap: .45em;
  align-items: var(--rhw-slide-align, flex-start);
  text-align: var(--rhw-slide-align, start);
  min-inline-size: 0;
}
.rhw-slider--above .rhw-slide-words{ align-items: center; text-align: center; }

.rhw-slide-code{
  display: inline-flex;
  align-items: center;
  padding: .3em .9em;
  border-radius: 999px;
  background: var(--rhw-slide-code-bg, rgba(127,127,127,.2));
  line-height: 1;
  white-space: nowrap;
}
.rhw-slide-name{ font-weight: 700; }
.rhw-slide-note{ opacity: .9; }

/* The two rows are made by the track wrapping inside one page's width, which a
   flex row cannot do — so the page is a grid instead once more than one row is
   asked for. */
.rhw-slider-track{
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: calc(100% / var(--rhw-slider-cols, 2));
  grid-template-rows: repeat(var(--rhw-slider-rows, 2), var(--rhw-slider-tall, 1fr));
  align-items: stretch;

  /* The space between cards is padding inside each card's share of the page,
     which would otherwise leave half of it standing outside the first and last
     card as well. The whole run is pulled back by that half at each edge, and
     by a whole one under the last row, so the space falls only between cards
     and the outer edges sit flush. The page still measures exactly one window,
     so the sliding is unaffected. */
  margin-inline: calc(var(--rhw-slider-gap, 18px) / -2);
  margin-block-end: calc(var(--rhw-slider-gap-down, var(--rhw-slider-gap, 18px)) * -1);
}

.rhw-slider-arrow{
  position: absolute;
  inset-block-start: 50%;
  translate: 0 -50%;
  inline-size: 2.6rem;
  block-size: 2.6rem;
  border-radius: 50%;
  border: 1px solid var(--rhw-slider-card-line, rgba(127,127,127,.35));
  background: var(--rhw-slider-card-bg, rgba(127,127,127,.12));
  cursor: pointer;
  z-index: 2;
}
.rhw-slider-arrow::before{
  content: '';
  display: block;
  inline-size: .6rem;
  block-size: .6rem;
  margin-inline: auto;
  border-inline-start: 2px solid currentColor;
  border-block-start: 2px solid currentColor;
}
.rhw-slider-arrow--back{ inset-inline-start: -1.3rem; }
.rhw-slider-arrow--back::before{ rotate: -45deg; translate: 25% 0; }
.rhw-slider-arrow--on{ inset-inline-end: -1.3rem; }
.rhw-slider-arrow--on::before{ rotate: 135deg; translate: -25% 0; }

/* The same thin marks the product list uses, and the same settings behind
   them — one idea, written once. */
.rhw-slider-marks{
  display: flex;
  justify-content: center;
  align-items: center;
  gap: var(--rhw-bar-gap, 6px);
  margin-block-start: var(--rhw-bar-away, .9rem);
}
.rhw-slider-marks .rhw-slider-mark{
  flex: 0 0 auto;
  padding: 0;
  margin: 0;
  border: 0;
  min-inline-size: 0;
  min-block-size: 0;
  font-size: 0;
  line-height: 0;
  border-radius: 999px;
  background: var(--rhw-bar-off, rgba(127,127,127,.4));
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  inline-size: var(--rhw-bar-long, 22px);
  block-size: var(--rhw-bar-thick, 3px);
  transition: background var(--rhw-map-ease, .35s) ease,
              inline-size var(--rhw-map-ease, .35s) ease;
}
.rhw-slider-marks .rhw-slider-mark:hover,
.rhw-slider-marks .rhw-slider-mark:focus-visible{ background: var(--rhw-bar-over, var(--rhw-bar-on, currentColor)); }
.rhw-slider-marks .rhw-slider-mark.is-on{ background: var(--rhw-bar-on, currentColor); }
.rhw-slider-marks .rhw-slider-mark:focus{ outline: none; }
.rhw-slider-marks .rhw-slider-mark:focus-visible{ outline: 2px solid var(--rhw-bar-on, currentColor); outline-offset: 3px; }

.rhw-slider--bare{
  padding: 1.25rem;
  border: 1px dashed currentColor;
  border-radius: 12px;
  opacity: .6;
  text-align: center;
}

@media (prefers-reduced-motion: reduce){
  .rhw-slider-track{ transition: none; }
}

/* --------------------------------------------------------------------- price
 * Three parts on one line, each free to be sized on its own. The line they
 * share is the writing line rather than the box, so a figure twice the size of
 * its label still sits on the same rule as the label instead of dragging it.
 */
.rhw-price{
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--rhw-price-gap, .45em);
  line-height: 1.2;
}
.rhw-price--stack{
  flex-direction: column;
  align-items: flex-start;
  gap: var(--rhw-price-gap, .2em);
}
/* The figure and its currency travel together: split across two lines they read
   as two different numbers. */
.rhw-price-amount{
  display: inline-flex;
  align-items: baseline;
  gap: var(--rhw-price-unit-gap, .35em);
}
.rhw-price--unit-under .rhw-price-amount{
  flex-direction: column;
  align-items: inherit;
}
.rhw-price-label{ display: inline; }
/* A colon belongs to the word before it, so it is inside the label and only
   the space after it is a control. */
.rhw-price-sep{ margin-inline-start: 0; }

/*
 * A hero with the picture switched off.
 *
 * The writing takes the whole width, and the row is only as tall as the
 * writing in it — there is no picture left to set the height, so nothing is
 * left over underneath. The placement controls still decide where the writing
 * stands, which is the point of turning the picture off in the first place.
 */
.rhw-hero--nopic .rhw-hero-media{ display: none; }
.rhw-hero--nopic .rhw-hero-copy{
  flex: 1 1 100%;
  max-width: 100%;
}
.rhw-hero--nopic .rhw-slide{ min-height: 0; }

/*
 * Filling the row it stands in.
 *
 * A hero beside something taller is stretched by the row; on its own the
 * slider is only as tall as its writing, so the height has to be passed down
 * to the slide before the writing can be placed anywhere within it.
 */
.rhw-hero--fill,
.rhw-hero--fill .rhw-hero-track,
.rhw-hero--fill .rhw-slide{ height: 100%; }

/* A figure turned over, so it looks towards the other side of the row. */
.rhw-strip-img--flip{ transform: scaleX(-1); }

/*
 * Glass that arrives on hover.
 *
 * The same surface the figure strip puts under its name box, made available as
 * a class so it can be dropped on anything — a product card in a listing, a
 * panel, a button — through Elementor's CSS Classes field. Nothing is drawn
 * until the pointer is on it, so a page of cards is not twenty blurred layers
 * being composited at rest.
 *
 * The layer sits behind the content rather than over it: the direct children
 * are lifted a step so text and pictures stay perfectly sharp while the blur
 * happens underneath them.
 */
.rhw-glass-hover{
  position: relative;
  isolation: isolate;
}
.rhw-glass-hover > *{
  position: relative;
  z-index: 1;
}
.rhw-glass-hover::before{
  content: "";
  position: absolute;
  inset: var(--rhw-glass-hover-inset, 0);
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--rhw-glass-hover-fade, .28s) var(--rhw-glass-hover-curve, ease);

  background-image:
    linear-gradient(115deg,
      rgba(var(--bm-glass-tint, 255,255,255), calc(.22 * var(--rhw-glass-hover-sheen, 1))) 0%,
      rgba(var(--bm-glass-tint, 255,255,255), 0) 34%,
      rgba(var(--bm-glass-tint, 255,255,255), 0) 66%,
      rgba(var(--bm-glass-tint, 255,255,255), calc(.10 * var(--rhw-glass-hover-sheen, 1))) 100%),
    linear-gradient(to bottom,
      rgba(var(--bm-glass-tint, 255,255,255), var(--bm-glass-a1, .20)),
      rgba(var(--bm-glass-tint, 255,255,255), var(--bm-glass-a2, .07)));
  box-shadow:
    inset 0 0 0 1px rgba(var(--bm-glass-tint, 255,255,255), var(--bm-glass-edge, .24)),
    inset 0 1px 0 rgba(var(--bm-glass-tint, 255,255,255), var(--bm-glass-hi, .42)),
    var(--bm-glass-lift, 0 10px 30px -12px rgba(0,0,0,.55));
}

/* Keyboard reaches it too, so the card is not a pointer-only trick. */
.rhw-glass-hover:hover::before,
.rhw-glass-hover:focus-within::before{
  opacity: 1;
  /* The blur is asked for here rather than above. A backdrop-filter costs the
   * compositor a layer for every element that carries one, whether or not it
   * can be seen, and a page of listing cards carries dozens. Asked for only
   * while the pointer is on a card, one card pays instead of all of them. */
  -webkit-backdrop-filter: blur(var(--rhw-glass-hover-blur, var(--bm-glass-blur, 20px))) saturate(var(--bm-glass-sat, 1.7));
  backdrop-filter: blur(var(--rhw-glass-hover-blur, var(--bm-glass-blur, 20px))) saturate(var(--bm-glass-sat, 1.7));
}

/* Somebody who has asked their system for less movement still gets the
   surface, just without the fade. */
@media (prefers-reduced-motion: reduce){
  .rhw-glass-hover::before{ transition: none; }
}

/* ---------------------------------------------------------------------------
 * Glass, on the element itself
 *
 * Typed into Elementor's CSS Classes field on a container, these make that
 * container out of glass. The surface is set on the element rather than on a
 * layer above it, which is what keeps a card from looking like a box inside
 * a box.
 *
 * Two surfaces, because one cannot serve both grounds. A white veil is
 * invisible on a white section; a smoked one disappears on a dark section.
 * Pick by the ground the element sits on:
 *
 *   rhw-glass-all    — on a dark or strongly coloured ground
 *   rhw-glass-smoke  — on a white or pale ground
 *
 * Neither casts a shadow. Inside a slider, or any box that clips what leaves
 * it, a shadow is cut off in a straight line across the rounded corners and
 * reads as a square edge. --rhw-glass-all-lift adds one where nothing clips.
 */
:root{
  --rhw-glass-all-blur: 6px;
  --rhw-glass-all-fill: .07;
  --rhw-glass-all-edge: .3;
  --rhw-glass-all-radius: 20px;
  --rhw-glass-all-fade: .28s;

  --rhw-glass-smoke-blur: 8px;
  --rhw-glass-smoke-sat: 1.15;
  --rhw-glass-smoke-fill: .07;
  --rhw-glass-smoke-edge: .14;

  /* What the pointer adds.
   *
   * These were written into the rule itself as fallbacks and were far too
   * strong: a quarter of black over a card turns a lilac panel to slate, which
   * reads as the card going out rather than coming forward. Half that is
   * enough to say the card has been picked up, and the edge and the lift do
   * the rest. They are named here so the strength can be changed in one place. */
  --rhw-glass-smoke-fill-on: .12;
  --rhw-glass-smoke-edge-on: .26;
  --rhw-glass-smoke-blur-on: 14px;
  --rhw-glass-smoke-sat-on: 1.3;

  /* The white surface over colour is left where it was; nobody has asked for
     it to be softer, and it is read against a dark ground rather than a pale
     one. */
  --rhw-glass-all-fill-on: .22;
  --rhw-glass-all-edge-on: .65;
  --rhw-glass-all-blur-on: 18px;

  /* How far in from each edge the smoke has faded to nothing.
   *
   * The sides used to be zero, which is invisible on a band that runs the full
   * width of the page and a hard vertical line on a band that does not: the
   * canvas simply stopped, and the seam read as a border down the page. All
   * four sides fade now, so the smoke ends where it ends without drawing an
   * edge. Named here so one band can be given its own if it needs one. */
  /* How big one puff of smoke is.
   *
   * The simulation drew every puff at a fixed size written into the shader
   * call, which on a band the width of the page reads as a cloud rather than a
   * wisp. It is a dial now, and set smaller than it was. Larger for a hero,
   * smaller for a band standing behind text. */
  --bm-fluid-size: 0.34;

  --rhw-smoke-top: 22%;
  --rhw-smoke-bottom: 12%;
  --rhw-smoke-left: 9%;
  --rhw-smoke-right: 9%;
}

.rhw-glass-all,
.rhw-glass-all-hover,
.rhw-glass-smoke,
.rhw-glass-smoke-hover{
  position: relative;
  overflow: hidden;
  border-radius: var(--rhw-glass-all-radius);
  border: 1px solid transparent !important;
}

/*
 * The veil is painted on a layer of its own rather than on the box.
 *
 * The class is written twice in each selector on purpose. Elementor claims
 * ::before on every container for its background overlay, with `content:
 * var(--background-overlay)`, and that rule carries exactly the same weight as
 * a single class of ours. Where it lands second it wins, the content resolves
 * to nothing, and the veil is never generated at all: the box keeps its edge
 * and loses its surface, which is precisely what a glass class failing looks
 * like. Doubling the class settles it without reaching for !important.
 *
 * Painted on the box it had to be said with !important, or Elementor's own
 * background beat it — and that left the Background control in the panel dead:
 * a colour could be chosen and nothing happened. On its own layer the two stop
 * competing. The box keeps its Background control, and the glass lies over
 * whatever is chosen there, which is what glass does.
 */
.rhw-glass-all.rhw-glass-all::before,
.rhw-glass-all-hover.rhw-glass-all-hover::before,
.rhw-glass-smoke.rhw-glass-smoke::before,
.rhw-glass-smoke-hover.rhw-glass-smoke-hover::before{
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--rhw-glass-all-fade) ease;
}

.rhw-glass-all.rhw-glass-all::before,
.rhw-glass-smoke.rhw-glass-smoke::before,
.rhw-glass-all-hover.rhw-glass-all-hover:hover::before,
.rhw-glass-all-hover.rhw-glass-all-hover:focus-within::before,
.rhw-glass-smoke-hover.rhw-glass-smoke-hover:hover::before,
.rhw-glass-smoke-hover.rhw-glass-smoke-hover:focus-within::before{
  opacity: 1;
}

/* Whatever the box holds sits above the veil rather than under it. */
.rhw-glass-all > *,
.rhw-glass-all-hover > *,
.rhw-glass-smoke > *,
.rhw-glass-smoke-hover > *{
  position: relative;
  z-index: 1;
}

/* On a dark ground: a white veil, the way glass reads over colour. */
.rhw-glass-all.rhw-glass-all::before,
.rhw-glass-all-hover.rhw-glass-all-hover::before{
  background: rgba(255,255,255, var(--rhw-glass-all-fill));
  -webkit-backdrop-filter: blur(var(--rhw-glass-all-blur));
  backdrop-filter: blur(var(--rhw-glass-all-blur));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.5),
    inset 0 -1px 0 rgba(255,255,255,.1),
    inset 0 0 4px 2px rgba(255,255,255,.2);
}

.rhw-glass-all,
.rhw-glass-all-hover:hover,
.rhw-glass-all-hover:focus-within{
  border-color: rgba(255,255,255, var(--rhw-glass-all-edge)) !important;
  box-shadow: var(--rhw-glass-all-lift, 0 0 0 0 rgba(0,0,0,0));
}

/* On a light ground: smoked glass, a trace darker than the page. */
.rhw-glass-smoke.rhw-glass-smoke::before,
.rhw-glass-smoke-hover.rhw-glass-smoke-hover::before{
  background: rgba(0,0,0, var(--rhw-glass-smoke-fill));
  -webkit-backdrop-filter: blur(var(--rhw-glass-smoke-blur)) saturate(var(--rhw-glass-smoke-sat));
  backdrop-filter: blur(var(--rhw-glass-smoke-blur)) saturate(var(--rhw-glass-smoke-sat));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.6),
    inset 0 0 0 1px rgba(255,255,255,.25);
}

.rhw-glass-smoke,
.rhw-glass-smoke-hover:hover,
.rhw-glass-smoke-hover:focus-within{
  border-color: rgba(0,0,0, var(--rhw-glass-smoke-edge)) !important;
  box-shadow: var(--rhw-glass-all-lift, 0 0 0 0 rgba(0,0,0,0));
}

/* Held back until the pointer arrives. The border is there from the start and
 * merely transparent, so nothing shifts by a pixel. */
.rhw-glass-all-hover,
.rhw-glass-smoke-hover{
  transition:
    background var(--rhw-glass-all-fade) ease,
    border-color var(--rhw-glass-all-fade) ease,
    box-shadow var(--rhw-glass-all-fade) ease,
    -webkit-backdrop-filter var(--rhw-glass-all-fade) ease,
    backdrop-filter var(--rhw-glass-all-fade) ease;
}

/* A glass box trims whatever reaches its edge, which is what the rounded
 * corners are for and exactly wrong for a box holding a menu: the submenu
 * hangs below the box and is cut off in a straight line. This class lets that
 * box spill, and lifts what hangs out of it above the surface, since a pane
 * that blurs what is behind it will otherwise be painted over the thing that
 * left it. The corners no longer trim a picture inside, so it belongs on the
 * box that carries a menu rather than on every glass box.
 *
 *   rhw-glass-open      on the same box as the glass class
 *   --rhw-glass-open-z  how far above the surface what spills is lifted
 */
.rhw-glass-open{ overflow: visible !important; }

.rhw-glass-open .elementor-nav-menu--dropdown,
.rhw-glass-open .sub-menu,
.rhw-glass-open .rhw-spill{
  position: relative;
  z-index: var(--rhw-glass-open-z, 99);
}


/* ---------------------------------------------------------------------------
 * A picture with writing over it
 *
 * A background image has no height of its own: the box has to be given one by
 * hand, and every screen wants a different one. A real picture brings its own
 * height, so the box is exactly as tall as the picture and nothing has to be
 * guessed.
 *
 * rhw-canvas goes on the container. The image widget inside it stays in the
 * flow and sets the height; everything else in that container is lifted over
 * the picture instead of landing underneath it. The overlay keeps Elementor's
 * own alignment controls, so where the writing sits is still set in the panel.
 *
 * The picture must be a direct child of the container that carries the class.
 */
.rhw-canvas{
  position: relative !important;
}

.rhw-canvas > .elementor-widget-image{
  position: relative;
  z-index: 0;
}
.rhw-canvas > .elementor-widget-image img{
  display: block;
  width: 100%;
  height: auto;
}

/* Everything that is not the picture lies over it. rhw-over says the same for
 * an element anywhere inside, so a box nested a level down can be lifted too. */
.rhw-canvas > :not(.elementor-widget-image),
.rhw-over{
  position: absolute !important;
  inset: var(--rhw-over-inset, 0);
  z-index: 2;
  margin: 0 !important;
}

/* The empty parts of the overlay do not intercept the pointer, so a picture
 * that is a link stays clickable around the writing. */
.rhw-over{ pointer-events: none; }
.rhw-over > *{ pointer-events: auto; }

/* ---------------------------------------------------------------------------
 * The Picture widget
 *
 * A real picture, so the box it stands in is exactly as tall as the picture at
 * every width. The alignment control moves the picture inside the widget; the
 * width control sizes the picture itself, so the two do not fight.
 */
.rhw-picture{
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  width: 100%;
}

/*
 * A height in per cent has to be measured against something. Elementor puts two
 * boxes between the container and the picture, and a box of no stated height
 * gives a percentage nothing to work from — so the height is passed down the
 * chain. Where the container is as tall as its own contents this changes
 * nothing, because a hundred per cent of an automatic height is still
 * automatic; where the container has been given a real height, the picture can
 * now take a share of it.
 */
.elementor-widget-robinhood-picture,
.elementor-widget-robinhood-picture > .elementor-widget-container{
  height: 100%;
}
.rhw-picture-link{
  display: block;
  line-height: 0;
  width: 100%;
}

/*
 * Several pictures taking turns in one place.
 *
 * They share a single grid cell rather than being stacked with absolute
 * positioning, so the box is as tall as the tallest of them and nothing below
 * moves as they change. With one picture the cell simply holds that one, and
 * the widget behaves exactly as it did before.
 */
.rhw-picture-stack{
  display: grid;
  grid-template-areas: "shot";
  width: 100%;
}
.rhw-picture-stack > .rhw-picture-img{
  grid-area: shot;
}
.rhw-picture--many .rhw-picture-stack > .rhw-picture-img{
  opacity: 0;
  transition:
    opacity   var(--rhw-picture-fade, .6s) var(--rhw-picture-ease, ease),
    transform var(--rhw-picture-fade, .6s) var(--rhw-picture-ease, ease),
    filter    var(--rhw-picture-fade, .6s) var(--rhw-picture-ease, ease);
}
.rhw-picture--many .rhw-picture-stack > .rhw-picture-img.is-on{
  opacity: 1;
  transform: none;
  filter: none;
}

/*
 * How one picture gives way to the next.
 *
 * Each is written as the state a picture is in before it is shown; the one on
 * screen is always at rest, so the same rule covers both arriving and leaving.
 */
.rhw-picture--fx-slide-x .rhw-picture-stack > .rhw-picture-img{
  transform: translateX(var(--rhw-picture-shift, 6%));
}
.rhw-picture--fx-slide-y .rhw-picture-stack > .rhw-picture-img{
  transform: translateY(var(--rhw-picture-shift, 6%));
}
.rhw-picture--fx-zoom .rhw-picture-stack > .rhw-picture-img{
  transform: scale(var(--rhw-picture-grow, 1.06));
}
.rhw-picture--fx-blur .rhw-picture-stack > .rhw-picture-img{
  filter: blur(var(--rhw-picture-haze, 10px));
}
.rhw-picture--fx-cut .rhw-picture-stack > .rhw-picture-img{
  transition-duration: 0s;
}

/* Nothing is hidden from a reader who has asked for less movement: the
   pictures still change, they simply cut rather than fade. */
@media (prefers-reduced-motion: reduce){
  .rhw-picture--many .rhw-picture-stack > .rhw-picture-img{ transition-duration: 0s; }
}

.rhw-picture-dots{
  display: flex;
  gap: var(--rhw-picture-dot-gap, 8px);
  justify-content: var(--rhw-picture-dot-at, center);
  width: 100%;
  margin-block-start: var(--rhw-picture-dot-top, 12px);
}
.rhw-picture-dot{
  appearance: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  width: var(--rhw-picture-dot-size, 8px);
  height: var(--rhw-picture-dot-size, 8px);
  border-radius: 999px;
  background: var(--rhw-picture-dot-off, rgba(0,0,0,.25));
  transition: background .25s ease, transform .25s ease;
}
.rhw-picture-dot.is-on{
  background: var(--rhw-picture-dot-on, currentColor);
  transform: scale(1.25);
}
.rhw-picture-img{
  display: block;
  max-width: 100%;
  height: auto;
  object-position: center center;
  transition-property: opacity, filter, transform;
  transition-duration: .3s;
  transition-timing-function: ease;
}
.rhw-picture-caption{ margin: 0; }

/*
 * The veil: a layer between the picture and whatever is written over it.
 *
 * It covers the picture and nothing else, so it can be as dark as the writing
 * needs without touching the writing. Pointer events pass through it — a
 * picture that links somewhere still links from every part of itself.
 */
.rhw-picture-veil{
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 1;
}

/*
 * The second layer sits on the first and still under the writing, so a
 * gradient running one way and a gradient running the other can both be seen.
 * One layer cannot do it: a linear gradient has a single direction, and making
 * one layer dark at both ends means a three-stop gradient whose middle has to
 * be re-balanced every time either end changes.
 */
.rhw-picture-veil-2{ z-index: 2; }
.rhw-picture{ position: relative; }
.rhw-picture-stack{ position: relative; z-index: 0; }


/* ---------------------------------------------------------------------------
 * The Product Count
 *
 * One line with a number in it, and a quieter line under it. Nothing is
 * positioned: the box is a column so the alignment control moves both lines
 * together and the space between them is a single number.
 */
.rhw-count{
  display: flex;
  flex-direction: column;
  align-items: stretch;
  text-align: center;
  width: 100%;
}
.rhw-count-line{
  margin: 0;
  width: 100%;
  line-height: 1.15;
}
.rhw-count-note{
  margin: var(--rhw-count-gap, 8px) 0 0;
  width: 100%;
  line-height: 1.4;
}

/* ---------------------------------------------------------------------------
 * A background overlay is scenery, not a surface to be touched
 *
 * A container given a background overlay in Elementor grows a layer across its
 * whole area. It is decoration and nothing else, but it still answers the
 * pointer and is drawn over everything inside — so a card under it never
 * learns that the pointer is on it.
 */
.e-con::before,
.e-con > .e-con-inner::before{
  pointer-events: none;
}

/* ---------------------------------------------------------------------------
 * A product card standing on a dark ground
 *
 * The surface only. Colour and type are set on the widgets in the builder,
 * where they belong, and nothing here overrules them.
 */
.rhw-card-dark{
  --rhw-card-fill:     .05;
  --rhw-card-fill-on:  .11;
  --rhw-card-edge:     .14;
  --rhw-card-edge-on:  .30;
  --rhw-card-blur:     14px;
  --rhw-card-fade:     .28s;

  position: relative;
  overflow: hidden;
  border-style: solid !important;
  border-width: 1px !important;
  border-color: rgba(255,255,255, var(--rhw-card-edge)) !important;
  background: rgba(255,255,255, var(--rhw-card-fill)) !important;
  /* No blur at rest. These cards stand on a coloured band, and a gradient
   * blurred is the same gradient; what reads as glass here is the veil and the
   * edge, not the blur. The layer it would cost, times every card on the page,
   * is what made scrolling heavy. */
  box-shadow: inset 0 1px 0 rgba(255,255,255,.16) !important;
  transition:
    background   var(--rhw-card-fade) ease,
    border-color var(--rhw-card-fade) ease,
    box-shadow   var(--rhw-card-fade) ease;
}
.rhw-card-dark:hover,
.rhw-card-dark:focus-within{
  border-color: rgba(255,255,255, var(--rhw-card-edge-on)) !important;
  background: rgba(255,255,255, var(--rhw-card-fill-on)) !important;
  -webkit-backdrop-filter: blur(var(--rhw-card-blur)) saturate(1.2) !important;
  backdrop-filter: blur(var(--rhw-card-blur)) saturate(1.2) !important;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.38),
    inset 0 0 0 1px rgba(255,255,255,.10) !important;
}

/* ---------------------------------------------------------------------------
 * Smoke that stops before the edge
 *
 * The fluid canvas fills its container exactly, so where one section ends and
 * the next begins the smoke is cut off in a straight line and the seam becomes
 * visible. Fading the canvas towards its own edges costs nothing and leaves
 * the simulation untouched.
 */
.rhw-smoke-fade > canvas.bm-fluid-canvas{
  -webkit-mask-image:
    linear-gradient(to bottom, transparent 0, #000 var(--rhw-smoke-top, 22%), #000 calc(100% - var(--rhw-smoke-bottom, 12%)), transparent 100%),
    linear-gradient(to right,  transparent 0, #000 var(--rhw-smoke-left, 0%),  #000 calc(100% - var(--rhw-smoke-right, 0%)),  transparent 100%);
  mask-image:
    linear-gradient(to bottom, transparent 0, #000 var(--rhw-smoke-top, 22%), #000 calc(100% - var(--rhw-smoke-bottom, 12%)), transparent 100%),
    linear-gradient(to right,  transparent 0, #000 var(--rhw-smoke-left, 0%),  #000 calc(100% - var(--rhw-smoke-right, 0%)),  transparent 100%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}


/*
 * Smoke that waits for the hand
 * -----------------------------
 * The fluid puffs on its own every few seconds so a section is never dead.
 * Over a photograph that reads as something happening by itself, which is not
 * always wanted; here the smoke should only answer the pointer. Setting the
 * interval to zero switches the automatic puffs off — the simulation still
 * runs, and a hand moving across the band still leaves a trail.
 */
body .rhw-smoke-onmove{
  --bm-fluid-idle: 0;
}


/*
 * Smoke in front of a picture
 * ---------------------------
 * The fluid canvas is deliberately painted at z-index -1, behind whatever the
 * container holds, so smoke drifts between the cards of a listing. That is the
 * right default everywhere except one case: a band whose whole surface is a
 * photograph. There the picture is opaque and in flow, so it paints over the
 * canvas and the smoke is drawn where nobody can see it.
 *
 * When a fluid container holds a Picture widget, the smoke belongs on top of
 * the photograph. Elementor's own overlay copy sits in an absolutely
 * positioned box at z-index 2, so lifting the canvas to 1 puts the smoke above
 * the image and still under the writing.
 *
 * `body` is here only to out-weigh the plugin's own `body [class*="bm-fluid"]`
 * rule, which is otherwise the more specific of the two.
 */
body [class*="bm-fluid"]:has(.rhw-picture) > canvas.bm-fluid-canvas{
  /* Zero, not one. One put the canvas above the picture and above the words
     with it, and smoke drifting across a headline is smoke in the way. Zero
     clears the picture and the background overlay and stops there; each band
     then lifts its own children over the canvas from its Custom CSS, so the
     text is always the top layer. */
  z-index: 0;
}

/* The escape hatch: put it back behind, for a band where the picture should
   stay clean. */
body .rhw-smoke-back > canvas.bm-fluid-canvas{
  z-index: -1;
}

/*
 * Where the automatic smoke sits
 * ------------------------------
 * The fluid now puffs at the two ends of a band and leaves the middle clear,
 * because that is where the writing usually is. The hero at the top of the
 * page is the exception: there the smoke belongs behind the headline, gathered
 * in the centre. This class says so, and can go on any other container that
 * wants the old behaviour.
 */
body .bm-fluid-middle{
  --bm-fluid-idle-bias: 1;
}


/*
 * Smoke that climbs from the floor
 * --------------------------------
 * The automatic puffs start near the ceiling and fall, which reads as smoke
 * drifting down past a figure. A band of products standing on the ground wants
 * the opposite: smoke rising off the floor behind them.
 */
body .bm-fluid-rise{
  --bm-fluid-idle-rise: 1;
}



/*
 * The picture, cut
 * ----------------
 * A circle, or the softer uneven round that reads as a hand-cut shape. The cut
 * is on the picture itself rather than a wrapper, so the border, the shadow and
 * the hover scale that were already there keep following the same edge.
 *
 * The drift is optional and off unless asked for. It animates border-radius,
 * which the browser can interpolate without laying anything out again, so it
 * costs nothing to run — and it stops for anyone who has asked their system
 * for less movement.
 */
.rhw-picture--circle .rhw-picture-img{ border-radius: 50%; }
.rhw-picture--blob .rhw-picture-img{ border-radius: 44% 56% 52% 48% / 48% 44% 56% 52%; }

.rhw-picture--morph .rhw-picture-img{
  animation: rhw-picture-drift var(--rhw-picture-morph, 14s) ease-in-out infinite;
}
@keyframes rhw-picture-drift{
  0%,
  100% { border-radius: 44% 56% 52% 48% / 48% 44% 56% 52%; }
  33%  { border-radius: 58% 42% 45% 55% / 42% 58% 42% 58%; }
  66%  { border-radius: 47% 53% 61% 39% / 56% 41% 59% 44%; }
}
@media (prefers-reduced-motion: reduce){
  .rhw-picture--morph .rhw-picture-img{ animation: none; }
}

/* ---------------------------------------------------------------
   Product card image frame
   Every product shot sits in the same square box at the same scale.
   The source files are square and normalised to 92% of the longest
   side, so this only guards the box: a future non-square upload can
   no longer make one card taller or one product larger than the rest.
   contain, never cover, so straps and buckles are never cropped.
--------------------------------------------------------------- */
.jet-listing-grid__item .elementor-widget-image img,
.jet-listing-grid__item .jet-listing-dynamic-image img,
.jet-listing-grid__item img.attachment-medium_large,
.jet-listing-grid__item .elementor-widget-theme-post-featured-image img{
  aspect-ratio: 1 / 1;
  width: 100%;
  height: auto;
  object-fit: contain;
  object-position: center;
}

/* ---------------------------------------------------------------------------
 * The place, and the ways to reach it
 *
 * A map, the words for the address, and a row of ways to act on it. Every
 * colour is a variable set from the panel, so the same widget sits on a dark
 * footer and on a white page without a second stylesheet.
 */
.rhw-loc{
  --rhw-loc-gap: 14px;
  --rhw-loc-map-gap: 12px;
  display: block;
  width: 100%;
}

.rhw-loc-map{
  --rhw-loc-edge: rgba(255,255,255,0.22);
  position: relative;
  width: 100%;
  height: 260px;
  overflow: hidden;
  border-radius: 14px;
  border: 1px solid var(--rhw-loc-edge);
  background: rgba(0,0,0,0.15);
}
.rhw-loc-map iframe{
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

/* Grey while it waits, in colour when it is being looked at. */
.rhw-loc-map--mute iframe{
  filter: grayscale(1) contrast(1.05);
  transition: filter .35s ease;
}
.rhw-loc-map--mute:hover iframe,
.rhw-loc-map--mute:focus-within iframe{ filter: none; }

/* The gap under the map is set once, on the box that holds the words, so it
 * stays the same whether the name is shown, the address is shown, or only one
 * of the two — and it is nothing at all when there is no map above them. */
.rhw-loc-words{ margin: 0; }
.rhw-loc-map + .rhw-loc-words{ margin-top: var(--rhw-loc-map-gap); }

.rhw-loc-label{
  margin: 0;
  font-weight: 600;
  line-height: 1.35;
}
.rhw-loc-address{
  margin: 6px 0 0;
  line-height: 1.7;
  opacity: .9;
}
.rhw-loc-label + .rhw-loc-address{ margin-top: 6px; }
.rhw-loc-words > .rhw-loc-address:first-child{ margin-top: 0; }

.rhw-loc-links{
  --rhw-loc-icon:   20px;
  --rhw-loc-pad:    10px;
  --rhw-loc-round:  50%;
  --rhw-loc-ink:     #fff;
  --rhw-loc-fill:    rgba(255,255,255,0.10);
  --rhw-loc-line:    rgba(255,255,255,0.20);
  --rhw-loc-ink-on:  #fff;
  --rhw-loc-fill-on: rgba(255,255,255,0.26);
  --rhw-loc-line-on: rgba(255,255,255,0.45);

  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: var(--rhw-loc-gap);
}

.rhw-loc-link{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--rhw-loc-pad);
  border-radius: var(--rhw-loc-round);
  color: var(--rhw-loc-ink);
  background: var(--rhw-loc-fill);
  border: 1px solid var(--rhw-loc-line);
  text-decoration: none;
  transition: color .22s ease, background .22s ease, border-color .22s ease, transform .22s ease;
}
.rhw-loc-link:hover,
.rhw-loc-link:focus-visible{
  color: var(--rhw-loc-ink-on);
  background: var(--rhw-loc-fill-on);
  border-color: var(--rhw-loc-line-on);
  transform: translateY(-2px);
}
.rhw-loc-link:focus-visible{ outline: 2px solid currentColor; outline-offset: 2px; }

.rhw-loc-icon{
  display: block;
  width:  var(--rhw-loc-icon);
  height: var(--rhw-loc-icon);
}

/* The name is for a screen reader, not for the eye — the icon carries it. */
.rhw-loc-name{
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce){
  .rhw-loc-link{ transition: none; }
  .rhw-loc-link:hover{ transform: none; }
  .rhw-loc-map--mute iframe{ transition: none; }
}

/* A link parked on a hash until its real address arrives: visible, laid out,
 * and plainly not ready — rather than an icon that opens an empty tab. */
.rhw-loc-link--parked{ opacity: .55; }
.rhw-loc-link--parked:hover{ transform: none; }



/* ---------------------------------------------------------------- colours --
 *
 * A word and the colour it names, side by side. The swatch is an empty box
 * filled by one variable written on it, so a colour that came out of a field
 * needs no rule of its own and nothing has to be generated in a stylesheet.
 *
 * The chequer behind it is what makes a white swatch readable on a white page
 * and shows through anything transparent; the edge does the rest.
 */
.rhw-colours{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--rhw-colours-gap, .75rem 1.1rem);
  width: var(--rhw-fill, auto);

  --rhw-colour-size: 18px;
  --rhw-colour-radius: 4px;
  --rhw-colour-edge: rgba(0,0,0,.18);
  --rhw-colour-edge-width: 1px;
  --rhw-colour-inner-gap: .5em;
}

.rhw-colour{
  display: inline-flex;
  align-items: center;
  gap: var(--rhw-colour-inner-gap);
  line-height: 1.2;
}

.rhw-colour-chip{
  flex: none;
  display: block;
  width: var(--rhw-colour-size);
  height: var(--rhw-colour-size);
  border-radius: var(--rhw-colour-radius);
  border: var(--rhw-colour-edge-width) solid var(--rhw-colour-edge);
  /* The colour is the top layer and the chequer lies under it, so a solid
   * colour hides the chequer and a transparent one lets it show through.
   * Painting the colour as a background-colour instead would put the chequer
   * on top of it and every swatch would come out chequered. */
  background-color: #ffffff;
  background-image:
    linear-gradient(var(--rhw-colour, transparent), var(--rhw-colour, transparent)),
    linear-gradient(45deg, rgba(0,0,0,.09) 25%, transparent 25%, transparent 75%, rgba(0,0,0,.09) 75%),
    linear-gradient(45deg, rgba(0,0,0,.09) 25%, transparent 25%, transparent 75%, rgba(0,0,0,.09) 75%);
  background-size: auto, 8px 8px, 8px 8px;
  background-position: 0 0, 0 0, 4px 4px;
  background-origin: border-box;
}

.rhw-colour-name{ font-family: inherit; }


/* ---------------------------------------------------------- specifications --
 *
 * Rows, not articles. A label and its answer sit on one line with a hairline
 * between rows, which is how a datasheet is read: down the labels until the
 * one that matters, then across.
 *
 * The line is a variable rather than a rule, so a section that wants no lines
 * simply leaves the colour empty.
 */
.rhw-specs{
  display: grid;
  grid-template-columns: var(--rhw-specs-template, minmax(0, 1fr));
  column-gap: var(--rhw-specs-col-gap, 48px);
  width: var(--rhw-fill, 100%);

  --rhw-specs-pad: 10px;
  --rhw-specs-label-width: 42%;
}

.rhw-spec{
  display: flex;
  align-items: baseline;
  gap: 1em;
  padding: var(--rhw-specs-pad) 0;
  border-bottom: 1px solid var(--rhw-specs-rule, transparent);
  min-width: 0;
}

/* The last row of every column, not only the last of the list. */
.rhw-spec:last-child{ border-bottom: 0; }

.rhw-spec-label{
  flex: none;
  width: var(--rhw-specs-label-width);
  font-family: inherit;
}

.rhw-spec-value{
  flex: 1 1 auto;
  min-width: 0;
  font-family: inherit;
}

.rhw-specs--under .rhw-spec{
  display: block;
}
.rhw-specs--under .rhw-spec-label{
  display: block;
  width: auto;
  margin-bottom: .25em;
}


/* The ruled look, so a specification table and a size table read as one family.
 * Same ruling and same corner, a different tint of the same purple, because two
 * tables on one page that are almost alike are worse than two that are either
 * the same or plainly different. */
.rhw-specs--table{
  border: 1px solid var(--rhw-specs-border, #e5e7eb);
  border-radius: var(--rhw-specs-radius, 10px);
  overflow: hidden;
  background: #ffffff;
  column-gap: 0;
}

.rhw-specs--table .rhw-spec{
  display: grid;
  grid-template-columns: var(--rhw-specs-label-width, 42%) minmax(0, 1fr);
  align-items: stretch;
  gap: 0;
  padding: 0;
  border-bottom: 1px solid var(--rhw-specs-border, #e5e7eb);
}

.rhw-specs--table .rhw-spec:last-child{ border-bottom: 0; }

.rhw-specs--table .rhw-spec-label,
.rhw-specs--table .rhw-spec-value{
  width: auto;
  padding: var(--rhw-specs-pad, 7px) 14px;
  /* A table is read down a column, so its lines sit closer than a
   * paragraph's. Left to the page's own line height a one word answer
   * stood in a row half as tall again as it needed. */
  line-height: var(--rhw-specs-line, 1.45);
}

.rhw-specs--table .rhw-spec-label{
  background: var(--rhw-specs-fill, #E2C9EE);
  border-inline-end: 1px solid var(--rhw-specs-border, #e5e7eb);
}

.rhw-specs--table .rhw-spec:nth-child(even) .rhw-spec-value{
  background: var(--rhw-specs-zebra, #FAF6FD);
}

.rhw-specs--table .rhw-spec:hover .rhw-spec-value{
  background: var(--rhw-specs-hover, #F1E4F8);
}

/* Under the answer rather than beside it, the two cells stack and the ruling
 * between them would cut the row in half, so it is dropped. */
.rhw-specs--table.rhw-specs--under .rhw-spec{ display: block; }
.rhw-specs--table.rhw-specs--under .rhw-spec-label{ border-inline-end: 0; }


/* ------------------------------------------------- questions and answers --
 *
 * Built on the browser's own disclosure element, so opening and closing needs
 * no script, keyboard and screen readers get it for nothing, and a question
 * whose answer is closed is still found by the browser's own page search.
 * Sharing one name is how the browser is told that opening one closes the
 * last, which is the only difference between the two behaviours offered.
 */
.rhw-qa{
  /* A column rather than a block, so the Gap control in the Layout section
   * has something to act on. A block box ignores gap entirely. */
  display: flex;
  flex-direction: column;
  width: var(--rhw-fill, 100%);

  --rhw-qa-pad: 14px;
  --rhw-qa-radius: 10px;
  --rhw-qa-intro-gap: 18px;
}

.rhw-qa-intro{
  /* Full width like the questions under it, or the section's Align Items
   * shrinks it to its own words and no text alignment can be seen. */
  width: 100%;
  margin: 0;
  font-family: inherit;
}

/* The theme zeroes a paragraph's margin with a selector of its own, so the
 * space under this line has to be said with at least as much weight or the
 * control that sets it does nothing. */
.rhw-qa > .rhw-qa-intro{
  margin-bottom: var(--rhw-qa-intro-gap);
}

.rhw-qa-item{
  /* A question is a row: it spans the list whatever the section's Align Items
   * says, or an open answer would be full width while the closed questions
   * beside it shrink to their own words. */
  width: 100%;
  border-bottom: 1px solid var(--rhw-qa-rule, transparent);
  border-radius: var(--rhw-qa-radius);
}

.rhw-qa-item:last-child{ border-bottom: 0; }

.rhw-qa-item[open]{ background: var(--rhw-qa-face, transparent); }

/* A closed question is a control, and a control that does not answer the
 * pointer reads as text. The open one is left alone: it already shows what
 * state it is in. */
.rhw-qa-item:not([open]) > .rhw-qa-q{
  transition: background-color .18s ease, color .18s ease;
}

.rhw-qa-item:not([open]) > .rhw-qa-q:hover{
  background: var(--rhw-qa-hover-face, transparent);
  color: var(--rhw-qa-q-ink-hover, var(--rhw-qa-q-ink, inherit));
  border-radius: var(--rhw-qa-radius);
}

.rhw-qa-q{
  display: flex;
  /* Centred rather than on the baseline, because a row given a height of its
   * own should hold its words in the middle of it. */
  align-items: center;
  min-height: var(--rhw-qa-q-height, 0);
  justify-content: space-between;
  gap: 1em;
  /* The space above and below is its own dial, because that is the one that
   * makes a row shorter; the height control below can only make it taller. */
  padding: var(--rhw-qa-pad-y, var(--rhw-qa-pad)) var(--rhw-qa-pad);
  cursor: pointer;
  list-style: none;
  color: var(--rhw-qa-q-ink, inherit);
  font-family: inherit;
}

/* The browser's focus ring is kept, because it is how a keyboard finds its
 * place, and only recoloured so it belongs to the page. */
.rhw-qa-q:focus-visible{
  outline: 2px solid var(--rhw-qa-mark, currentColor);
  outline-offset: -2px;
  border-radius: var(--rhw-qa-radius);
}

/* Safari draws its own triangle unless both of these are said. */
.rhw-qa-q::-webkit-details-marker{ display: none; }
.rhw-qa-q::marker{ content: ''; }

/* The sign is drawn rather than typed, so it needs no font and no icon set:
 * a plus that loses its upright when the answer is open. */
.rhw-qa-q::after{
  content: '';
  flex: none;
  width: .62em;
  height: .62em;
  background:
    linear-gradient(currentColor, currentColor) center/100% 2px no-repeat,
    linear-gradient(currentColor, currentColor) center/2px 100% no-repeat;
  color: var(--rhw-qa-mark, currentColor);
  transition: transform .2s ease;
}

/* An open question sits on the panel rather than on the section behind it, so
 * it is allowed a colour of its own. Left unset it keeps the closed one and
 * nothing changes. */
.rhw-qa-item[open] > .rhw-qa-q{
  color: var(--rhw-qa-q-ink-open, var(--rhw-qa-q-ink, inherit));
}

.rhw-qa-item[open] > .rhw-qa-q::after{
  color: var(--rhw-qa-mark-open, var(--rhw-qa-mark, currentColor));
  background:
    linear-gradient(currentColor, currentColor) center/100% 2px no-repeat;
  transform: rotate(180deg);
}

.rhw-qa-a{
  padding: 0 var(--rhw-qa-pad) var(--rhw-qa-pad-y, var(--rhw-qa-pad));
  color: var(--rhw-qa-a-ink, inherit);
  font-family: inherit;
}

/* Opening.
 *
 * A disclosure snaps open, because the browser reveals its content in one
 * step. Where the panel's own box can be animated it is, from no height to
 * whatever the answer needs, which is the only way to do this without a
 * script. Everywhere else the answer still arrives, by fading and settling,
 * so nothing anywhere opens with a bang.
 */
.rhw-qa{ --rhw-qa-ease: .28s; }

@supports (interpolate-size: allow-keywords) {
  .rhw-qa{ interpolate-size: allow-keywords; }

  .rhw-qa-item::details-content{
    block-size: 0;
    overflow: hidden;
    transition:
      block-size var(--rhw-qa-ease) ease,
      content-visibility var(--rhw-qa-ease) allow-discrete;
  }

  .rhw-qa-item[open]::details-content{ block-size: auto; }
}

.rhw-qa-item[open] > .rhw-qa-a{
  animation: rhw-qa-arrive var(--rhw-qa-ease) ease both;
}

@keyframes rhw-qa-arrive{
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}

/* A reader who has asked for less movement gets the answer at once. */
@media (prefers-reduced-motion: reduce) {
  .rhw-qa-item::details-content{ transition: none; }
  .rhw-qa-item[open] > .rhw-qa-a{ animation: none; }
  .rhw-qa-q::after{ transition: none; }
}

.rhw-qa-a p{ margin: 0 0 .6em 0; }
.rhw-qa-a p:last-child{ margin-bottom: 0; }

/* The space inside a question is the same on both sides and in both states.
 * It used to be nought on the starting side until the answer was opened, so
 * that a closed question lined up with the running text beside it. That is
 * only right where a question has nothing drawn behind it: once a row has a
 * face, a rule and a rounded corner, a word that starts where the corner
 * starts reads as a fault, and the row visibly shifted sideways as it opened. */


/* ------------------------------------------------------ related products --
 *
 * Cards chosen by hand in the catalogue rather than by a rule. The whole card
 * is the link, so there is nothing to hunt for, and every picture is given the
 * same height while keeping its own shape inside it, or three products of
 * three different silhouettes would leave the names on three different lines.
 */
.rhw-related{
  display: grid;
  grid-template-columns: var(--rhw-related-template, repeat(3, minmax(0, 1fr)));
  gap: var(--rhw-related-gap, 20px);
  /* The Gap in the Layout section writes `gap` on this same element, so the
   * variable is the default and whatever the panel says wins. */
  width: var(--rhw-fill, 100%);

  --rhw-related-pad: 16px;
  --rhw-related-radius: 12px;
  --rhw-related-image: 160px;
}

.rhw-related-card{
  display: flex;
  flex-direction: column;
  gap: .35em;
  padding: var(--rhw-related-pad);
  border: 1px solid var(--rhw-related-edge, transparent);
  border-radius: var(--rhw-related-radius);
  background: var(--rhw-related-face, transparent);
  text-decoration: none;
  color: inherit;
  min-width: 0;
}

.rhw-related-shot{
  display: flex;
  align-items: center;
  justify-content: center;
  height: var(--rhw-related-image);
  margin-bottom: .5em;
}

.rhw-related-shot img{
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}

.rhw-related-code,
.rhw-related-name{
  display: block;
  font-family: inherit;
}


/* ------------------------------------------------------------- deferred --
 *
 * A band of glass costs the browser a blur on every scroll frame, and it pays
 * that price whether the band is on the screen or a thousand pixels below it.
 * This class lets the browser skip a band's rendering entirely until it comes
 * near the viewport, which leaves the design untouched and takes the work off
 * the scroll.
 *
 * The height hint keeps the scrollbar honest while a band is skipped. Not for
 * a band that holds a slider: a slider measures its slides on load and cannot
 * do that inside something the browser has not rendered.
 *
 *   rhw-defer              on a band well below the fold
 *   --rhw-defer-height     roughly how tall it is, such as 900px
 */
.rhw-defer{
  content-visibility: auto;
  contain-intrinsic-size: auto var(--rhw-defer-height, 700px);
}


/* ---------------------------------------------------------------- buttons --
 *
 * A button is a label, not a paragraph: a button never breaks its words across
 * two lines. Where the box it sits in is narrower than the words, the button
 * grows instead of wrapping, and on a small screen its side padding gives way
 * first so it still fits.
 */
.elementor-button .elementor-button-text,
.elementor-button-wrapper .elementor-button{
  white-space: nowrap;
}

@media (max-width: 1024px) {
  .elementor-button{
    padding-inline: clamp(10px, 3vw, 24px);
  }
}



/* ------------------------------------------------------- scrolling, softly --
 *
 * While the page is moving, the panels stop blurring what is behind them. See
 * the note in frontend.js: the veil and the edge stay, so a panel still reads
 * as glass, and the frame budget goes to the scroll instead of to twenty
 * backdrop readbacks a frame.
 */
html.rhw-scrolling *:not(header):not(header *):not(.elementor-location-header):not(.elementor-location-header *),
html.rhw-scrolling *:not(header):not(header *):not(.elementor-location-header):not(.elementor-location-header *)::before,
html.rhw-scrolling *:not(header):not(header *):not(.elementor-location-header):not(.elementor-location-header *)::after{
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}


/* A dropdown fades and nothing else.
 *
 * The menu inherits `transition: all`, which puts the blur behind the panel and
 * the panel's own size into the same animation as its opacity. Both are
 * expensive to interpolate and neither should move. */
.bm-glass-nav ul.sub-menu{
  transition-property: opacity, transform;
}


/* ---------------------------------------------------- how big one puff is --
 *
 * One size does not suit every band. On a tall hero a small puff reads as a
 * wisp; on a strip two hundred pixels deep the same puff is cut off top and
 * bottom before it has formed, and what is left looks like torn paper rather
 * than smoke. These two classes go on the container itself, beside the fluid
 * class, so a short band can be given something broad and soft and a tall one
 * something finer.
 */
body .rhw-smoke-lg{ --bm-fluid-size: 0.85; }
body .rhw-smoke-sm{ --bm-fluid-size: 0.20; }


/* ------------------------------------------------------------ a map, mono --
 *
 * Elementor's map widget is a Google embed in an iframe, which cannot be
 * restyled from the outside: the colours belong to Google. A grey filter over
 * the whole frame is the one thing that does work, and on a page built out of
 * violet and white a full-colour map is the only loud thing on it. Contrast is
 * lifted a little because grey scaling flattens the roads into the ground.
 *
 * The pointer brings the colour back, so anyone actually reading the map gets
 * the real thing.
 */
.rhw-map-mono iframe{
  filter: grayscale(1) contrast(1.06);
  transition: filter .35s ease;
}

.rhw-map-mono:hover iframe,
.rhw-map-mono:focus-within iframe{
  filter: grayscale(0) contrast(1);
}


/* ------------------------------------------------- the reCAPTCHA badge ----
 *
 * Google fixes its badge to the bottom right, which is where the WhatsApp
 * button already lives, so the two sat on top of each other. The badge moves
 * to the other corner. It stays visible, which is what Google's terms ask for:
 * hiding it is only allowed if the notice is written out in the form instead.
 */
.grecaptcha-badge{
  left: 14px !important;
  right: auto !important;
}


/* ------------------------------------------------- a glass button, tinted --
 *
 * The section buttons on the home page are made of the same glass as the rest
 * of the site, which is why they belong to it. A button that points at Waze or
 * at Google Maps has to be recognisable as that company's, and the two things
 * are not in conflict: the material stays, the tint changes.
 *
 * `bm-glass-btn` paints its surface from --bm-glass-tint, an RGB triple, so a
 * tint class is all that is needed. The two alphas are lifted at the same time,
 * because a brand colour at seven per cent is not a brand colour.
 *
 *   bm-glass-btn rhw-tint-waze
 */
.rhw-tint-brand  { --bm-glass-tint: 129,41,144; --bm-glass-a1:.92; --bm-glass-a2:.74; }
.rhw-tint-google { --bm-glass-tint: 66,133,244; --bm-glass-a1:.92; --bm-glass-a2:.74; }
.rhw-tint-waze   { --bm-glass-tint: 51,204,255; --bm-glass-a1:.92; --bm-glass-a2:.74; }
.rhw-tint-neshan { --bm-glass-tint: 15,157,88;  --bm-glass-a1:.92; --bm-glass-a2:.74; }
.rhw-tint-balad  { --bm-glass-tint: 232,86,42;  --bm-glass-a1:.92; --bm-glass-a2:.74; }

/* =========================================================================
 * A word beside the hamburger
 * Elementor's Menu widget draws only an icon. Robinhood_Menu_Word puts the
 * word at the end of the widget and marks the widget rhw-has-word, rather
 * than wrapping the toggle: Elementor closes the panel with
 * `.elementor-menu-toggle:not(.elementor-active) + .elementor-nav-menu__container`,
 * and anything placed between those two leaves the panel open for good. The
 * order property brings the word back to the front of the row.
 * ===================================================================== */
.elementor-element.elementor-widget.elementor-widget-nav-menu.rhw-has-word,
.elementor-widget-nav-menu.rhw-has-word > .elementor-widget-container{
  /*
   * Elementor stands its Menu widget up as a column with
   * `.elementor-widget-nav-menu:not(:has(.elementor-widget-container)):not([class*="elementor-hidden-"])`,
   * which is three classes' worth and sits later in the cascade, so the word
   * and the button came out on two lines. Four of the widget's own classes are
   * named here to outweigh it, and the row is told not to wrap.
   *
   * The second selector is for the shape where Elementor keeps a
   * .elementor-widget-container: the column is then laid on that, and the word
   * sits inside it rather than beside it, so that is the element to turn.
   */
  display: flex;
  flex-direction: row;
  align-items: center;
  flex-wrap: nowrap;
  gap: 10px;
}
.rhw-menu-word{
  order: -1;
  line-height: 1.35em;
  letter-spacing: -0.5px;
  white-space: nowrap;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
}

/* =========================================================================
 * A finger driving the scan
 * On Drag the figure stops being a place the page can be scrolled from, so
 * the browser never begins a scroll the widget would then have to cancel.
 * On Hold the figure keeps its scrolling and the cancelling is done in the
 * touchmove handler, once the hold has been recognised.
 * ===================================================================== */
.rhw-map.is-grab .rhw-map-figure{ touch-action: none; }
.rhw-map.is-scrub .rhw-map-figure{ -webkit-user-select: none; user-select: none; }

/* =========================================================================
 * A narrower copy of a picture
 * The <picture> that carries the phone and tablet sources must not become a
 * box of its own: the stack is a grid and the img has to stay its child.
 * ===================================================================== */
.rhw-picture-swap{ display: contents; }

/* =========================================================================
 * The naming box, held inside the strip
 * Hung above or below the figure it names, the box needs room around the
 * strip. A phone has none and the box lands on the band underneath, so this
 * pins it to the strip's own edge instead, where it covers the figures.
 * The class is written per device by the widget's own switch.
 * ===================================================================== */
.rhw-strip-inside-yes .rhw-strip .rhw-strip-row{ padding-block-end: var(--rhw-strip-room, 68px); position: relative; }
.rhw-strip-inside-yes .rhw-strip .rhw-strip-one{
    position: static;
    /* A figure that is moved, grown or filtered is itself the box a
       placed child is measured against, whatever its position says —
       and grayscale(0) counts, no-op though it looks. All three are
       given up here so the row can hold the name, and the grey is put
       back on the picture inside, where it shows the same. */
    translate: none; scale: none; transform: none; filter: none;
  }
  .rhw-strip-inside-yes .rhw-strip .rhw-strip-one .rhw-strip-img{
    filter: grayscale(var(--rhw-strip-base-grey, 0));
  }
.rhw-strip-inside-yes .rhw-strip .rhw-strip-box--under,
.rhw-strip-inside-yes .rhw-strip .rhw-strip-box--over{
  inset-block-start: auto;
  inset-block-end: 0;
  inset-inline: 0;
  inline-size: auto;
  max-inline-size: none;
  margin-inline: 0;
  translate: 0 0;
  white-space: normal;
}

/* The class a responsive switch writes carries the device in its own name and
   not in a media query, so the query is put here. The strip's own class is
   named again in each selector because the rules these answer are three
   classes deep and would otherwise win on weight alone. */
@media (min-width: 768px) and (max-width: 1024px){
  .rhw-strip-inside-tablet-yes .rhw-strip .rhw-strip-row{ padding-block-end: var(--rhw-strip-room, 68px); position: relative; }
  .rhw-strip-inside-tablet-yes .rhw-strip .rhw-strip-one{
    position: static;
    /* A figure that is moved, grown or filtered is itself the box a
       placed child is measured against, whatever its position says —
       and grayscale(0) counts, no-op though it looks. All three are
       given up here so the row can hold the name, and the grey is put
       back on the picture inside, where it shows the same. */
    translate: none; scale: none; transform: none; filter: none;
  }
  .rhw-strip-inside-tablet-yes .rhw-strip .rhw-strip-one .rhw-strip-img{
    filter: grayscale(var(--rhw-strip-base-grey, 0));
  }
  .rhw-strip-inside-tablet-yes .rhw-strip .rhw-strip-box--under,
  .rhw-strip-inside-tablet-yes .rhw-strip .rhw-strip-box--over{
    inset-block-start: auto; inset-block-end: 0; inset-inline: 0;
    inline-size: auto; max-inline-size: none; margin-inline: 0;
    translate: 0 0; white-space: normal;
  }
}
/*
 * On a phone this is not a choice. A box hung outside the strip lands on the
 * band underneath at every width this narrow, so below 768 every strip that
 * names its own figures keeps the box inside, stretched, under their feet.
 * The switch above still decides it on a tablet and a wide screen.
 */
@media (max-width: 767px){
  /* Only where the box is actually held inside the strip. A box that sits
     below the strip needs no room kept for it, and reserving it anyway left a
     band of nothing under the figures on every phone. */
  .rhw-strip:not(.rhw-strip--pointer) .rhw-strip-row:has(.rhw-strip-box--under, .rhw-strip-box--over){
    padding-block-end: var(--rhw-strip-room, 68px);
    position: relative;
  }
  .rhw-strip:not(.rhw-strip--pointer) .rhw-strip-one{
    position: static;
    translate: none; scale: none; transform: none; filter: none;
  }
  .rhw-strip:not(.rhw-strip--pointer) .rhw-strip-one .rhw-strip-img{
    filter: grayscale(var(--rhw-strip-base-grey, 0));
  }
  .rhw-strip:not(.rhw-strip--pointer) .rhw-strip-box--under,
  .rhw-strip:not(.rhw-strip--pointer) .rhw-strip-box--over{
    inset-block-start: auto; inset-block-end: 0; inset-inline: 0;
    inline-size: auto; max-inline-size: none; margin-inline: 0;
    translate: 0 0; white-space: normal;
  }
}

@media (max-width: 767px){
  .rhw-strip-inside-mobile-yes .rhw-strip .rhw-strip-row{ padding-block-end: var(--rhw-strip-room, 68px); position: relative; }
  .rhw-strip-inside-mobile-yes .rhw-strip .rhw-strip-one{
    position: static;
    /* A figure that is moved, grown or filtered is itself the box a
       placed child is measured against, whatever its position says —
       and grayscale(0) counts, no-op though it looks. All three are
       given up here so the row can hold the name, and the grey is put
       back on the picture inside, where it shows the same. */
    translate: none; scale: none; transform: none; filter: none;
  }
  .rhw-strip-inside-mobile-yes .rhw-strip .rhw-strip-one .rhw-strip-img{
    filter: grayscale(var(--rhw-strip-base-grey, 0));
  }
  .rhw-strip-inside-mobile-yes .rhw-strip .rhw-strip-box--under,
  .rhw-strip-inside-mobile-yes .rhw-strip .rhw-strip-box--over{
    inset-block-start: auto; inset-block-end: 0; inset-inline: 0;
    inline-size: auto; max-inline-size: none; margin-inline: 0;
    translate: 0 0; white-space: normal;
  }
}

/* ================================================== the row, swiped ==

   Only where the Swipe switch has been turned on for the screen being read.
   Without that class none of this exists, so a strip that has always sat
   still goes on sitting still.

   The row scrolls inside the widget and nothing else: overflow on the row
   itself, never on an ancestor, so the page keeps its own scrolling and
   nothing anywhere else on the page can start moving sideways.

   Each figure is given a width of its own and told not to shrink, which is
   the whole point — the squeeze is what made ten of them unreadable. The
   snap settles the row on a figure rather than between two, and the padding
   at the ends lets the first and last one reach the middle.
   ==================================================================== */

.rhw-swipe-yes .rhw-strip-row{
  overflow-x: auto;
  overflow-y: visible;
  justify-content: flex-start;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--rhw-strip-swipe-edge, 12px);
  padding-inline: var(--rhw-strip-swipe-edge, 12px);
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.rhw-swipe-yes .rhw-strip-row::-webkit-scrollbar{ display: none; }
.rhw-swipe-yes .rhw-strip-one{
  flex: 0 0 var(--rhw-strip-swipe-w, 38%);
  inline-size: var(--rhw-strip-swipe-w, 38%);
  scroll-snap-align: center;
}

@media (max-width: 1024px){
  .rhw-swipe-tablet-yes .rhw-strip-row{
    overflow-x: auto;
    overflow-y: visible;
    justify-content: flex-start;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--rhw-strip-swipe-edge, 12px);
    padding-inline: var(--rhw-strip-swipe-edge, 12px);
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .rhw-swipe-tablet-yes .rhw-strip-row::-webkit-scrollbar{ display: none; }
  .rhw-swipe-tablet-yes .rhw-strip-one{
    flex: 0 0 var(--rhw-strip-swipe-w, 38%);
    inline-size: var(--rhw-strip-swipe-w, 38%);
    scroll-snap-align: center;
  }
}

@media (max-width: 767px){
  .rhw-swipe-mobile-yes .rhw-strip-row{
    overflow-x: auto;
    overflow-y: visible;
    justify-content: flex-start;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--rhw-strip-swipe-edge, 12px);
    padding-inline: var(--rhw-strip-swipe-edge, 12px);
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .rhw-swipe-mobile-yes .rhw-strip-row::-webkit-scrollbar{ display: none; }
  .rhw-swipe-mobile-yes .rhw-strip-one{
    flex: 0 0 var(--rhw-strip-swipe-w, 38%);
    inline-size: var(--rhw-strip-swipe-w, 38%);
    scroll-snap-align: center;
  }
}

/* The swiped row is a flex item, so without a width of its own it shrinks to
   fit its content — and its content is measured as a share of the row. That
   circle collapsed the strip to a sliver the first time this shipped. */
.rhw-swipe-yes .rhw-strip-row{ inline-size: 100%; }
@media (max-width: 1024px){ .rhw-swipe-tablet-yes .rhw-strip-row{ inline-size: 100%; } }
@media (max-width: 767px){ .rhw-swipe-mobile-yes .rhw-strip-row{ inline-size: 100%; } }

/* The widget itself is a flex item that shrinks to fit what is in it, and
   what is in it is now measured as a share of the widget. So when the row is
   being swiped the widget is told to take the width it is given, and the
   strip and the row take all of that. Only while swiping. */
.rhw-swipe-yes{ flex: 1 1 100%; inline-size: 100%; max-inline-size: 100%; }
.rhw-swipe-yes .rhw-strip{ inline-size: 100%; }

@media (max-width: 1024px){
  .rhw-swipe-tablet-yes{ flex: 1 1 100%; inline-size: 100%; max-inline-size: 100%; }
  .rhw-swipe-tablet-yes .rhw-strip{ inline-size: 100%; }
}

@media (max-width: 767px){
  .rhw-swipe-mobile-yes{ flex: 1 1 100%; inline-size: 100%; max-inline-size: 100%; }
  .rhw-swipe-mobile-yes .rhw-strip{ inline-size: 100%; }
}

/* ======================================= the filter dropdowns, ours ==

   The native select is kept — it is still the field the filter plugin
   reads and writes — and only taken out of sight. The button over it
   wears whatever that select was given in the panel, so the closed field
   looks exactly as it did. The list is the site's own submenu: opened
   under the field, never over it.
   ==================================================================== */

.rhw-sel{ position: relative; }

/* The select keeps every bit of its own styling and stays the field you
   see. It only stops taking taps, so the operating system's picker cannot
   open over the page. */
.rhw-sel > select{ pointer-events: none; }

/* Transparent, exactly over the field, and the only thing that is clicked. */
.rhw-sel-face{
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  opacity: 0;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
}
.rhw-sel-face:focus-visible{ opacity: 1; outline: 2px solid currentColor; outline-offset: 2px; }

.rhw-sel-list{
  position: absolute;
  inset-block-start: calc(100% + 6px);
  inset-inline: 0;
  z-index: 40;
  display: none;
  flex-direction: column;
  gap: 3px;
  max-block-size: min(60vh, 420px);
  overflow-y: auto;
  padding: 6px;
  border-radius: 15px;
  background-color: rgba(18, 10, 22, .92);
  border: 1px solid rgba(255, 255, 255, .16);
  box-shadow: 0 18px 40px rgba(0, 0, 0, .35);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  backdrop-filter: blur(14px) saturate(1.3);
}
.rhw-sel.is-open .rhw-sel-list{ display: flex; }

.rhw-sel-row{
  display: block;
  inline-size: 100%;
  text-align: start;
  font: inherit;
  font-family: inherit;
  line-height: 1.35em;
  letter-spacing: -0.5px;
  color: #F4EEF7;
  background: transparent;
  border: 0;
  border-radius: 11px;
  padding: 9px 12px;
  cursor: pointer;
  white-space: normal;
  transition: background-color .16s ease;
}
.rhw-sel-row:hover,
.rhw-sel-row:focus-visible{ background-color: rgba(255, 255, 255, .12); }
.rhw-sel-row.is-on{ background-color: rgba(255, 255, 255, .18); }
/* Only reached if a filter is set to Disable rather than Hide. */
.rhw-sel-row.is-off{ opacity: .38; cursor: default; }
.rhw-sel-row.is-off:hover{ background-color: transparent; }

/* ======================================================================
 * Roll Up.
 *
 * The way back to the top. Fixed to the screen rather than to the page, so
 * it stays in its corner however far down the reader is, and drawn only
 * once they are far enough down to want it. Until then it is not merely
 * transparent: it takes no clicks either, so it cannot sit invisibly over
 * something that does.
 * ================================================================== */

/* The widget holds nothing in the flow — the button inside is fixed to the
   screen — so its own place on the page is taken away. Left in the flow it
   left a band of empty page behind it wherever it was dropped. */
.elementor-widget-robinhood-roll-up{
  position: absolute;
  inline-size: 0;
  block-size: 0;
  overflow: visible;
}

/* The class is written twice on purpose. The theme's reset styles every
   button — `[type="button"], button` — and that weighs exactly as much as a
   single class of ours and lands after it, which turned the box back into
   an inline-block with a pink edge. Two classes settle it without !important. */
.rhw-rollup.rhw-rollup{
  --rhw-rollup-x: 24px;
  --rhw-rollup-arrow: 18px;
  --rhw-rollup-weight: 2px;
  --rhw-rollup-gap: 8px;
  --rhw-rollup-full: 1;
  --rhw-rollup-dim: .2;
  --rhw-rollup-fade: 320ms;

  position: fixed;
  bottom: 32px;
  left: var(--rhw-rollup-x);
  z-index: 90;

  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--rhw-rollup-gap);

  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;

  opacity: 0;
  visibility: hidden;
  translate: 0 8px;
  transition: opacity var(--rhw-rollup-fade) ease, translate .25s ease, visibility 0s linear var(--rhw-rollup-fade);
}

.rhw-rollup.rhw-rollup.is-up{
  opacity: var(--rhw-rollup-full);
  visibility: visible;
  translate: 0 0;
  transition: opacity var(--rhw-rollup-fade) ease, translate .25s ease, visibility 0s;
}

/* While the page is actually moving it thins out of the way, and comes back
   the moment it stops. A finger resting on it always brings it back — being
   touched is a better answer than being faint. */
.rhw-rollup.rhw-rollup.is-up.is-dim{ opacity: var(--rhw-rollup-dim); }
.rhw-rollup.rhw-rollup.is-up.is-dim:hover,
.rhw-rollup.rhw-rollup.is-up.is-dim:focus-visible{ opacity: var(--rhw-rollup-full); }

/* Drawn rather than pulled from a font, so it takes the colour it is given
   and the thickness stays honest at any size. */
.rhw-rollup .rhw-rollup-arrow{
  display: block;
  inline-size: var(--rhw-rollup-arrow);
  block-size: var(--rhw-rollup-arrow);
  border-block-start: var(--rhw-rollup-weight) solid currentColor;
  border-inline-start: var(--rhw-rollup-weight) solid currentColor;
  rotate: 45deg;
  translate: 0 25%;
}

.rhw-rollup-icon{ display: inline-flex; }
.rhw-rollup-icon svg{
  inline-size: var(--rhw-rollup-arrow);
  block-size: var(--rhw-rollup-arrow);
  fill: currentColor;
}
.rhw-rollup-icon i{ font-size: var(--rhw-rollup-arrow); }

.rhw-rollup-label{
  line-height: 1.35em;
  letter-spacing: -0.5px;
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce){
  .rhw-rollup{ transition: opacity .01s linear, visibility 0s; translate: none; }
}

/* ---------------------------------------------------------------- dock -- */

/* Fixed to the screen, so it must not also take a place in the flow — left
   in it, the container it sits in keeps a widget's worth of height and the
   page ends on a band of empty ground. */
.elementor-widget-robinhood-dock{
  position: absolute;
  inline-size: 0;
  block-size: 0;
  overflow: visible;
}

/* The theme's reset has its own word on links and on anything shaped like a
   button, and it lands after this file. The class is written twice so this
   is the more particular rule and wins on its own merits, without !important. */
.rhw-dock.rhw-dock{
  --rhw-dock-x: 12px;
  --rhw-dock-max: 520px;
  --rhw-dock-blur: 18px;
  --rhw-dock-sat: 140%;
  --rhw-dock-mark: 24px;
  --rhw-dock-gap: 4px;
  --rhw-dock-dot: 7px;
  --rhw-dock-dot-ink: #FF3B30;
  --rhw-dock-full: 1;
  --rhw-dock-dim: .3;
  --rhw-dock-fade: 320ms;

  position: fixed;
  inset-inline: var(--rhw-dock-x);
  bottom: 16px;
  margin-inline: auto;
  max-inline-size: var(--rhw-dock-max);
  z-index: 95;

  display: flex;
  align-items: stretch;
  justify-content: space-between;
  gap: 2px;

  padding: 6px;
  border: 0;
  border-radius: 100px;
  background-color: rgba(20, 16, 28, .32);
  color: #fff;

  /* What makes it glass rather than a tinted box: the page behind is blurred
     and its colour kept up, so it reads as a pane and not as paint. */
  -webkit-backdrop-filter: blur(var(--rhw-dock-blur)) saturate(var(--rhw-dock-sat));
  backdrop-filter: blur(var(--rhw-dock-blur)) saturate(var(--rhw-dock-sat));

  /* What tells the eye it is glass rather than a tinted box: a hairline of
     light along the edge, brightest at the top where a pane catches it. */
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18),
              inset 0 0 0 1px rgba(255, 255, 255, .07),
              0 12px 34px rgba(0, 0, 0, .34);

  opacity: var(--rhw-dock-full);
  /* Leaving is quick; coming back is the slow one, rising from below and
     settling rather than snapping into place. */
  transition: opacity var(--rhw-dock-back, 560ms) cubic-bezier(.16, 1, .3, 1),
              translate var(--rhw-dock-back, 560ms) cubic-bezier(.16, 1, .3, 1);
}

/* The menu covers the screen, and the dock has no business sitting over it.
   It leaves at once and takes its time coming back. */
.rhw-dock.rhw-dock.is-gone{
  opacity: 0;
  visibility: hidden;
  translate: 0 18px;
  transition: opacity 160ms ease, translate 160ms ease, visibility 0s linear 160ms;
}

/* Held back until the reader has gone far enough down, when it is asked to
   wait at all. With nothing asked of it the script never adds this. */
.rhw-dock.rhw-dock.is-away{
  opacity: 0;
  visibility: hidden;
  translate: 0 14px;
  transition: opacity var(--rhw-dock-fade) ease, translate var(--rhw-dock-fade) ease, visibility 0s linear var(--rhw-dock-fade);
}

/* While the page is actually moving it thins out of the way, and comes back
   the moment it stops. A finger resting on it always brings it back. */
.rhw-dock.rhw-dock.is-dim:not(.is-away){ opacity: var(--rhw-dock-dim); }
.rhw-dock.rhw-dock.is-dim:not(.is-away):hover,
.rhw-dock.rhw-dock.is-dim:not(.is-away):focus-within{ opacity: var(--rhw-dock-full); }

/* The class is written twice again, because the rule that lays the dock out
   above says `display: flex` at that same weight; a single class here would
   be overruled and the dock would stand on every screen. */
.rhw-dock.rhw-dock--mobile{ display: none; }
.rhw-dock.rhw-dock--small{ display: none; }

@media (max-width: 1024px){
  .rhw-dock.rhw-dock--small{ display: flex; }
}

@media (max-width: 767px){
  .rhw-dock.rhw-dock--mobile{ display: flex; }
}

/* A single shortcut can be held to one kind of screen — a chat button the
   wider screen already shows for itself has no place in the dock there. */
.rhw-dock .rhw-dock-one.rhw-dock-one--phone{ display: none; }
.rhw-dock .rhw-dock-one.rhw-dock-one--desk{ display: flex; }

@media (max-width: 767px){
  .rhw-dock .rhw-dock-one.rhw-dock-one--phone{ display: flex; }
  .rhw-dock .rhw-dock-one.rhw-dock-one--desk{ display: none; }
}

.rhw-dock .rhw-dock-one{
  flex: 1 1 0;
  min-inline-size: 0;

  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--rhw-dock-gap);

  padding: 8px;
  border: 0;
  border-radius: 100px;
  background-color: transparent;
  color: inherit;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  transition: background-color .2s ease, color .2s ease;

  /* One of them may be a button rather than a link — the way back to the
     top — and the theme has its own word on every button. */
  font: inherit;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
}

.rhw-dock .rhw-dock-one.rhw-dock-one:hover,
.rhw-dock .rhw-dock-one.rhw-dock-one:focus-visible{ text-decoration: none; }

.rhw-dock .rhw-dock-one.is-here{
  background-color: var(--rhw-dock-here-face, rgba(255, 255, 255, .14));
  color: var(--rhw-dock-here-ink, inherit);
}

/* The theme's reset paints every button #cc3366 the moment it is touched,
   and two of these are buttons. The class is written twice so this is the
   more particular rule; the colours themselves stay in the panel, and only
   the fallback lives here. */
.rhw-dock .rhw-dock-one.rhw-dock-one:hover,
.rhw-dock .rhw-dock-one.rhw-dock-one:focus,
.rhw-dock .rhw-dock-one.rhw-dock-one:focus-visible,
.rhw-dock .rhw-dock-one.rhw-dock-one:active{
  background-color: var(--rhw-dock-press-face, var(--rhw-dock-here-face, rgba(255, 255, 255, .14)));
  color: var(--rhw-dock-press-ink, inherit);
  border-color: transparent;
}

.rhw-dock .rhw-dock-mark{
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--rhw-dock-mark);
  block-size: var(--rhw-dock-mark);
  flex: 0 0 auto;
}

.rhw-dock .rhw-dock-mark svg{
  inline-size: 100%;
  block-size: 100%;
  fill: currentColor;
}

.rhw-dock .rhw-dock-mark i{ font-size: var(--rhw-dock-mark); line-height: 1; }

.rhw-dock .rhw-dock-mark--shot img{
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  border-radius: 50%;
  display: block;
}

.rhw-dock .rhw-dock-dot{
  position: absolute;
  inset-inline-end: -1px;
  inset-block-end: -1px;
  inline-size: var(--rhw-dock-dot);
  block-size: var(--rhw-dock-dot);
  border-radius: 50%;
  background-color: var(--rhw-dock-dot-ink);
}

.rhw-dock .rhw-dock-word{
  font-size: 10px;
  line-height: 1.35em;
  letter-spacing: -0.5px;
  max-inline-size: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

@media (prefers-reduced-motion: reduce){
  .rhw-dock.rhw-dock{ transition: opacity .01s linear; translate: none; }
}

/* Anything else pinned to the foot of the screen — the chat button and the
   panel it opens — would sit under the dock. They are moved rather than
   re-placed, so whatever space the plugin keeps between the two of them is
   kept as it was. With no dock on the page the distance is zero and nothing
   of theirs is touched. */
.wa__btn_popup,
.wa__popup_chat_box{
  translate: 0 calc(0px - var(--rhw-dock-lift, 0px));
}

/* Where a shortcut in the dock presses the chat button, the button itself is
   put away so the same thing is not on the screen twice. It is still there to
   be pressed, and the panel it opens is untouched. */
.wa__btn_popup{
  display: var(--rhw-chat-float, block);
}


/* ------------------------------------------------------- the request -- */

/* Thirty products set as one paragraph of ticks is a wall nobody reads. Laid
   out in columns, each on its own line, the eye can run down them. */
/*
 * A list you can see all of.
 *
 * A drawer hides its own contents and asks to be opened before it will say
 * what is in it. These two lists are short enough to stand on the page, in as
 * many columns as the width allows and one column on a telephone, so the whole
 * choice is visible at a glance.
 */
.elementor-field-group-category .elementor-field-subgroup{
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
	gap: 8px 22px;
}

.elementor-field-group-products .elementor-field-subgroup{ display: block; }

.elementor-field-group-category .elementor-field-option,
.elementor-field-group-products .elementor-field-option{
	display: flex;
	align-items: flex-start;
	gap: 8px;
	line-height: 1.35em;
	letter-spacing: -0.5px;
}

.elementor-field-group-category .elementor-field-option input,
.elementor-field-group-products .elementor-field-option input{
	margin: 2px 0 0;
	flex: 0 0 auto;
}

@media (max-width: 767px){
	.elementor-field-group-category .elementor-field-subgroup,
	.elementor-field-group-products .elementor-field-subgroup{
		grid-template-columns: 1fr;
		gap: 10px;
	}
}

.elementor-field-group-products .elementor-field-subgroup .elementor-field-option{
  display: flex;
  align-items: center;
  gap: 8px;
  line-height: 1.35em;
  letter-spacing: -0.5px;
}

/* The two errands, and the handful of things one of them asks about, read
   better side by side than stacked. */
.elementor-field-group-kind .elementor-field-subgroup,
.elementor-field-group-topic .elementor-field-subgroup{
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;
}

@media (max-width: 767px){
  .elementor-field-group-products .elementor-field-subgroup{
    grid-template-columns: 1fr;
    gap: 10px;
  }
}

/*
 * The request form on a telephone.
 *
 * Two things break a form on a small screen and neither is the layout. A field
 * whose text is under sixteen pixels makes iOS zoom the whole page the moment
 * it is tapped, and never zoom back; and a row of choices written side by side
 * runs off the edge. So the text is held at sixteen where the screen is small,
 * and the choices stand one under the other.
 */
.elementor-field-group-kind .elementor-field-subgroup{
	display: flex;
	flex-wrap: wrap;
	gap: 8px 24px;
}

@media (max-width: 767px){
	.elementor-field-group-kind .elementor-field-subgroup{ flex-direction: column; }

	.elementor-form .elementor-field-textual,
	.elementor-form select.elementor-field-textual{ font-size: 16px; }
}

/*
 * A field put away stays away.
 *
 * Elementor lays every field group out as a flexbox, and a rule that names a
 * class outranks the browser's own rule for the hidden attribute, so a field
 * the form has put away is still drawn. Naming the class twice settles it
 * without shouting.
 */
.elementor-field-group[hidden].elementor-field-group{ display: none; }

/*
 * Three errands, three faces.
 *
 * One form asks three different things, and a reader should be able to see
 * which one they are on without reading a word. The page carries the errand on
 * its own body, so a picture, a heading or a colour can belong to one errand
 * and stay away for the other two. Only the ones that do not belong are
 * hidden, so whatever display each element was given is left alone.
 */
body[data-errand="order"] .pane-medical,
body[data-errand="order"] .pane-choosing,
body[data-errand="medical"] .pane-order,
body[data-errand="medical"] .pane-choosing,
body[data-errand="choosing"] .pane-order,
body[data-errand="choosing"] .pane-medical{ display: none; }

body[data-errand] .pane-order,
body[data-errand] .pane-medical,
body[data-errand] .pane-choosing{
	animation: rhw-errand 420ms cubic-bezier(.16,1,.3,1) both;
}

@keyframes rhw-errand{
	from{ opacity: 0; translate: 0 8px; }
	to  { opacity: 1; translate: 0 0; }
}

@media (prefers-reduced-motion: reduce){
	body[data-errand] .pane-order,
	body[data-errand] .pane-medical,
	body[data-errand] .pane-choosing{ animation: none; }
}

/*
 * The colour of the errand.
 *
 * The send button takes the colour of the thing being sent, and takes it on
 * hover too: the theme paints every button of its own accord on hover, and a
 * form that turns red under the thumb looks like a mistake.
 */
body{ --bm-errand-ink: #812990; }
body[data-errand="medical"]{ --bm-errand-ink: #3F0C46; }
body[data-errand="choosing"]{ --bm-errand-ink: #A838C1; }

body[data-errand] .elementor-form .elementor-button[type="submit"],
body[data-errand] .elementor-form .elementor-button[type="submit"]:hover,
body[data-errand] .elementor-form .elementor-button[type="submit"]:focus{
	background-color: var(--bm-errand-ink);
}

/*
 * A word beside a field, for the fields that need one.
 *
 * The mark sits on the label and says nothing until it is asked: hovered with
 * a mouse, reached with a keyboard, or tapped on a telephone. It is drawn as a
 * ring rather than a filled disc so it reads as a note and not as a warning,
 * and it never reserves any room of its own.
 */
.rhw-hint{
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	inline-size: 15px;
	block-size: 15px;
	margin-inline-start: 6px;
	vertical-align: -2px;
	cursor: help;
	color: currentColor;
	opacity: .55;
	transition: opacity 180ms ease;
}

.rhw-hint:hover,
.rhw-hint:focus,
.rhw-hint.is-open{ opacity: 1; outline: none; }

.rhw-hint svg{
	inline-size: 15px;
	block-size: 15px;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.4;
	stroke-linecap: round;
}

.rhw-hint .rhw-hint-dot{ fill: currentColor; stroke: none; }

.rhw-hint-said{
	position: absolute;
	inset-block-end: calc(100% + 9px);
	inset-inline-start: 50%;
	translate: -50% 4px;
	inline-size: max-content;
	max-inline-size: 260px;
	padding: 9px 12px;
	border-radius: 10px;
	background: #1A1A1A;
	color: #FFFFFF;
	font-size: 12px;
	font-weight: 400;
	line-height: 1.45em;
	letter-spacing: -0.2px;
	text-align: start;
	text-transform: none;
	white-space: normal;
	box-shadow: 0 10px 26px rgba(0,0,0,.22);
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transition: opacity 180ms ease, translate 180ms cubic-bezier(.16,1,.3,1), visibility 180ms;
	z-index: 20;
}

.rhw-hint:hover .rhw-hint-said,
.rhw-hint:focus .rhw-hint-said,
.rhw-hint.is-open .rhw-hint-said{
	opacity: 1;
	visibility: visible;
	translate: -50% 0;
}

/* Near the edge of a telephone the bubble would hang off the screen. */
@media (max-width: 767px){
	.rhw-hint-said{
		inset-inline-start: 0;
		translate: 0 4px;
		max-inline-size: min(260px, 74vw);
	}

	.rhw-hint:hover .rhw-hint-said,
	.rhw-hint:focus .rhw-hint-said,
	.rhw-hint.is-open .rhw-hint-said{ translate: 0 0; }
}

/*
 * The request form, in the shape it was chosen in.
 *
 * Everything a panel can say is said on the widget: the fill, the radius, the
 * type, the button. Three things are left here because no panel has a control
 * for them. A field that fills rather than outlines needs somewhere to go when
 * it is being typed in, so it turns white and takes a thin line of the errand's
 * own colour. A box for several lines of writing cannot be a pill, so it keeps
 * a softer corner of its own. And a field must never move the page when it is
 * focused, so the line it takes replaces a line that was already there.
 */
.bm-cf .elementor-field-group .elementor-field-textual{
	transition: background-color 170ms ease, border-color 170ms ease;
}

body .bm-cf.bm-cf .elementor-field-group .elementor-field-textual:focus,
body .bm-cf.bm-cf .elementor-field-group .elementor-field-textual:focus-visible{
	background-color: #FFFFFF;
	border-color: var(--bm-errand-ink, #812990);
	outline: none;
}

body .bm-cf.bm-cf .elementor-field-group textarea.elementor-field-textual{
	border-radius: 10px;
	padding-block: 14px;
	padding-inline: 20px;
}

.bm-cf .elementor-field-group .elementor-field::placeholder{ color: #9A93A0; }

/*
 * One height for everything a finger has to hit: forty-six points, which is
 * comfortable on a telephone without making a long form taller than it needs
 * to be. The padding is written here rather than taken from the widget's own
 * size steps, because those steps jump from too small to too tall.
 */
/*
 * A drawer is the same height as a box you type in.
 *
 * Elementor hangs the size class on the control for a text field but on the
 * wrapper for a drawer, so a rule written for one silently misses the other
 * and the drawers stand taller than everything beside them. Both are named
 * by the one class they truly share.
 */
body .bm-cf.bm-cf .elementor-field-group .elementor-field-textual{
	padding-block: 11px;
	padding-inline: 18px;
}

body .bm-cf.bm-cf .elementor-field-group select.elementor-field-textual{
	padding-inline-end: 40px;
}

body .bm-cf.bm-cf .elementor-button[type="submit"]{
	padding-block: 13px;
	padding-inline: 28px;
}

.bm-cf .elementor-field-subgroup{
	font-size: 15px;
	line-height: 1.35em;
	letter-spacing: -0.5px;
}

/* The choices stand on the page itself; only what is typed into sits in a box. */
.bm-cf .elementor-field-group-kind .elementor-field-subgroup{
	gap: 8px 26px;
}

/*
 * A field is forty-six points tall.
 *
 * The widget's own size steps set a least height as well as padding, and its
 * large step is nearly sixty, which turns eight questions into a page and a
 * half. The height is settled here instead, once, for every kind of field.
 */
body .bm-cf.bm-cf .elementor-field-group .elementor-field-textual{
	min-height: 46px;
	font-size: 16px;
	line-height: 1.35em;
}

body .bm-cf.bm-cf .elementor-field-group textarea.elementor-field-textual{
	min-height: 120px;
}

/*
 * The products already chosen, above the list rather than inside it.
 *
 * They stay while the list underneath changes, so a reader can cross the
 * catalogue and collect a knee support and a wrist support in one request.
 */
.rhw-picked{
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 0 0 14px;
}

.rhw-chip{
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 7px 8px 7px 14px;
	border-radius: 10px;
	background: var(--bm-errand-ink, #812990);
	color: #FFFFFF;
	font-size: 13.5px;
	line-height: 1.35em;
	letter-spacing: -0.5px;
}

.rhw-chip-off{
	display: inline-flex;
	align-items: center;
	justify-content: center;
	inline-size: 20px;
	block-size: 20px;
	padding: 0;
	border: 0;
	border-radius: 7px;
	background: rgba(255,255,255,.18);
	color: #FFFFFF;
	font-size: 15px;
	line-height: 1;
	cursor: pointer;
	transition: background-color 150ms ease;
}

.rhw-chip-off:hover,
.rhw-chip-off:focus{ background: rgba(255,255,255,.34); outline: none; }

.rhw-pickable{
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 9px 22px;
}

@media (max-width: 767px){
	.rhw-pickable{ grid-template-columns: 1fr; gap: 11px; }
}

.rhw-pickable-say{
	margin: 0;
	color: #8A8290;
	font-size: 13.5px;
	line-height: 1.6em;
	letter-spacing: -0.3px;
}

/*
 * The same list, on a light ground.
 *
 * The filters stand on dark bands and their list is smoked glass. The request
 * form stands on white, where smoked glass would read as a different site, so
 * the list keeps its shape and changes only its ground. The chosen row is
 * filled with the colour of the errand, which is the same colour the send
 * button is wearing three fields below.
 */
.rhw-sel--light .rhw-sel-list{
	padding: 7px;
	border-radius: 12px;
	background-color: #FFFFFF;
	border: 1px solid #E4DCE8;
	box-shadow: 0 16px 38px rgba(63, 12, 70, .16);
	-webkit-backdrop-filter: none;
	backdrop-filter: none;
}

.rhw-sel--light .rhw-sel-row{
	color: #1A1A1A;
	border-radius: 8px;
	padding: 9px 12px;
	font-size: 15px;
}

.rhw-sel--light .rhw-sel-row:hover,
.rhw-sel--light .rhw-sel-row:focus-visible{ background-color: #F3EFF5; }

.rhw-sel--light .rhw-sel-row.is-on{
	background-color: var(--bm-errand-ink, #812990);
	color: #FFFFFF;
}

/* On a telephone the list may be taller than the screen, so it scrolls itself. */
@media (max-width: 767px){
	.rhw-sel--light .rhw-sel-list{ max-block-size: 52vh; }
}


/* ------------------------------------------------------------------ *
 * Telegram: the person, and the bot.
 *
 * Two buttons that belong to the same family as the rest of the row:
 * the house gradient, the same rounding, and a hover that slides the
 * gradient along rather than swapping one flat colour for another. The
 * bot carries a picture instead of a glyph, a second line under its
 * name, and a slow breath that stops for anybody who has asked their
 * machine to keep still.
 * ------------------------------------------------------------------ */

.rhw-tg{
	display: flex;
	flex-wrap: wrap;
	align-items: stretch;
	gap: 10px;
	--rhw-tg-from: #812990;
	--rhw-tg-mid: #A838C1;
	--rhw-tg-to: #D786EC;
	--rhw-tg-ink: #FFFFFF;
	--rhw-tg-note-ink: rgba(255,255,255,.82);
	--rhw-tg-radius: 10px;
	--rhw-tg-lift: 2px;
	--rhw-tg-face: 34px;
	--rhw-tg-breath: 4.5s;
}

.rhw-tg-btn{
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 10px;
	padding: 9px 18px;
	border-radius: var(--rhw-tg-radius);
	color: var(--rhw-tg-ink);
	text-decoration: none;
	background-image: linear-gradient(115deg, var(--rhw-tg-from) 0%, var(--rhw-tg-mid) 45%, var(--rhw-tg-to) 100%);
	background-size: 210% 100%;
	background-position: 0% 50%;
	box-shadow: 0 6px 18px rgba(129,41,144,.22);
	transition: background-position .55s ease, box-shadow .3s ease, transform .3s ease;
}

.rhw-tg-btn:hover,
.rhw-tg-btn:focus-visible{
	background-position: 100% 50%;
	transform: translateY(calc(var(--rhw-tg-lift) * -1));
	box-shadow: 0 12px 26px rgba(168,56,193,.34);
	color: var(--rhw-tg-ink);
}

.rhw-tg-btn:active{ transform: none; }

.rhw-tg-mark{ display: inline-flex; }
.rhw-tg-glyph{ inline-size: 20px; block-size: 20px; }

.rhw-tg-said{
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	line-height: 1.35em;
}

.rhw-tg-word{
	font-weight: 500;
	letter-spacing: -0.5px;
	text-transform: uppercase;
}

.rhw-tg-note{
	font-size: 11px;
	line-height: 1.35em;
	letter-spacing: -0.3px;
	text-transform: none;
	color: var(--rhw-tg-note-ink);
}

.rhw-tg-face{
	position: relative;
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	inline-size: var(--rhw-tg-face);
	block-size: var(--rhw-tg-face);
}

.rhw-tg-face img,
.rhw-tg-drawn{
	inline-size: 100%;
	block-size: 100%;
	object-fit: contain;
	display: block;
}

.rhw-tg-quiet{
	padding: 10px 14px;
	border: 1px dashed #D3D3D3;
	border-radius: 10px;
	color: #727272;
	font-size: 13px;
}

@media (prefers-reduced-motion: no-preference){
	.rhw-tg-bot.is-breathing .rhw-tg-face{
		animation: rhw-tg-float var(--rhw-tg-breath) ease-in-out infinite;
	}

	.rhw-tg-bot.is-breathing .rhw-tg-face::before{
		content: "";
		position: absolute;
		inline-size: calc(var(--rhw-tg-face) * 1.7);
		block-size: calc(var(--rhw-tg-face) * 1.7);
		border-radius: 50%;
		background: radial-gradient(circle, rgba(255,255,255,.38), rgba(255,255,255,0) 68%);
		animation: rhw-tg-glow var(--rhw-tg-breath) ease-in-out infinite;
		pointer-events: none;
	}

	.rhw-tg-bot.is-breathing .rhw-tg-face > *{ position: relative; }
}

@keyframes rhw-tg-float{
	0%, 100%{ transform: translateY(0); }
	50%{ transform: translateY(-3px); }
}

@keyframes rhw-tg-glow{
	0%, 100%{ opacity: .25; transform: scale(.9); }
	50%{ opacity: .7; transform: scale(1.05); }
}

@media (max-width: 767px){
	.rhw-tg{ inline-size: 100%; }
	.rhw-tg-btn{ flex: 1 1 auto; justify-content: center; }
}

/* ------------------------------------------------------------------ *
 * The search button's magnifier
 *
 * JetSearch draws its button's icon with an icon font, and the icon
 * font is not loaded on a page whose widgets all draw their own marks.
 * The result is a violet circle with nothing in it. The mark is drawn
 * here instead, as a shape masked out of the button's own colour, so
 * the colour control in the panel still governs it and no font has to
 * be fetched for one glyph.
 * ------------------------------------------------------------------ */
.jet-ajax-search__submit{
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-inline-size: 46px;
	min-block-size: 46px;
	cursor: pointer;
}

.jet-ajax-search__submit i{ display: none; }

.jet-ajax-search__submit .jet-ajax-search__submit-icon{
	display: block;
	inline-size: 18px;
	block-size: 18px;
	background-color: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M10 2a8 8 0 1 0 5.293 14.293l4.707 4.707 1.414-1.414-4.707-4.707A8 8 0 0 0 10 2zm0 2a6 6 0 1 1 0 12 6 6 0 0 1 0-12z'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M10 2a8 8 0 1 0 5.293 14.293l4.707 4.707 1.414-1.414-4.707-4.707A8 8 0 0 0 10 2zm0 2a6 6 0 1 1 0 12 6 6 0 0 1 0-12z'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* The sheet of results reads like a list, not like a page of cards. */
.jet-ajax-search__results-item{
	transition: background-color .2s ease;
}

.jet-ajax-search__results-item:hover{
	background-color: #F5E7FC;
}

/* ------------------------------------------------------------------ *
 * The search sheet
 *
 * Each result is a card with the same rounding as the rest of the
 * site, a hairline between one and the next, and the shop's violet
 * where the plugin ships blue.
 * ------------------------------------------------------------------ */
.jet-ajax-search__results-item{
	border-radius: 12px;
	overflow: hidden;
	/* Breathing room at the sides is given by the list, not by the card.
	 * A card that is already the full width of the list and then carries
	 * a side margin is wider than what holds it, and the sheet grew a
	 * grey scrollbar along its bottom edge to say so. */
	margin: 4px 0;
}

.jet-ajax-search__results-slide{
	padding-inline: 6px;
	overflow-x: hidden;
}

.jet-ajax-search__results-item:hover{
	background-color: #F5E7FC;
}

.jet-ajax-search__spinner,
.jet-ajax-search__spinner::before,
.jet-ajax-search__spinner::after,
.jet-ajax-search-spinner,
.jet-search-spinner{
	border-top-color: #A838C1 !important;
	color: #A838C1 !important;
}

.jet-ajax-search__results-count,
.jet-ajax-search__full-results{
	color: #812990;
}

/* ------------------------------------------------------------------ *
 * The count reads under the cards
 *
 * JetSearch prints the number of matches in a header above the list
 * and the all-results button in a footer below it, so the two lines
 * that say the same thing end up on opposite sides of the results.
 * The sheet is laid out as a column and the header is sent to the
 * bottom, where the eye arrives after the last card.
 * ------------------------------------------------------------------ */
.jet-ajax-search__results-holder.show{
	/* The plugin writes display on the element itself when it opens the
	   sheet, so the column has to be said louder than an inline style. */
	display: flex !important;
	flex-direction: column;
}

.jet-ajax-search__results-list{ order: 1; }
.jet-ajax-search__results-header{ order: 2; }
.jet-ajax-search__results-footer{ order: 3; }

.jet-ajax-search__results-header:empty,
.jet-ajax-search__results-footer:empty{ display: none; }

/* One line: the count on the left, the button on the right. */
.jet-ajax-search__results-header,
.jet-ajax-search__results-footer{
	display: flex;
	align-items: center;
	gap: 10px;
}

.jet-ajax-search__results-count{
	background: none;
	border: 0;
	cursor: pointer;
}

/* A card whose button once hung over the edge left a grey scrollbar
 * across the bottom of the sheet. Nothing here is meant to scroll
 * sideways. */
.jet-ajax-search__results-list,
.jet-ajax-search__results-list-inner{
	overflow-x: hidden;
}

/* ------------------------------------------------------------------ *
 * A filter with nothing left to offer
 *
 * JetSmartFilters indexes the options against what is actually in the
 * list, and where a category has no product carrying any of them it
 * hides the filter's own body. What it cannot hide is the panel the
 * filter was dropped into: the glass box, its border and its padding
 * stay behind, and the page shows two empty rounded slabs where the
 * choices should be. The panel goes with its contents.
 *
 * The rule reads the inline style the plugin writes, so it follows the
 * filter live: the moment a choice becomes available again the panel
 * comes back on its own.
 * ------------------------------------------------------------------ */
.elementor-widget-jet-smart-filters-checkboxes:has(.jet-filter[style*="display: none"]),
.elementor-widget-jet-smart-filters-checkboxes:has(.jet-filter[style*="display:none"]),
.elementor-widget-jet-smart-filters-radio:has(.jet-filter[style*="display: none"]),
.elementor-widget-jet-smart-filters-radio:has(.jet-filter[style*="display:none"]),
.elementor-widget-jet-smart-filters-select:has(.jet-filter[style*="display: none"]),
.elementor-widget-jet-smart-filters-select:has(.jet-filter[style*="display:none"]),
.elementor-widget-jet-smart-filters-color-image:has(.jet-filter[style*="display: none"]),
.elementor-widget-jet-smart-filters-color-image:has(.jet-filter[style*="display:none"]){
	display: none !important;
}

/* ------------------------------------------------------------------ *
 * The 404 stands on its own
 *
 * A page that says nothing was found is the one page with no content
 * to frame, so it is shown as a canvas: no header above it and no
 * footer under it, only the picture and the way back. The header and
 * footer templates themselves are untouched, so every other page keeps
 * them; if the theme's own header is ever used instead of ours, it is
 * covered by the same rule.
 * ------------------------------------------------------------------ */
body.error404 .elementor-location-header,
body.error404 .elementor-location-footer,
body.error404 > header.site-header,
body.error404 > footer.site-footer,
body.error404 .e-floating-buttons,
body.error404 .wa__widget_container,
body.error404 .rhw-dock,
body.error404 #wpfooter{
	display: none !important;
}

body.error404{
	margin: 0;
	background: #0A0A0B;

	/*
	 * And it is not scaled. Page Scale draws the whole site at one width
	 * and zooms it to fit, which is right for a page made of type and
	 * boxes and meaningless for a page that is one photograph: with the
	 * zoom on, a section asked for the full height of the window came out
	 * at the zoom's fraction of it and left a band of empty page under
	 * the picture. Here the window is the drawing.
	 */
	zoom: 1 !important;

	/* One screen, and nothing under it to scroll to. */
	overflow: hidden;
}

/*
 * The upright telephone has a picture of its own now, set on the 404
 * template and shown only in portrait, so nothing here has to fit a
 * wide photograph into a tall window any more.
 */

/* ==========================================================================
   The bot button before the bot is open
   ==========================================================================
   The offer is worth showing while the door is still shut, so the button
   keeps its shape and loses its address. It is a span, not a link: nothing
   to click, nothing to open in a new tab, and a reader on a keyboard walks
   straight past it. The paint drops back so it reads as a promise rather
   than an invitation, and it holds still, because a button that breathes
   asks to be pressed.
   ========================================================================== */

.rhw-tg-btn.is-soon{
	cursor: default;
	opacity: .72;
	filter: saturate(.55);
	box-shadow: none;
}

.rhw-tg-btn.is-soon:hover,
.rhw-tg-btn.is-soon:focus-visible{
	transform: none;
	box-shadow: none;
	opacity: .72;
}

.rhw-tg-btn.is-soon .rhw-tg-face{ animation: none; }


/* --------------------------------------------------------------------------
   Nothing stays hidden waiting for a script
   --------------------------------------------------------------------------
   Elementor hides anything with an entrance animation until its own script
   arrives and lets it in. With the scripts held back until the reader touches
   the page, that script may not arrive at all, and a reader who only looks is
   left with a page whose header and half its sections never appear.

   So the hiding is given an end of its own. After a second and a bit the
   element becomes visible whether the script came or not. When the script does
   come first, which is the usual case, it takes the class off and plays the
   animation exactly as before and none of this is ever reached.
   -------------------------------------------------------------------------- */
@keyframes rhw-unhide { from { visibility: hidden; } to { visibility: visible; } }

.elementor-invisible{
	animation: rhw-unhide 0.01s linear 0.4s forwards;
}

@media (prefers-reduced-motion: reduce){
	.elementor-invisible{ animation-delay: 0s; }
}

/* ---------------------------------------------------------------------------
 * A link inside a sentence, without a rule under it
 * ---------------------------------------------------------------------------
 * Nothing on this site is underlined, so a link in the middle of a paragraph
 * has to be told apart some other way. Two things do it here and both of them
 * survive whatever ground the paragraph is standing on: the words are set a
 * step heavier than the sentence around them, and their colour is the colour
 * of that sentence carried part of the way towards the brand violet. Because
 * the mix starts from the text's own colour, a link in pale grey writing on a
 * dark band stays pale and a link in near-black writing on a white panel stays
 * dark: it never turns into violet on violet, and it is never less readable
 * than the sentence it belongs to.
 *
 * A browser without colour mixing keeps the inherited colour and the heavier
 * weight, which is still a link the reader can see.
 * ------------------------------------------------------------------------- */
a{ text-decoration: none; }

.rhw-qa-a a{
	color: inherit;
	font-weight: 600;
	text-decoration: none;
	transition: color .2s ease, opacity .2s ease;
}

@supports (color: color-mix(in oklab, white, black)){
	.rhw-qa-a a{
		color: color-mix(in oklab, currentColor 45%, #B71DDC);
	}

	.rhw-qa-a a:hover,
	.rhw-qa-a a:focus-visible{
		color: color-mix(in oklab, currentColor 20%, #EAA7FF);
	}
}

.rhw-qa-a a:hover,
.rhw-qa-a a:focus-visible{
	text-decoration: none;
	opacity: .85;
}

/* ---------------------------------------------------------------------------
 * A section with nothing in it is not a section
 * ---------------------------------------------------------------------------
 * A heading that promises related products, a line explaining what they are,
 * and then "nothing found" underneath, is three pieces of furniture around an
 * empty room. Where a group is only worth showing when its listing has
 * something in it, the group carries `bm-empty-group` and each piece that
 * should go with it carries `bm-empty-hide`. When the listing inside comes
 * back empty the whole group stands down, heading and all.
 *
 * The listing itself is left to render, because its empty state is what the
 * rule reads. A browser too old to read a parent by what it contains shows the
 * section as it was, message and all, which is the behaviour we started from.
 * ------------------------------------------------------------------------- */
.bm-empty-group:has(.jet-listing-not-found) .bm-empty-hide{
	display: none !important;
}
