:root{
  /* Stronger than the built-in curves, which are too weak to read as intentional. */
  --qt-ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --qt-ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);

  /* Currency mark sizing - tune these two and every price follows. */
  --qt-cur-size: 0.58em;
  --qt-cur-rise: 0.50em;
}

/* ---------------------------------------------------------------- 1. PRESS
 * The site had no :active state anywhere - 0 rules across 474 stylesheets.
 * The scale sits on the inner <a>, while Elementor's hover scale sits on the
 * wrapper, so the two compose rather than fight: hovering then pressing reads
 * as a small dip out of the raised state.
 * Properties are listed explicitly - never `all`, which drags layout and paint
 * onto the main thread.
 */
a.elementor-button,
button.elementor-button,
.elementor-button-link,
.qt-book-now-link,
a.healcode-pricing-link,
.wdt-popup-box-trigger-label,
.tribe-events-c-btn,
.wp-block-button__link{
  transition:
    transform 160ms var(--qt-ease-out),
    background-color 200ms ease,
    border-color 200ms ease,
    color 200ms ease,
    box-shadow 200ms ease;
  -webkit-tap-highlight-color: transparent;
}

a.elementor-button:active,
button.elementor-button:active,
.elementor-button-link:active,
.qt-book-now-link:active,
a.healcode-pricing-link:active,
.wdt-popup-box-trigger-label:active,
.tribe-events-c-btn:active,
.wp-block-button__link:active{
  transform: scale(0.97);
}

/* Keyboard users get the same acknowledgement as pointer users. */
a.elementor-button:focus-visible,
button.elementor-button:focus-visible,
.qt-book-now-link:focus-visible,
.wdt-popup-box-trigger-label:focus-visible{
  outline: 2px solid currentColor;
  outline-offset: 3px;
}

/* ------------------------------------------------------- 2. HOVER ON TOUCH
 * Elementor applies its hover scale through --e-transform-scale. On a touch
 * device that hover fires on tap and then STICKS until the user taps elsewhere,
 * which reads as a stuck, broken card. Neutralise it where there is no real
 * pointer; the :active press above is the correct feedback there instead.
 */
@media (hover: none), (pointer: coarse){
  .elementor-element:hover{
    --e-transform-scale: 1 !important;
    --e-transform-scaleX: 1 !important;
    --e-transform-scaleY: 1 !important;
  }
}

/* --------------------------------------------------------- 3. CARD MOTION
 * Treatment and pricing cards: give the lift a real curve and a duration under
 * 300ms. Only transform and opacity animate, so this stays on the GPU.
 */
@media (hover: hover) and (pointer: fine){
  .elementor-element[class*="elementor-element-"] > .elementor-widget-container,
  .elementor-widget-image img{
    transition: transform 220ms var(--qt-ease-out), opacity 220ms var(--qt-ease-out);
  }
}

/* ------------------------------------------------------------- 4. NUMERALS
 * Elsie is a display face with uneven digit proportions - its 8 is drawn
 * optically smaller than its 5, 3 and 7 - and the $ glyph overhangs its own
 * advance width. Set inline at full size, the currency mark therefore lands in
 * a different place next to every price, which reads as $88 sitting high.
 *
 * Elsie ships no lining-figure alternates, so lnum cannot fix it. Instead the
 * $ is wrapped in .qt-cur and positioned deterministically: smaller, raised to
 * meet the digits' cap height, and no longer at the mercy of the glyph beside
 * it. A smaller raised currency mark is the conventional setting for display
 * prices anyway, so this reads better as well as consistently.
 */
.qt-cur{
  font-size: var(--qt-cur-size);
  line-height: 1;
  vertical-align: var(--qt-cur-rise);
  margin-right: 0.04em;
  letter-spacing: 0;
}

/* Tabular figures keep the four prices aligned as a set. */
.elementor-element-d7cd41d,
.elementor-element-eaf3a60,
.elementor-element-53685a2b,
.elementor-element-qtbl0004{
  font-variant-numeric: tabular-nums;
  -webkit-font-feature-settings: "tnum" 1;
  font-feature-settings: "tnum" 1;
}

/* ------------------------------------------------------- 5. REDUCED MOTION
 * Gentler, not absent. Colour and opacity still carry meaning, so they stay;
 * movement goes. Elementor entrance animations park content at opacity:0 and
 * rely on JS to reveal it, so that has to be forced visible or the page reads
 * as empty for anyone with the preference set.
 */
@media (prefers-reduced-motion: reduce){
  a.elementor-button,
  button.elementor-button,
  .qt-book-now-link,
  .elementor-widget-container,
  .elementor-widget-image img{
    transition-property: background-color, border-color, color, opacity !important;
    transition-duration: 200ms !important;
  }

  a.elementor-button:active,
  button.elementor-button:active,
  .qt-book-now-link:active{
    transform: none;
  }

  .elementor-element:hover{
    --e-transform-scale: 1 !important;
  }

  .elementor-invisible{
    opacity: 1 !important;
    animation: none !important;
  }

  .animated,
  [class*="fadeIn"],
  [class*="slideIn"],
  [class*="zoomIn"]{
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }

  html{ scroll-behavior: auto !important; }
}
