

/* === A. TOUCH DEVICES: remove tap-flash on every interactive element === */
@media (hover: none), (pointer: coarse) {
  *, *::before, *::after {
    -webkit-tap-highlight-color: transparent !important;
  }
  /* Don't fire hover styles on touch — they leave stuck "lit" states
     after a tap, which visually reads as a blink/flash on mobile. */
  .stat-card:hover,
  .feature-card:hover,
  .cal-day:not(.empty):hover,
  .trade-detail-card:hover,
  .cdp:hover,
  .nav-btn:hover,
  .btn-primary:hover,
  .btn-ghost:hover,
  .landing-btn-primary:hover,
  .landing-btn-ghost:hover,
  .landing-btn-primary-lg:hover,
  .landing-btn-ghost-lg:hover,
  .checklist-item:hover,
  .daily-todo-item:hover,
  .date-clickable:hover,
  #propfirmPage .pf-bignum-card:hover,
  #propfirmPage .pf-preset:hover,
  #montecarloPage .mc-stat:hover,
  #montecarloPage .mc-preset:hover {
    transform: none !important;
    box-shadow: inherit !important;
  }
}

/* === B. MOBILE: disable every infinite animation that causes repaint
        storms. Pure CSS opacity-only blinks are kept where they're cheap
        and meaningful (LIVE dots). Everything that animates box-shadow,
        background-position, or filter is paused. === */
@media (max-width: 768px) {

  /* ---- B0. GLOBAL whole-page flicker killers (added) ----
     These target the "every screen, always blinking" problem:
       1) The fixed full-screen 3D perspective grid + radial glow drawn on
          body::before / body::after. A perspective-transformed fixed layer
          forces the whole viewport to repaint on every frame on Android
          Chrome -> full-page flicker. We FLATTEN it (no perspective) and
          isolate it on its own GPU layer instead of removing the look.
       2) Any leftover infinite keyframe animation -> paused.
       3) backdrop-filter blur on large always-visible surfaces (sidebar,
          cards) is the other classic Android repaint storm -> softened.
     None of this changes layout or removes features. */
  body::before,
  body::after {
    transform: none !important;          /* kill perspective/rotateX repaint */
    animation: none !important;
    will-change: auto !important;
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
  }
  /* Stop every remaining infinite animation on phones (LIVE dots that are
     opacity-only stay fine; this just halts the expensive ones). */
  *,
  *::before,
  *::after {
    animation-iteration-count: 1 !important;
  }
  /* Re-allow a tiny set of cheap, meaningful opacity blinks if needed.
     (Intentionally minimal — add selectors here only if a live indicator
     must keep pulsing.) */

  /* Heavy, always-on blur surfaces -> lighter to avoid repaint storms.
     The frosted look is preserved with a solid-ish background fallback. */
  .sidebar,
  .section-card,
  .hero-banner,
  .stat-card,
  .daily-todo-card,
  .modal,
  .landing-nav {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }

  /* ---- B1. Prop firm pulse/blink halos: kept *visually* with a static
     border/glow but the infinite keyframe is off. The pf-pill-breach
     pulse on the actual breach status pill is preserved because it's
     a critical UX alert. ---- */
  #propfirmPage .pf-status-critical,
  #propfirmPage .pf-status-violated,
  #propfirmPage .pf-bar-card.pf-bar-crit {
    animation: none !important;
  }
  #propfirmPage .pf-bar-fill.pf-fill-breach {
    animation: none !important;
  }

  /* ---- B2. Monte Carlo hero scanning line + pulsing dot ---- */
  #montecarloPage .mc-hero::after,
  #montecarloPage .mc-badge .dot,
  #montecarloPage .mc-empty .ico {
    animation: none !important;
  }

  /* ---- B3. Session-clock now-line glow + glow-pulse halo ---- */
  .sc-tl-now-line,
  .sc-wb-glow {
    animation: none !important;
  }

  /* ---- B4. Hero equity card — kill the heaviest layers on phones ----
     mix-blend-mode + animated background-position is the #1 cause of
     flicker on Android Chrome and Safari iOS. The card itself stays
     beautiful (static gradients + glow), just no constant repaint. */
  .hero-banner .hero-stat > .eq-holo,
  .hero-banner .hero-stat > .eq-bg-grid,
  .hero-banner .hero-stat > .eq-particles {
    display: none !important;
  }
  .hero-banner .hero-stat .val {
    animation: none !important;
    background-size: 100% 100% !important;
  }
  .hero-banner .hero-stat::before {
    animation: none !important;
  }
  .hero-banner .hero-stat > .eq-corner-accent .dot {
    animation: none !important;
  }

  /* ---- B5. Prayer pulse + plans pulse + sle pulse — static borders ---- */
  [class*="prayer-pulse"],
  .plans-pulse,
  .sle-pulse {
    animation: none !important;
  }

  /* ---- B6. 3D card layers don't render on phones anyway — make sure
     none of the always-on / dynamic 3D layers are present. Even if they
     get injected by JS we hide them so they can't repaint. ---- */
  .stat-card > .edge-top-3d,
  .stat-card > .edge-left-3d,
  .stat-card > .edge-right-3d,
  .stat-card > .edge-bottom-3d,
  .stat-card > .glow-3d,
  .stat-card > .auto-shimmer-3d,
  .stat-card > .border-light-3d,
  .stat-card > .accent-pulse-3d {
    display: none !important;
  }
  .stat-card {
    animation: none !important;
    transform: none !important;
  }

  /* ---- B7. Reduce backdrop-filter cost on the elements that combine
     it with infinite animations underneath. We swap blur for a solid
     dark background of the same tone. Visually it's nearly identical
     on a phone screen, but the GPU compositor stops re-blurring
     every frame. ---- */
  .sidebar,
  .modal,
  .section-card,
  .daily-todo-card,
  .hero-banner,
  #propfirmPage .pf-panel,
  #propfirmPage .pf-bignum-card,
  #propfirmPage .pf-bar-card,
  #montecarloPage .mc-panel,
  #montecarloPage .mc-stat,
  #montecarloPage .mc-chart-card {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }

  /* ---- B8. Force GPU compositing on the few animations we kept alive
     so they don't trigger layout/paint on the rest of the page. ---- */
  .dss-live-time,
  .dss-live-time::before,
  .dss-now-time,
  .pf-bar-pill.pf-pill-breach,
  .live-dot,
  .live-dot-ring {
    transform: translateZ(0) !important;
    -webkit-transform: translateZ(0) !important;
    backface-visibility: hidden !important;
    -webkit-backface-visibility: hidden !important;
    will-change: opacity !important;
  }

  /* ---- B9. Stop iOS Safari double-tap zoom / 300ms tap-flash on
     every clickable surface. ---- */
  button, a, .nav-btn, .stat-card, .cal-day, .checklist-item,
  .daily-todo-item, .cdp, .trade-detail-card, .feature-card,
  .landing-btn-primary, .landing-btn-ghost,
  .landing-btn-primary-lg, .landing-btn-ghost-lg {
    touch-action: manipulation;
  }

  /* ---- B10. Body background grid + glow — they're already cheap but
     pin them to the GPU so they don't fight with sticky elements
     during scroll (which on iOS causes the "everything blinks once"
     effect on rubber-band scroll). ---- */
  body::before,
  body::after {
    transform: translateZ(0) !important;
    -webkit-transform: translateZ(0) !important;
    will-change: transform !important;
  }
}

/* === C. EXPLICIT REDUCED-MOTION HONOURING ===
   For anyone with the OS setting on, kill EVERY infinite animation. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001s !important;
  }
}

/* === D. SAFETY NET FOR VERY SMALL PHONES (<= 380px) ===
   On the smallest devices, also remove the page-level fade-in animation
   from `.page.active`. It briefly drops opacity to 0 every time the user
   switches tabs and on a slow device this looks like a blink. */
@media (max-width: 380px) {
  .page.active {
    animation: none !important;
  }
}

/* === E. UTILITY: spin animation for the cloud-sync button === */
@keyframes spin {
  to { transform: rotate(360deg); }
}
#syncNowBtn[disabled] {
  display: inline-block;
}


/*
  PERFORMANCE MODE
  ----------------
  Kills GPU-intensive effects across the app: backdrop blurs, glow
  shadows, scale/translate hover transforms, and the body's grid +
  glow background layers. Visual style stays clean — borders, colors,
  badges all unchanged — just much smoother on slow hardware.
*/
html.perf-mode *,
html.perf-mode *::before,
html.perf-mode *::after {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
html.perf-mode body::before,
html.perf-mode body::after,
html.perf-mode .auth-bg-grid,
html.perf-mode .auth-bg-glow,
html.perf-mode .landing-page::before,
html.perf-mode .landing-page::after,
html.perf-mode .hero-banner::before,
html.perf-mode .hero-banner::after,
html.perf-mode .mt5-card::before,
html.perf-mode .rules-card::before {
  display: none !important;
}
html.perf-mode .stat-card:hover,
html.perf-mode .feature-card:hover,
html.perf-mode .trade-detail-card:hover,
html.perf-mode .cal-day:not(.empty):hover,
html.perf-mode .landing-btn-primary:hover,
html.perf-mode .landing-btn-primary-lg:hover,
html.perf-mode .btn-primary:hover {
  transform: none !important;
  box-shadow: none !important;
}
html.perf-mode .mt5-status-pill.syncing .dot {
  animation: none !important;
}
/* === CRITICAL FLICKER FIX: kill page-nav fadeIn animation ===
   The global `.page.active { animation: fadeIn .25s ease; }` fires on
   EVERY navigation click. On mobile/slower GPUs, this triggers a paint
   + composite for the entire page on each click, causing visible flicker.
   In perf-mode we make page nav instant — far smoother. */
html.perf-mode .page.active {
  animation: none !important;
}
/* === Kill broad `transition: all` on heavy cards in perf-mode ===
   These cascade compositing work across many properties on every state
   change (hover, focus, class toggle). Removing them eliminates
   click-induced repaints on the dashboard and stat grids. */
html.perf-mode .stat-card,
html.perf-mode .feature-card,
html.perf-mode .trade-detail-card,
html.perf-mode .cal-day,
html.perf-mode .daily-todo-item,
html.perf-mode .checklist-item,
html.perf-mode .nav-btn,
html.perf-mode .btn-primary,
html.perf-mode .btn-ghost,
html.perf-mode .landing-btn-primary,
html.perf-mode .landing-btn-primary-lg,
html.perf-mode .landing-btn-ghost,
html.perf-mode .landing-btn-ghost-lg {
  transition: none !important;
}

/*
  REDUCE MOTION
  -------------
  Cuts all animation and transition durations to near-zero. Pages
  appear instantly instead of fading in; toggles flip without easing.
  Also respects the OS-level prefers-reduced-motion by default.
*/
html.reduce-motion *,
html.reduce-motion *::before,
html.reduce-motion *::after {
  animation-duration: 0.001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.001ms !important;
  scroll-behavior: auto !important;
}

/* ====================================================================
   MOBILE FLICKER MITIGATIONS (Tier 4)
   --------------------------------------------------------------------
   PC + mobile browsers fine, mobile-APP (PWA) shows flickering.
   Three causes targeted here:
     1. iOS Safari/WebView treats backdrop-filter inside scrolling
        containers as new compositing layers on every scroll frame —
        causes white flashes / repaint storms on PWAs.
     2. 100vh on iOS recalculates whenever the URL bar shows/hides,
        snapping the layout and flickering everything inside it.
     3. position:fixed elements with backdrop-filter (sidebar, modals)
        flicker on iOS when other content scrolls behind them.
   ==================================================================== */

/* (1) Disable backdrop-filter entirely on installed PWA / iOS-WebKit
       — the visual loss is minimal (we still have solid backgrounds)
       and the flicker goes away completely. */
html.is-standalone *,
html.is-standalone *::before,
html.is-standalone *::after,
html.is-ios *,
html.is-ios *::before,
html.is-ios *::after {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* (2) Compensate the removed transparency by making the backgrounds
       fully opaque in those environments — without this they would
       look washed-out where blur used to do the heavy lifting. */
html.is-standalone .sidebar,
html.is-ios .sidebar {
  background: #0a0a12 !important;
}
html.is-standalone .modal,
html.is-ios .modal,
html.is-standalone .section-card,
html.is-ios .section-card,
html.is-standalone .daily-todo-card,
html.is-ios .daily-todo-card,
html.is-standalone .hero-banner,
html.is-ios .hero-banner,
html.is-standalone .stat-card,
html.is-ios .stat-card {
  background: #0d0d18 !important;
}
html.is-standalone .landing-nav,
html.is-ios .landing-nav {
  background: #08080f !important;
}

/* (3) Force a stable compositing layer on the elements most likely
       to flicker — sidebar, modals, page roots. translateZ(0)
       triggers GPU acceleration and locks the layer so subsequent
       scrolls don't re-trigger compositing. */
html.is-standalone .sidebar,
html.is-ios .sidebar,
html.is-standalone .modal-backdrop,
html.is-ios .modal-backdrop,
html.is-standalone .otp-modal,
html.is-ios .otp-modal {
  -webkit-transform: translateZ(0);
  transform: translateZ(0);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  will-change: transform;
}

/* (4) Replace 100vh with safer dynamic viewport on iOS — keeps the
       layout stable even as the URL bar slides in/out. Falls back
       to 100vh on browsers that don't support dvh. */
@supports (height: 100dvh) {
  html.is-ios .sidebar,
  html.is-ios .main {
    min-height: 100dvh !important;
  }
  html.is-ios .auth-overlay,
  html.is-ios .landing-page {
    min-height: 100dvh !important;
  }
}

/* (5) Disable the body::before grid + ::after glow on standalone
       and small iOS screens — these are pure decoration and the
       biggest flicker culprit on mobile. */
html.is-standalone body::before,
html.is-standalone body::after {
  display: none !important;
}
@media (max-width: 480px) {
  html.is-ios body::before,
  html.is-ios body::after {
    display: none !important;
  }
}

/* (6) Tame all "infinite" animations on standalone — they keep the
       compositor working overtime which manifests as global flicker
       on weaker mobile hardware. */
html.is-standalone .mt5-status-pill.syncing .dot {
  animation: none !important;
}



/* (a) Tame the focus glow on form controls *inside an open modal* on
       touch devices. The 24px aura is the loudest flicker source on
       iOS — replace it with a clean 1px border-color change (still
       visible focus indication, zero paint cost). */
@media (hover: none), (pointer: coarse), (max-width: 1024px) {
  .modal-backdrop.open .form-select:focus,
  .modal-backdrop.open .form-input:focus,
  .modal-backdrop.open .week-review-field:focus,
  .modal-backdrop.open select:focus,
  .modal-backdrop.open input:focus,
  .modal-backdrop.open textarea:focus {
    box-shadow: none !important;
    border-color: #7C5CFC !important;
    background: #0a0a12 !important;
  }
}

/* (b) Drop backdrop-filter on the modal *while it's open* on touch
       devices. The dim modal-backdrop already provides visual
       separation; the blur layer is the expensive part that
       re-rasterizes during picker overlay. Solid background restores
       the lost contrast. */
@media (hover: none), (pointer: coarse), (max-width: 1024px) {
  .modal-backdrop.open,
  .modal-backdrop.open .modal {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
  .modal-backdrop.open .modal {
    background: #0d0d18 !important;
  }
}

/* (c) Pin modal + backdrop to their own GPU compositing layer when
       open. This isolates them from page-level repaints so the
       picker open/close doesn't ripple paint into the modal. */
.modal-backdrop.open,
.modal-backdrop.open .modal {
  -webkit-transform: translateZ(0);
  transform: translateZ(0);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}
.modal-backdrop.open .modal {
  contain: paint;
}

/* (d) Hide body decorative pseudos while any modal-backdrop is open.
       They're invisible behind the modal anyway, but their
       perspective-transformed re-rasters are the #1 contributor to
       picker-time flicker. Uses :has() — supported on iOS Safari
       15.4+, Chrome 105+, Firefox 121+ (all 2022-2023). Older
       browsers fall back gracefully to the existing behavior. */
body:has(.modal-backdrop.open)::before,
body:has(.modal-backdrop.open)::after {
  display: none !important;
}

/* (e) Skip the 300ms tap delay on form controls inside modals —
       during that delay the browser holds stale paint frames that
       leak through as flicker on slow GPUs. */
.modal-backdrop.open .form-select,
.modal-backdrop.open .form-input,
.modal-backdrop.open select,
.modal-backdrop.open input,
.modal-backdrop.open textarea {
  touch-action: manipulation;
}

/* (f) GLOBAL BODY SCROLL LOCK — while ANY overlay/popup is open, the
       page behind must not scroll. Without this, scrolling inside a
       modal chains to the body once (or wherever) the wheel/touch
       lands outside the modal's own scroll area. Uses :has() (same
       support baseline as (d) above). Covers every backdrop type in
       the app — add new backdrop classes here when introducing one. */
body:has(.modal-backdrop.open),
body:has(.pj-otp-backdrop.open),
body:has(.qv-backdrop.open),
body:has(.support-modal-backdrop.open),
body:has(.upgrade-backdrop.open),
body:has(.logout-modal-backdrop.open),
body:has(.auth-overlay:not(.hidden)),
/* Lock the ROOT scroller too — on phones (and some desktop setups) the page
   scrolls on <html>, not <body>, so locking body alone still let the
   background move behind an open modal. */
html:has(.modal-backdrop.open),
html:has(.pj-otp-backdrop.open),
html:has(.qv-backdrop.open),
html:has(.support-modal-backdrop.open),
html:has(.upgrade-backdrop.open),
html:has(.logout-modal-backdrop.open),
html:has(.auth-overlay:not(.hidden)) {
  overflow: hidden !important;
}

/* (g) Stop scroll chaining at the overlay edge: when the modal's own
       scroll area hits its end, the leftover wheel/touch delta must
       die there — not hand off to the page. Applied to the backdrops
       (they are the scroll containers when the modal is taller than
       the viewport) and the modal boxes themselves. */
.modal-backdrop,
.pj-otp-backdrop,
.qv-backdrop,
.support-modal-backdrop,
.upgrade-backdrop,
.logout-modal-backdrop,
.auth-overlay,
.modal,
.otp-modal,
.pj-otp-modal,
.upgrade-modal,
/* custom dropdown / time / date popups — their inner scroll must die at
   the popup edge, never hand off to the modal or page behind */
.cs-panel,
.ctp-col,
.dpk-panel {
  overscroll-behavior: contain;
}



.link-btn {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: #7C5CFC;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  display: inline;
}
.link-btn:hover { text-decoration: underline; }
.link-btn:focus-visible {
  outline: 2px solid #7C5CFC;
  outline-offset: 2px;
  border-radius: 3px;
}
.link-btn:disabled,
.link-btn.disabled {
  color: #7c7c94;
  cursor: not-allowed;
  text-decoration: none;
}
