/* =========================================================================
   MLE guided-tour runtime  -  engine.css
   Every rule is scoped under an .mtx- class. No bare element selectors:
   the host pages are baked OpenEMR/MLE HTML with very aggressive CSS and
   nothing may leak in either direction.
   ========================================================================= */

.mtx-root {
  /* design tokens live here so everything below is one source of truth */
  --mtx-violet: #7c3aed;
  --mtx-violet-hover: #6d28d9;
  --mtx-navy: #0f172a;
  --mtx-muted: #64748b;
  --mtx-surface: #ffffff;
  --mtx-border: #e2e8f0;
  --mtx-shadow: 0 10px 30px rgba(15, 23, 42, .12);
  --mtx-scrim: rgba(15, 10, 30, .72);
  --mtx-radius-card: 12px;
  --mtx-radius-btn: 8px;
  --mtx-font: 'Plus Jakarta Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mtx-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --mtx-ease: cubic-bezier(.4, 0, .2, 1);

  position: fixed;
  inset: 0;
  z-index: 2147483000;
  pointer-events: none; /* children opt back in individually */
  font-family: var(--mtx-font);
  color: var(--mtx-navy);
  -webkit-font-smoothing: antialiased;
}

.mtx-root, .mtx-root * { box-sizing: border-box; }

/* ---------------------------------------------------------------- spotlight
   The box variant is a single positioned div whose gigantic spread box-shadow
   paints the scrim everywhere except its own footprint. It stays
   pointer-events:none so the cut-out is genuinely clickable; blocking the rest
   of the page is the capture-phase click listener's job, not the shadow's. */
.mtx-spot {
  position: fixed;
  left: 0; top: 0; width: 0; height: 0;
  border-radius: 12px;
  pointer-events: none;
  box-shadow: 0 0 0 9999px var(--mtx-scrim);
  transition: left .3s var(--mtx-ease), top .3s var(--mtx-ease),
              width .3s var(--mtx-ease), height .3s var(--mtx-ease),
              border-radius .3s var(--mtx-ease), opacity .22s var(--mtx-ease);
  opacity: 0;
}
.mtx-spot.mtx-on { opacity: 1; }

/* First spotlight of a variant on a page entry: the base geometry is 0,0,0x0, so a
   plain "set the rect and unhide" grows the cut-out diagonally out of the top-left
   corner. The engine adds .mtx-place for exactly one frame while it writes the real
   geometry (still at opacity 0), then drops it and adds .mtx-on so only the fade
   animates. Same-variant glides never see this class. */
.mtx-spot.mtx-place,
.mtx-spot-svg.mtx-place .mtx-hole,
.mtx-spot-svg.mtx-place .mtx-hole-ring { transition: none !important; }

/* pulsing violet ring, drawn as a pseudo so it never intercepts anything */
.mtx-spot::after {
  content: '';
  position: absolute;
  inset: -2px;
  border: 2px solid var(--mtx-violet);
  border-radius: inherit;
  animation: mtx-pulse 1.8s var(--mtx-ease) infinite;
}
@keyframes mtx-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(124, 58, 237, .45); }
  70%  { box-shadow: 0 0 0 10px rgba(124, 58, 237, 0); }
  100% { box-shadow: 0 0 0 0 rgba(124, 58, 237, 0); }
}

/* svg variant  -  for targets trapped in awkward stacking / transform contexts
   where a box-shadow scrim gets clipped by an ancestor. */
.mtx-spot-svg {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0;
  transition: opacity .22s var(--mtx-ease);
}
.mtx-spot-svg.mtx-on { opacity: 1; }
.mtx-spot-svg .mtx-hole,
.mtx-spot-svg .mtx-hole-ring {
  transition: x .3s var(--mtx-ease), y .3s var(--mtx-ease),
              width .3s var(--mtx-ease), height .3s var(--mtx-ease);
}
.mtx-spot-svg .mtx-hole-ring {
  fill: none;
  stroke: var(--mtx-violet);
  stroke-width: 2;
  animation: mtx-ring-fade 1.8s var(--mtx-ease) infinite;
}
@keyframes mtx-ring-fade {
  0%, 100% { opacity: 1; }
  55% { opacity: .35; }
}

/* ------------------------------------------------------------------- card */
/* While a timeline is parked on a real click, the card must never block that
   click: it goes ghost (visible but non-interactive) until the park resolves. */
.mtx-card.mtx-ghost { pointer-events: none; opacity: 0.6; }

.mtx-card {
  position: fixed;
  left: 0; top: 0;
  width: 340px;
  max-width: calc(100vw - 32px);
  background: var(--mtx-surface);
  border: 1px solid var(--mtx-border);
  border-left: 3px solid var(--mtx-violet);
  border-radius: var(--mtx-radius-card);
  box-shadow: var(--mtx-shadow);
  padding: 16px 18px 14px;
  /* while hidden the card must not sit on top of the page's top-left corner */
  pointer-events: none;
  visibility: hidden;
  opacity: 0;
  transition: opacity .18s var(--mtx-ease), transform .18s var(--mtx-ease);
  transform: translateY(4px);
}
.mtx-card.mtx-on { opacity: 1; transform: none; pointer-events: auto; visibility: visible; }
.mtx-card.mtx-measuring { opacity: 0 !important; }

/* A MID-STEP relocation glides; a step entry does not.
   The card re-places itself while a step is still on screen whenever the thing it
   points at moves: a timeline grows its target, or an `aim` op hands the spotlight to
   the next act of a wow. Teleporting the card across the screen at those moments reads
   as a glitch, so left/top join the transition - but ONLY while engine.js has stamped
   .mtx-glide, which it does exclusively for a card that is already visible (see
   glideable()). A step ENTRY places the card while it is .mtx-measuring, without this
   class, so it lands instantly exactly as it always has instead of sliding in from the
   previous step's position.
   Both reduced-motion blocks at the foot of this file set `transition: none !important`
   on .mtx-card, which outranks this rule in either direction; engine.js's `reduced`
   flag independently refuses to add the class at all. */
.mtx-card.mtx-glide {
  transition: opacity .18s var(--mtx-ease), transform .18s var(--mtx-ease),
              left .22s var(--mtx-ease), top .22s var(--mtx-ease);
}

/* A card at a free viewport anchor is not adjacent to anything it could point at, so
   it grows no caret and takes no side border treatment. engine.js hides the caret node
   itself; this is the belt to that pair of braces. */
.mtx-card[data-side="free"] .mtx-caret,
.mtx-card[data-side="none"] .mtx-caret { display: none; }

.mtx-title {
  font: 700 16px/1.3 var(--mtx-font);
  color: var(--mtx-navy);
  margin: 0 0 6px;
}
.mtx-body {
  font: 400 14px/1.55 var(--mtx-font);
  color: #334155;
}
.mtx-body p { margin: 0 0 8px; }
.mtx-body p:last-child { margin-bottom: 0; }
.mtx-body strong, .mtx-body b { font-weight: 700; color: var(--mtx-navy); }
.mtx-body code { font: 500 12.5px/1.4 var(--mtx-mono); background: #f1f5f9; padding: 1px 5px; border-radius: 4px; }
.mtx-body ul { margin: 6px 0; padding-left: 18px; }
.mtx-body li { margin: 2px 0; }

.mtx-foot {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 14px;
}
.mtx-meta {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-right: auto;
  min-width: 0;
}
.mtx-count {
  font: 500 12px/1 var(--mtx-mono);
  color: var(--mtx-muted);
  letter-spacing: .01em;
  white-space: nowrap;
}
.mtx-hint {
  font: 500 12px/1.35 var(--mtx-font);
  color: var(--mtx-violet);
}

/* buttons */
.mtx-btn {
  font: 600 13px/1 var(--mtx-font);
  border-radius: var(--mtx-radius-btn);
  padding: 9px 14px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background .15s var(--mtx-ease), color .15s var(--mtx-ease), border-color .15s var(--mtx-ease);
  white-space: nowrap;
}
.mtx-btn:focus-visible { outline: 2px solid var(--mtx-violet); outline-offset: 2px; }
.mtx-btn-primary { background: var(--mtx-violet); color: #fff; }
.mtx-btn-primary:hover { background: var(--mtx-violet-hover); }
.mtx-btn-primary[disabled] { background: #c4b5fd; cursor: default; }
.mtx-btn-ghost { background: transparent; color: var(--mtx-muted); border-color: var(--mtx-border); }
.mtx-btn-ghost:hover { color: var(--mtx-navy); border-color: #cbd5e1; }
.mtx-btn-ghost[disabled] { opacity: .45; cursor: default; }
.mtx-btn-x {
  background: transparent;
  border: 0;
  color: #94a3b8;
  font: 400 16px/1 var(--mtx-font);
  padding: 8px;
  cursor: pointer;
  border-radius: var(--mtx-radius-btn);
}
.mtx-btn-x:hover { color: var(--mtx-navy); background: #f1f5f9; }
.mtx-hidden { display: none !important; }
.mtx-show { display: block !important; }   /* timelines reveal display:none page sections */

/* caret */
.mtx-caret {
  position: absolute;
  width: 12px; height: 12px;
  background: var(--mtx-surface);
  border: 1px solid var(--mtx-border);
  transform: rotate(45deg);
}
.mtx-card[data-side="bottom"] .mtx-caret { top: -7px; border-right: 0; border-bottom: 0; }
.mtx-card[data-side="top"]    .mtx-caret { bottom: -7px; border-left: 0; border-top: 0; }
.mtx-card[data-side="right"]  .mtx-caret { left: -7px; border-right: 0; border-top: 0; }
.mtx-card[data-side="left"]   .mtx-caret { right: -7px; border-left: 0; border-bottom: 0; }

/* bottom-sheet mode under 1280px */
.mtx-card.mtx-sheet {
  left: 0 !important;
  right: 0;
  top: auto !important;
  bottom: 0;
  width: 100%;
  max-width: 100%;
  border-radius: var(--mtx-radius-card) var(--mtx-radius-card) 0 0;
  border-left: 1px solid var(--mtx-border);
  border-top: 3px solid var(--mtx-violet);
  padding: 18px 20px calc(18px + env(safe-area-inset-bottom, 0px));
  transform: translateY(8px);
}
.mtx-card.mtx-sheet.mtx-on { transform: none; }
.mtx-card.mtx-sheet .mtx-caret { display: none; }

/* ------------------------------------------------------------------ toast */
.mtx-toasts {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
  pointer-events: none;
  z-index: 3;
}
.mtx-toast {
  background: var(--mtx-navy);
  color: #f8fafc;
  font: 500 13px/1.4 var(--mtx-font);
  padding: 10px 16px;
  border-radius: var(--mtx-radius-btn);
  box-shadow: var(--mtx-shadow);
  max-width: min(420px, calc(100vw - 32px));
  text-align: center;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .2s var(--mtx-ease), transform .2s var(--mtx-ease);
}
.mtx-toast.mtx-on { opacity: 1; transform: none; }

/* ------------------------------------------------------- free-roam hotspot */
.mtx-dot {
  position: absolute;
  top: -5px;
  right: -5px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--mtx-violet);
  box-shadow: 0 0 0 0 rgba(124, 58, 237, .55);
  animation: mtx-pulse 1.8s var(--mtx-ease) infinite;
  pointer-events: none;
  z-index: 40;
}
.mtx-hotspot-host { cursor: pointer; }

.mtx-mini {
  position: fixed;
  width: 300px;
  max-width: calc(100vw - 32px);
  background: var(--mtx-surface);
  border: 1px solid var(--mtx-border);
  border-left: 3px solid var(--mtx-violet);
  border-radius: var(--mtx-radius-card);
  box-shadow: var(--mtx-shadow);
  padding: 14px 16px;
  pointer-events: auto;
}
.mtx-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
  background: #f5f3ff;
  color: var(--mtx-violet);
  border: 1px solid #ddd6fe;
  border-radius: 999px;
  padding: 6px 12px;
  font: 600 12px/1 var(--mtx-font);
  cursor: pointer;
}
.mtx-chip:hover { background: #ede9fe; }

/* --------------------------------------------------------------- end card */
.mtx-end-wrap {
  position: fixed;
  inset: 0;
  background: rgba(15, 10, 30, .72);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  pointer-events: auto;
}
.mtx-end {
  background: var(--mtx-surface);
  border: 1px solid var(--mtx-border);
  border-radius: var(--mtx-radius-card);
  box-shadow: var(--mtx-shadow);
  padding: 30px 32px 26px;
  width: 480px;
  max-width: 100%;
  max-height: calc(100vh - 48px);
  overflow: auto;
  text-align: center;
}
.mtx-end-head { font: 700 22px/1.25 var(--mtx-font); margin: 0 0 14px; color: var(--mtx-navy); }
.mtx-recap { list-style: none; margin: 0 0 22px; padding: 0; text-align: left; }
.mtx-recap li {
  font: 400 14px/1.5 var(--mtx-font);
  color: #334155;
  padding: 6px 0 6px 26px;
  position: relative;
}
.mtx-recap li::before {
  content: '';
  position: absolute;
  left: 4px; top: 12px;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--mtx-violet);
}
.mtx-end-cta {
  display: inline-block;
  background: var(--mtx-violet);
  color: #fff;
  text-decoration: none;
  font: 700 14px/1 var(--mtx-font);
  padding: 13px 26px;
  border-radius: var(--mtx-radius-btn);
}
.mtx-end-cta:hover { background: var(--mtx-violet-hover); color: #fff; text-decoration: none; }
.mtx-end-alt {
  display: block;
  margin-top: 14px;
  font: 500 13px/1 var(--mtx-font);
  color: var(--mtx-muted);
  text-decoration: none;
}
.mtx-end-alt:hover { color: var(--mtx-violet); }
.mtx-end-next {
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--mtx-border);
}

/* =========================================================================
   MOBILE  -  the counter-scaled tour chrome
   =========================================================================
   bake.mjs pins the layout viewport of every app page to the 1920 capture width,
   so a phone renders the whole desktop screen scaled to fit (~0.2x on a 390px
   handset). At that scale one CSS px is a fifth of a device pixel and none of the
   chrome above is legible or touchable. engine.js therefore lays the chrome out in
   DEVICE-INDEPENDENT px and counter-scales it back with transform: scale(1/scale),
   stamping .mtx-vv on each node it owns. So inside a .mtx-vv subtree every length
   below is read as DEVICE px  -  "14px" here really is 14px on the glass, the same
   size it is on a desktop.

   JS owns left/top/width/transform on these nodes. CSS owns nothing but the look.
   None of it can reach a desktop: .mtx-vv (and the .mtx-coarse class on <html>) are
   applied only when engine.js's isMobile() is true, which needs a coarse primary
   pointer AND a phone-sized visual viewport. On a fine pointer these selectors match
   nothing and the desktop rules above are the whole story.
   ========================================================================= */

/* JS writes the reciprocal scale here so the one rule that has to live OUTSIDE
   .mtx-root (the hotspot dot is appended to a PAGE element) can counter-scale too.
   A free-roam dot is 10 layout px, i.e. 2 device px at fit zoom: invisible AND
   unhittable. Counter-scaling puts it back at its desktop size, and the ::after halo
   gives it a 44 device px tap radius. The halo is inside the dot's own (already
   counter-scaled) coordinate space, so its 44px is 44 DEVICE px. Making the dot
   pointer-interactive costs nothing: the ONE capture-phase click interceptor walks up
   with closest('[data-demo-hotspot]'), which reaches the host from the dot exactly as
   it does from the host's own content. */
.mtx-coarse .mtx-dot {
  transform: scale(var(--mtx-k, 1));
  transform-origin: 100% 0%;
  pointer-events: auto;
  /* Not cosmetic: Chromium's touch adjustment ("fat finger") only snaps a tap to nodes
     it considers clickable, and at fit zoom its search radius spans ~200 layout px. A
     dot without this was losing its own taps to the shell tab rail 30 layout px above
     it (measured). cursor:pointer is what puts the dot in that candidate set. */
  cursor: pointer;
  /* WebKit will not synthesise a click from a tap on a node it might still be waiting
     to double-tap-zoom on; without this the dot swallowed its own taps in Safari
     (measured: touchstart/touchend, no click). Also kills the legacy 300ms delay. */
  touch-action: manipulation;
}
/* The tap radius. Anchored to the dot's top-right  -  the same corner transform-origin
   pins  -  so it grows only LEFT and DOWN, into the host. A centred halo grew right
   instead and pushed documentElement.scrollWidth to 1971/1992 on the two pages whose
   hotspots sit near the right edge, which is exactly the horizontal overflow the pinned
   layout viewport exists to prevent. Its 44px are DEVICE px: it lives inside the dot's
   already counter-scaled coordinate space. */
.mtx-coarse .mtx-dot::after {
  content: '';
  position: absolute;
  right: 0; top: 0;
  width: 44px; height: 44px;
  border-radius: 50%;
}

/* A repositioning pinch/pan must not animate its way to the new spot. */
.mtx-root .mtx-vv { transition: opacity .18s var(--mtx-ease) !important; }

/* ---- the card, as a true bottom sheet inside the visual viewport --------- */
.mtx-card.mtx-vv {
  border-radius: var(--mtx-radius-card) var(--mtx-radius-card) 0 0;
  border-left: 1px solid var(--mtx-border);
  border-top: 3px solid var(--mtx-violet);
  padding: 16px 16px 20px;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.mtx-card.mtx-vv .mtx-caret { display: none; }
/* A long step body scrolls INSIDE the sheet, so Next can never be pushed off the
   screen by copy (the height cap itself is inline, off the visual viewport). */
.mtx-card.mtx-vv .mtx-body { overflow-y: auto; min-height: 0; font-size: 14.5px; }
.mtx-card.mtx-vv .mtx-title { font-size: 17px; }
.mtx-card.mtx-vv .mtx-count,
.mtx-card.mtx-vv .mtx-hint { font-size: 13px; }
.mtx-card.mtx-vv .mtx-foot { margin-top: 12px; gap: 10px; flex: 0 0 auto; }
/* >= 44px on the glass: Apple's and Google's minimum, and the size the mobile e2e
   suite asserts before it will call a step tappable. */
.mtx-card.mtx-vv .mtx-btn {
  min-height: 44px; padding: 12px 18px; font-size: 14px; touch-action: manipulation;
}
.mtx-card.mtx-vv .mtx-btn-x {
  min-width: 44px; min-height: 44px; font-size: 18px; touch-action: manipulation;
}

/* ---- toasts ------------------------------------------------------------- */
.mtx-toasts.mtx-vv { align-items: stretch; }
.mtx-toasts.mtx-vv .mtx-toast { max-width: 100%; font-size: 13.5px; padding: 12px 16px; }

/* ---- free-roam tip card ------------------------------------------------- */
.mtx-mini.mtx-vv { padding: 16px; }
.mtx-mini.mtx-vv .mtx-title { font-size: 16px; }
.mtx-mini.mtx-vv .mtx-body { font-size: 14px; max-height: 300px; overflow-y: auto; }
.mtx-mini.mtx-vv .mtx-chip {
  min-height: 44px; padding: 10px 16px; font-size: 13px; touch-action: manipulation;
}

/* ---- end card: the whole scrim is one scaled frame ---------------------- */
.mtx-end-wrap.mtx-vv { padding: 16px; }
.mtx-end-wrap.mtx-vv .mtx-end {
  width: 100%; max-width: 100%; max-height: 100%; padding: 22px 20px 20px;
}
.mtx-end-wrap.mtx-vv .mtx-end-head { font-size: 20px; }
.mtx-end-wrap.mtx-vv .mtx-recap li { font-size: 13.5px; }
.mtx-end-wrap.mtx-vv .mtx-end-cta {
  display: block; padding: 15px 20px; font-size: 15px; touch-action: manipulation;
}
.mtx-end-wrap.mtx-vv .mtx-end-alt { font-size: 13px; padding: 10px 0; }
.mtx-end-wrap.mtx-vv .mtx-btn,
.mtx-end-wrap.mtx-vv .mtx-chip { min-height: 44px; touch-action: manipulation; }

/* ---- "best on desktop" banner ------------------------------------------- */
.mtx-note {
  position: fixed;
  left: 0; top: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--mtx-navy);
  color: #f8fafc;
  padding: 12px 14px;
  box-shadow: var(--mtx-shadow);
  pointer-events: auto;
  z-index: 6;
}
.mtx-note-text { font: 500 13px/1.4 var(--mtx-font); flex: 1 1 auto; }
.mtx-note-ok {
  flex: 0 0 auto; min-height: 40px; padding: 10px 18px; font-size: 14px;
  touch-action: manipulation;
}

/* ---- enlarged tap target over a parked control -------------------------- */
/* Invisible on purpose: the spotlight cut-out is what tells the visitor WHERE to
   press, and a visible slab over the control would hide the very thing it points
   at. Sized in LAYOUT px by JS (>= 44 device px on each axis) and centred on the
   real control, which it forwards the tap to. */
.mtx-tapproxy {
  position: fixed;
  margin: 0; padding: 0; border: 0;
  background: transparent;
  -webkit-appearance: none;
  appearance: none;
  pointer-events: auto;
  touch-action: manipulation;
  cursor: pointer;
  z-index: 5;
}
.mtx-tapproxy:focus { outline: none; }

/* ------------------------------------------------------- reduced motion */
@media (prefers-reduced-motion: reduce) {
  .mtx-root .mtx-spot,
  .mtx-root .mtx-spot-svg,
  .mtx-root .mtx-spot-svg .mtx-hole,
  .mtx-root .mtx-spot-svg .mtx-hole-ring,
  .mtx-root .mtx-card,
  .mtx-root .mtx-toast { transition: none !important; }
  .mtx-root .mtx-spot::after,
  .mtx-root .mtx-dot,
  .mtx-root .mtx-spot-svg .mtx-hole-ring { animation: none !important; }
}
/* engine also sets this class so JS-side reduced motion matches the CSS */
.mtx-root.mtx-noanim .mtx-spot,
.mtx-root.mtx-noanim .mtx-spot-svg,
.mtx-root.mtx-noanim .mtx-spot-svg .mtx-hole,
.mtx-root.mtx-noanim .mtx-spot-svg .mtx-hole-ring,
.mtx-root.mtx-noanim .mtx-card,
.mtx-root.mtx-noanim .mtx-toast { transition: none !important; }
.mtx-root.mtx-noanim .mtx-spot::after,
.mtx-root.mtx-noanim .mtx-dot { animation: none !important; }
